Skip to content

Commit d916158

Browse files
authored
feat: arb v2 (#5247)
2 parents faa9c0e + a4b27c6 commit d916158

File tree

30 files changed

+2147
-582
lines changed

30 files changed

+2147
-582
lines changed

Cargo.lock

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cosmwasm/ibc-union/lightclient/arbitrum/src/client.rs

Lines changed: 96 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ impl IbcClient for ArbitrumLightClient {
4444
storage_proof,
4545
value,
4646
)
47-
.map_err(Into::<Error>::into)
48-
.map_err(Into::into)
47+
.map_err(|e| Error::EthereumLightClient(e.into()).into())
4948
}
5049

5150
fn verify_non_membership(
@@ -61,8 +60,7 @@ impl IbcClient for ArbitrumLightClient {
6160
consensus_state.ibc_storage_root,
6261
storage_proof,
6362
)
64-
.map_err(Into::<Error>::into)
65-
.map_err(Into::into)
63+
.map_err(|e| Error::EthereumLightClient(e.into()).into())
6664
}
6765

6866
fn verify_header(
@@ -71,37 +69,83 @@ impl IbcClient for ArbitrumLightClient {
7169
header: Self::Header,
7270
_relayer: Addr,
7371
) -> Result<StateUpdate<Self>, IbcClientError<Self>> {
74-
let ClientState::V1(mut client_state) = ctx.read_self_client_state()?;
75-
let l1_consensus_state = ctx
76-
.read_consensus_state::<EthereumLightClient>(
77-
client_state.l1_client_id,
78-
header.l1_height.height(),
79-
)
80-
.map_err(Into::<Error>::into)?;
81-
82-
arbitrum_verifier::verify_header_v1(&client_state, &header, l1_consensus_state.state_root)
83-
.map_err(Error::HeaderVerify)?;
84-
85-
let consensus_state = ConsensusState {
86-
state_root: header.l2_header.state_root,
87-
ibc_storage_root: header.l2_ibc_account_proof.storage_root,
88-
// must be nanos
89-
timestamp: Timestamp::from_secs(header.l2_header.timestamp),
90-
};
91-
92-
let new_latest_height = header
93-
.l2_header
94-
.number
95-
.try_into()
96-
.map_err(|()| Error::L2HeightTooLarge(header.l2_header.number))?;
97-
98-
let state_update = StateUpdate::new(new_latest_height, consensus_state);
99-
100-
if client_state.latest_height < new_latest_height {
101-
client_state.latest_height = new_latest_height;
102-
Ok(state_update.overwrite_client_state(ClientState::V1(client_state)))
103-
} else {
104-
Ok(state_update)
72+
match (ctx.read_self_client_state()?, header) {
73+
(ClientState::V1(mut client_state), Header::V1(header)) => {
74+
let l1_consensus_state = ctx
75+
.read_consensus_state::<EthereumLightClient>(
76+
client_state.l1_client_id,
77+
header.l1_height.height(),
78+
)
79+
.map_err(Error::from)?;
80+
81+
arbitrum_verifier::v1::verify_header(
82+
&client_state,
83+
&header,
84+
l1_consensus_state.state_root,
85+
)
86+
.map_err(Error::HeaderVerifyV1)?;
87+
88+
let consensus_state = ConsensusState {
89+
state_root: header.l2_header.state_root,
90+
ibc_storage_root: header.l2_ibc_account_proof.storage_root,
91+
// must be nanos
92+
timestamp: Timestamp::from_secs(header.l2_header.timestamp),
93+
};
94+
95+
let new_latest_height = header
96+
.l2_header
97+
.number
98+
.try_into()
99+
.map_err(|()| Error::L2HeightTooLarge(header.l2_header.number))?;
100+
101+
let state_update = StateUpdate::new(new_latest_height, consensus_state);
102+
103+
if client_state.latest_height < new_latest_height {
104+
client_state.latest_height = new_latest_height;
105+
Ok(state_update.overwrite_client_state(ClientState::V1(client_state)))
106+
} else {
107+
Ok(state_update)
108+
}
109+
}
110+
(ClientState::V2(mut client_state), Header::V2(header)) => {
111+
let l1_consensus_state = ctx
112+
.read_consensus_state::<EthereumLightClient>(
113+
client_state.l1_client_id,
114+
header.l1_height.height(),
115+
)
116+
.map_err(Error::from)?;
117+
118+
arbitrum_verifier::v2::verify_header(
119+
&client_state,
120+
&header,
121+
l1_consensus_state.state_root,
122+
)
123+
.map_err(Error::HeaderVerifyV2)?;
124+
125+
let consensus_state = ConsensusState {
126+
state_root: header.l2_header.state_root,
127+
ibc_storage_root: header.l2_ibc_account_proof.storage_root,
128+
// must be nanos
129+
timestamp: Timestamp::from_secs(header.l2_header.timestamp),
130+
};
131+
132+
let new_latest_height = header
133+
.l2_header
134+
.number
135+
.try_into()
136+
.map_err(|()| Error::L2HeightTooLarge(header.l2_header.number))?;
137+
138+
let state_update = StateUpdate::new(new_latest_height, consensus_state);
139+
140+
if client_state.latest_height < new_latest_height {
141+
client_state.latest_height = new_latest_height;
142+
Ok(state_update.overwrite_client_state(ClientState::V2(client_state)))
143+
} else {
144+
Ok(state_update)
145+
}
146+
}
147+
(ClientState::V1(_), _) => Err(Error::HeaderMustBeV1.into()),
148+
(ClientState::V2(_), _) => Err(Error::HeaderMustBeV2.into()),
105149
}
106150
}
107151

@@ -114,13 +158,15 @@ impl IbcClient for ArbitrumLightClient {
114158
Err(Error::Unimplemented.into())
115159
}
116160

117-
fn status(
118-
ctx: IbcClientCtx<Self>,
119-
ClientState::V1(client_state): &Self::ClientState,
120-
) -> Status {
161+
fn status(ctx: IbcClientCtx<Self>, client_state: &Self::ClientState) -> Status {
121162
let _ = ctx;
122163

123-
if client_state.frozen_height.height() != 0 {
164+
let frozen_height = match client_state {
165+
ClientState::V1(client_state) => client_state.frozen_height,
166+
ClientState::V2(client_state) => client_state.frozen_height,
167+
};
168+
169+
if frozen_height.height() != 0 {
124170
Status::Frozen
125171
} else {
126172
Status::Active
@@ -140,11 +186,17 @@ impl IbcClient for ArbitrumLightClient {
140186
consensus_state.timestamp
141187
}
142188

143-
fn get_latest_height(ClientState::V1(client_state): &Self::ClientState) -> u64 {
144-
client_state.latest_height
189+
fn get_latest_height(client_state: &Self::ClientState) -> u64 {
190+
match client_state {
191+
ClientState::V1(client_state) => client_state.latest_height,
192+
ClientState::V2(client_state) => client_state.latest_height,
193+
}
145194
}
146195

147-
fn get_counterparty_chain_id(ClientState::V1(client_state): &Self::ClientState) -> String {
148-
client_state.chain_id.to_string()
196+
fn get_counterparty_chain_id(client_state: &Self::ClientState) -> String {
197+
match client_state {
198+
ClientState::V1(client_state) => client_state.chain_id.to_string(),
199+
ClientState::V2(client_state) => client_state.chain_id.to_string(),
200+
}
149201
}
150202
}

cosmwasm/ibc-union/lightclient/arbitrum/src/errors.rs

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,31 @@
11
use ethereum_light_client::client::EthereumLightClient;
22
use ibc_union_light_client::IbcClientError;
3-
use unionlabs::{
4-
ibc::core::client::height::Height,
5-
primitives::{H256, U256},
6-
};
3+
use unionlabs::primitives::U256;
74

85
use crate::client::ArbitrumLightClient;
96

107
#[derive(Debug, thiserror::Error)]
118
pub enum Error {
129
#[error(transparent)]
13-
Evm(#[from] ethereum_light_client::errors::Error),
14-
15-
// REVIEW: Move this variant to IbcClientError?
16-
#[error("consensus state not found at height {0}")]
17-
ConsensusStateNotFound(Height),
10+
EthereumLightClient(#[from] IbcClientError<EthereumLightClient>),
1811

1912
#[error("the l2 height {0} is too large (> u64::MAX)")]
2013
L2HeightTooLarge(U256),
2114

22-
#[error("IBC path is empty")]
23-
EmptyIbcPath,
24-
25-
#[error("proof is empty")]
26-
EmptyProof,
27-
28-
#[error("expected value ({expected}) and stored value ({stored}) don't match")]
29-
StoredValueMismatch { expected: H256, stored: H256 },
15+
#[error("failed to verify arbitrum header (v1)")]
16+
HeaderVerifyV1(#[from] arbitrum_verifier::v1::Error),
3017

31-
#[error("failed to verify arbitrum header: {0}")]
32-
HeaderVerify(#[from] arbitrum_verifier::Error),
18+
#[error("failed to verify arbitrum header (v2)")]
19+
HeaderVerifyV2(#[from] arbitrum_verifier::v2::Error),
3320

3421
#[error("the operation has not been implemented yet")]
3522
Unimplemented,
3623

37-
#[error(transparent)]
38-
EvmIbcClient(#[from] IbcClientError<EthereumLightClient>),
24+
#[error("invalid header, must be v1")]
25+
HeaderMustBeV1,
26+
27+
#[error("invalid header, must be v2")]
28+
HeaderMustBeV2,
3929
}
4030

4131
impl From<Error> for IbcClientError<ArbitrumLightClient> {

deployments/deployments.json

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,86 @@
242242
}
243243
}
244244
},
245+
"arbitrum.421614": {
246+
"ibc_interface": "ibc-solidity",
247+
"deployer": "0x6dd4e0224d46b60d86e57c9e5980589e9818020f",
248+
"sender": "0x95fb5cb304508d74d855514d7bc9bda75c304ce2",
249+
"manager": "0x40cdff51ae7487e0b4a4d6e5f86eb15fb7c1d9f4",
250+
"multicall": {
251+
"address": "0x70276995f225df69936eaec02ddece998a9e3662",
252+
"height": 0,
253+
"commit": "unknown"
254+
},
255+
"core": {
256+
"address": "0xee4ea8d358473f0fcebf0329feed95d56e8c04d7",
257+
"height": 0,
258+
"commit": "d03dc6ee0e753ddb5938b23a76f09cf4572f577a"
259+
},
260+
"lightclient": {
261+
"cometbls": {
262+
"address": "0x7700ea295f62989d2c98721389a521c96fe3c4c0",
263+
"height": 0,
264+
"commit": "d03dc6ee0e753ddb5938b23a76f09cf4572f577a"
265+
},
266+
"state-lens/ics23/ics23": {
267+
"address": "0x2c5b55a11fad1d169b83df21d886ce0797f3a83d",
268+
"height": 0,
269+
"commit": "c2c6c2c8e11910ccd5ca6bc3db1055364a21af8a"
270+
},
271+
"state-lens/ics23/mpt": {
272+
"address": "0x473b540b38f02db8109d5bf4f80f0e03e4e31805",
273+
"height": 0,
274+
"commit": "2d6ccbaaf8dcb6d282e8e499584de937f9719066"
275+
}
276+
},
277+
"app": {
278+
"ucs03": {
279+
"address": "0x5fbe74a283f7954f10aa04c2edf55578811aeb03",
280+
"height": 0,
281+
"commit": "5a54fb0e68a9284297e42902354cfb41f4b81bf9"
282+
}
283+
}
284+
},
285+
"arbitrum.42161": {
286+
"ibc_interface": "ibc-solidity",
287+
"deployer": "0x6dd4e0224d46b60d86e57c9e5980589e9818020f",
288+
"sender": "0x95fb5cb304508d74d855514d7bc9bda75c304ce2",
289+
"manager": "0x40cdff51ae7487e0b4a4d6e5f86eb15fb7c1d9f4",
290+
"multicall": {
291+
"address": "0x70276995f225df69936eaec02ddece998a9e3662",
292+
"height": 0,
293+
"commit": "unknown"
294+
},
295+
"core": {
296+
"address": "0xee4ea8d358473f0fcebf0329feed95d56e8c04d7",
297+
"height": 0,
298+
"commit": "d03dc6ee0e753ddb5938b23a76f09cf4572f577a"
299+
},
300+
"lightclient": {
301+
"cometbls": {
302+
"address": "0x7700ea295f62989d2c98721389a521c96fe3c4c0",
303+
"height": 0,
304+
"commit": "d03dc6ee0e753ddb5938b23a76f09cf4572f577a"
305+
},
306+
"state-lens/ics23/ics23": {
307+
"address": "0x2c5b55a11fad1d169b83df21d886ce0797f3a83d",
308+
"height": 0,
309+
"commit": "c2c6c2c8e11910ccd5ca6bc3db1055364a21af8a"
310+
},
311+
"state-lens/ics23/mpt": {
312+
"address": "0x473b540b38f02db8109d5bf4f80f0e03e4e31805",
313+
"height": 0,
314+
"commit": "2d6ccbaaf8dcb6d282e8e499584de937f9719066"
315+
}
316+
},
317+
"app": {
318+
"ucs03": {
319+
"address": "0x5fbe74a283f7954f10aa04c2edf55578811aeb03",
320+
"height": 0,
321+
"commit": "5a54fb0e68a9284297e42902354cfb41f4b81bf9"
322+
}
323+
}
324+
},
245325
"bob.808813": {
246326
"ibc_interface": "ibc-solidity",
247327
"deployer": "0x6dd4e0224d46b60d86e57c9e5980589e9818020f",

0 commit comments

Comments
 (0)