@@ -33,6 +33,7 @@ use ibc_proto::google::protobuf::Any;
3333use ibc_proto:: protobuf:: Protobuf ;
3434use prost:: Message ;
3535use serde:: { Deserialize , Serialize } ;
36+ use tiny_keccak:: { Hasher , Keccak } ;
3637
3738/// The revision number for the Ethereum light client is always 0.
3839///
@@ -204,11 +205,12 @@ impl<const SYNC_COMMITTEE_SIZE: usize> ClientState<SYNC_COMMITTEE_SIZE> {
204205 }
205206 let key =
206207 calculate_ibc_commitment_storage_location ( & self . ibc_commitments_slot , path. clone ( ) ) ;
208+ let commitment = Self :: keccak256 ( & value) ;
207209 self . execution_verifier
208210 . verify_membership (
209211 root,
210212 key. as_bytes ( ) ,
211- rlp:: encode ( & trim_left_zero ( & value ) ) . as_ref ( ) ,
213+ rlp:: encode ( & trim_left_zero ( commitment . as_bytes ( ) ) ) . as_ref ( ) ,
212214 proof. clone ( ) ,
213215 )
214216 . map_err ( |e| ClientError :: ClientSpecific {
@@ -314,6 +316,14 @@ impl<const SYNC_COMMITTEE_SIZE: usize> ClientState<SYNC_COMMITTEE_SIZE> {
314316 Ok ( ( ) )
315317 }
316318 }
319+
320+ fn keccak256 ( bz : & [ u8 ] ) -> H256 {
321+ let mut hasher = Keccak :: v256 ( ) ;
322+ let mut output = [ 0u8 ; 32 ] ;
323+ hasher. update ( bz) ;
324+ hasher. finalize ( & mut output) ;
325+ H256 :: from_slice ( & output)
326+ }
317327}
318328
319329impl < const SYNC_COMMITTEE_SIZE : usize > Ics2ClientState for ClientState < SYNC_COMMITTEE_SIZE > {
@@ -1018,6 +1028,7 @@ fn verify_delay_passed(
10181028#[ cfg( test) ]
10191029mod tests {
10201030 use super :: * ;
1031+ use core:: str:: FromStr ;
10211032 use ethereum_consensus:: fork:: {
10221033 altair:: ALTAIR_FORK_SPEC , bellatrix:: BELLATRIX_FORK_SPEC , capella:: CAPELLA_FORK_SPEC ,
10231034 deneb:: DENEB_FORK_SPEC ,
@@ -1124,6 +1135,76 @@ mod tests {
11241135 assert ! ( res. is_ok( ) , "{:?}" , res) ;
11251136 }
11261137
1138+ #[ test]
1139+ fn test_verify_membership ( ) {
1140+ let client_state =
1141+ ClientState :: < { ethereum_consensus:: preset:: minimal:: PRESET . SYNC_COMMITTEE_SIZE } > {
1142+ ibc_address : Address ( hex ! ( "a7f733a4fEA1071f58114b203F57444969b86524" ) ) ,
1143+ ibc_commitments_slot : H256 ( hex ! (
1144+ "1ee222554989dda120e26ecacf756fe1235cd8d726706b57517715dde4f0c900"
1145+ ) ) ,
1146+ latest_execution_block_number : 1 . into ( ) ,
1147+ ..Default :: default ( )
1148+ } ;
1149+ let root = hex ! ( "27cd08827e6bf1e435832f4b2660107beb562314287b3fa534f3b189574c0cca" )
1150+ . to_vec ( )
1151+ . into ( ) ;
1152+ let ( path, proof, value) = get_membership_proof ( ) ;
1153+ let proof_height = Height :: new ( ETHEREUM_CLIENT_REVISION_NUMBER , 1 ) . unwrap ( ) ;
1154+ let res = client_state. verify_membership (
1155+ proof_height,
1156+ & Default :: default ( ) ,
1157+ & proof. try_into ( ) . unwrap ( ) ,
1158+ & root,
1159+ Path :: from_str ( & path) . unwrap ( ) ,
1160+ value,
1161+ ) ;
1162+ assert ! ( res. is_ok( ) , "{:?}" , res) ;
1163+ }
1164+
1165+ #[ test]
1166+ fn test_verify_non_membership ( ) {
1167+ let client_state =
1168+ ClientState :: < { ethereum_consensus:: preset:: minimal:: PRESET . SYNC_COMMITTEE_SIZE } > {
1169+ ibc_address : Address ( hex ! ( "a7f733a4fEA1071f58114b203F57444969b86524" ) ) ,
1170+ ibc_commitments_slot : H256 ( hex ! (
1171+ "1ee222554989dda120e26ecacf756fe1235cd8d726706b57517715dde4f0c900"
1172+ ) ) ,
1173+ latest_execution_block_number : 1 . into ( ) ,
1174+ ..Default :: default ( )
1175+ } ;
1176+ let root = hex ! ( "27cd08827e6bf1e435832f4b2660107beb562314287b3fa534f3b189574c0cca" )
1177+ . to_vec ( )
1178+ . into ( ) ;
1179+ let ( path, proof) = get_non_membership_proof ( ) ;
1180+ let proof_height = Height :: new ( ETHEREUM_CLIENT_REVISION_NUMBER , 1 ) . unwrap ( ) ;
1181+ let res = client_state. verify_non_membership (
1182+ proof_height,
1183+ & Default :: default ( ) ,
1184+ & proof. try_into ( ) . unwrap ( ) ,
1185+ & root,
1186+ Path :: from_str ( & path) . unwrap ( ) ,
1187+ ) ;
1188+ assert ! ( res. is_ok( ) , "{:?}" , res) ;
1189+ }
1190+
1191+ // returns: (path, proof, value)
1192+ fn get_membership_proof ( ) -> ( String , Vec < u8 > , Vec < u8 > ) {
1193+ (
1194+ "clients/lcp-client-0/clientState" . to_string ( ) ,
1195+ hex ! ( "f90159f901118080a0143145e818eeff83817419a6632ea193fd1acaa4f791eb17282f623f38117f56a0e6ee0a993a7254ee9253d766ea005aec74eb1e11656961f0fb11323f4f91075580808080a01efae04adc2e970b4af3517581f41ce2ba4ff60492d33696c1e2a5ab70cb55bba03bac3f5124774e41fb6efdd7219530846f9f6441045c4666d2855c6598cfca00a020d7122ffc86cb37228940b5a9441e9fd272a3450245c9130ca3ab00bc1cd6ef80a0047f255205a0f2b0e7d29d490abf02bfb62c3ed201c338bc7f0088fa9c5d77eda069fecc766fcb2df04eb3a834b1f4ba134df2be114479e251d9cc9b6ba493077b80a094c3ed6a7ef63a6a67e46cc9876b9b1882eeba3d28e6d61bb15cdfb207d077e180f843a03e077f3dfd0489e70c68282ced0126c62fcef50acdcb7f57aa4552b87b456b11a1a05dc044e92e82db28c96fd98edd502949612b06e8da6dd74664a43a5ed857b298" ) . to_vec ( ) ,
1196+ hex ! ( "0a242f6962632e6c69676874636c69656e74732e6c63702e76312e436c69656e74537461746512ed010a208083673c69fe3f098ea79a799d9dbb99c39b4b4f17a1a79ef58bdf8ae86299951080f524220310fb012a1353575f48415244454e494e475f4e45454445442a1147524f55505f4f55545f4f465f44415445320e494e54454c2d53412d3030323139320e494e54454c2d53412d3030323839320e494e54454c2d53412d3030333334320e494e54454c2d53412d3030343737320e494e54454c2d53412d3030363134320e494e54454c2d53412d3030363135320e494e54454c2d53412d3030363137320e494e54454c2d53412d30303832383a14cb96f8d6c2d543102184d679d7829b39434e4eec48015001" ) . to_vec ( )
1197+ )
1198+ }
1199+
1200+ // returns: (path, proof)
1201+ fn get_non_membership_proof ( ) -> ( String , Vec < u8 > ) {
1202+ (
1203+ "clients/lcp-client-1/clientState" . to_string ( ) ,
1204+ hex ! ( "f90114f901118080a0143145e818eeff83817419a6632ea193fd1acaa4f791eb17282f623f38117f56a0e6ee0a993a7254ee9253d766ea005aec74eb1e11656961f0fb11323f4f91075580808080a01efae04adc2e970b4af3517581f41ce2ba4ff60492d33696c1e2a5ab70cb55bba03bac3f5124774e41fb6efdd7219530846f9f6441045c4666d2855c6598cfca00a020d7122ffc86cb37228940b5a9441e9fd272a3450245c9130ca3ab00bc1cd6ef80a0047f255205a0f2b0e7d29d490abf02bfb62c3ed201c338bc7f0088fa9c5d77eda069fecc766fcb2df04eb3a834b1f4ba134df2be114479e251d9cc9b6ba493077b80a094c3ed6a7ef63a6a67e46cc9876b9b1882eeba3d28e6d61bb15cdfb207d077e180" ) . to_vec ( )
1205+ )
1206+ }
1207+
11271208 #[ test]
11281209 fn test_trusting_period_validation ( ) {
11291210 {
0 commit comments