@@ -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}
0 commit comments