Skip to content

Commit 06864ca

Browse files
authored
Merge pull request #31 from datachainlab/fix-membership-value
Fix to generate commitment in `verify_membership` Signed-off-by: Jun Kimura <jun.kimura@datachain.jp>
2 parents 80ea9cc + b13451d commit 06864ca

File tree

6 files changed

+116
-19
lines changed

6 files changed

+116
-19
lines changed

crates/ibc/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ ssz-rs = { git = "https://github.com/bluele/ssz_rs", branch = "serde-no-std", de
1616
hex = { version = "0.4.3", default-features = false }
1717

1818
ethereum-ibc-proto = { path = "../../proto", default-features = false }
19-
ethereum-consensus = { git = "https://github.com/datachainlab/ethereum-light-client-rs", rev = "v0.1.6", default-features = false }
20-
ethereum-light-client-verifier = { git = "https://github.com/datachainlab/ethereum-light-client-rs", rev = "v0.1.6", default-features = false }
19+
ethereum-consensus = { git = "https://github.com/datachainlab/ethereum-light-client-rs", rev = "v0.1.7", default-features = false }
20+
ethereum-light-client-verifier = { git = "https://github.com/datachainlab/ethereum-light-client-rs", rev = "v0.1.7", default-features = false }
2121

2222
[dev-dependencies]
2323
time = { version = "0.3", default-features = false, features = ["macros", "parsing"] }
2424
hex-literal = "0.4.1"
25-
ethereum-light-client-verifier = { git = "https://github.com/datachainlab/ethereum-light-client-rs", rev = "v0.1.6", default-features = false, features = ["test-utils"] }
25+
ethereum-light-client-verifier = { git = "https://github.com/datachainlab/ethereum-light-client-rs", rev = "v0.1.7", default-features = false, features = ["test-utils"] }

crates/ibc/src/client_state.rs

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use ibc_proto::google::protobuf::Any;
3333
use ibc_proto::protobuf::Protobuf;
3434
use prost::Message;
3535
use 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

319329
impl<const SYNC_COMMITTEE_SIZE: usize> Ics2ClientState for ClientState<SYNC_COMMITTEE_SIZE> {
@@ -1018,6 +1028,7 @@ fn verify_delay_passed(
10181028
#[cfg(test)]
10191029
mod 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
{

crates/ibc/src/errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ pub enum Error {
9999
ContextError(ContextError),
100100
/// zero timestamp error
101101
ZeroTimestampError,
102+
/// zero block number error
103+
ZeroBlockNumberError,
102104
/// timestamp overflow error: `{0}`
103105
TimestampOverflowError(TimestampOverflowError),
104106
/// parse timestamp error: `{0}`

crates/ibc/src/header.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::types::{
1212
use bytes::Buf;
1313
use ethereum_consensus::compute::compute_timestamp_at_slot;
1414
use ethereum_consensus::context::ChainContext;
15+
use ethereum_consensus::types::U64;
1516
use ethereum_ibc_proto::ibc::lightclients::ethereum::v1::Header as RawHeader;
1617
use ethereum_light_client_verifier::updates::ConsensusUpdate;
1718
use ibc::core::ics02_client::error::ClientError;
@@ -86,6 +87,9 @@ impl<const SYNC_COMMITTEE_SIZE: usize> Header<SYNC_COMMITTEE_SIZE> {
8687
if self.timestamp.into_tm_time().is_none() {
8788
return Err(Error::ZeroTimestampError);
8889
}
90+
if self.execution_update.block_number == U64(0) {
91+
return Err(Error::ZeroBlockNumberError);
92+
}
8993
let header_timestamp_nanos = self
9094
.timestamp
9195
.into_tm_time()
@@ -237,7 +241,7 @@ mod tests {
237241
let dummy_execution_block_number = 1;
238242

239243
for b in [false, true] {
240-
let update = gen_light_client_update_with_params::<32, _>(
244+
let (update, _) = gen_light_client_update_with_params::<32, _>(
241245
&ctx,
242246
base_signature_slot,
243247
base_attested_slot,
@@ -257,7 +261,10 @@ mod tests {
257261
is_next: true,
258262
},
259263
consensus_update: update.clone(),
260-
execution_update: ExecutionUpdateInfo::default(),
264+
execution_update: ExecutionUpdateInfo {
265+
block_number: U64(2),
266+
..Default::default()
267+
},
261268
account_update: AccountUpdateInfo::default(),
262269
timestamp: Timestamp::from_nanoseconds(
263270
compute_timestamp_at_slot(&ctx, update.finalized_beacon_header().slot).0
@@ -278,7 +285,10 @@ mod tests {
278285
is_next: true,
279286
},
280287
consensus_update: update,
281-
execution_update: ExecutionUpdateInfo::default(),
288+
execution_update: ExecutionUpdateInfo {
289+
block_number: U64(2),
290+
..Default::default()
291+
},
282292
account_update: AccountUpdateInfo::default(),
283293
timestamp: Timestamp::from_nanoseconds(0).unwrap(),
284294
};
@@ -287,7 +297,7 @@ mod tests {
287297
assert!(res.is_err(), "header with zero timestamp should fail");
288298
}
289299

290-
let update = gen_light_client_update_with_params::<32, _>(
300+
let (update, _) = gen_light_client_update_with_params::<32, _>(
291301
&ctx,
292302
base_signature_slot,
293303
base_attested_slot,

crates/ibc/src/misbehaviour.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ mod tests {
245245
let dummy_execution_state_root = [1u8; 32].into();
246246
let dummy_execution_block_number = 1;
247247

248-
let update_1 = gen_light_client_update_with_params::<32, _>(
248+
let (update_1, _) = gen_light_client_update_with_params::<32, _>(
249249
&ctx,
250250
base_signature_slot,
251251
base_attested_slot,
@@ -257,7 +257,7 @@ mod tests {
257257
true,
258258
32,
259259
);
260-
let update_2 = gen_light_client_update_with_params::<32, _>(
260+
let (update_2, _) = gen_light_client_update_with_params::<32, _>(
261261
&ctx,
262262
base_signature_slot,
263263
base_attested_slot,
@@ -288,7 +288,7 @@ mod tests {
288288
assert_eq!(misbehaviour, decoded);
289289

290290
let different_dummy_execution_state_root = [2u8; 32].into();
291-
let update_3 = gen_light_client_update_with_params::<32, _>(
291+
let (update_3, _) = gen_light_client_update_with_params::<32, _>(
292292
&ctx,
293293
base_signature_slot,
294294
base_attested_slot,

crates/ibc/src/update.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ mod tests {
177177

178178
{
179179
// store_period == finalized_period == attested_period == signature_period
180-
let update = to_consensus_update_info(gen_light_client_update_with_params::<32, _>(
180+
let (update, _) = gen_light_client_update_with_params::<32, _>(
181181
&ctx,
182182
base_signature_slot,
183183
base_attested_slot,
@@ -188,7 +188,8 @@ mod tests {
188188
scm.get_committee(base_store_period + 1),
189189
true,
190190
32,
191-
));
191+
);
192+
let update = to_consensus_update_info(update);
192193
let new_block_number = 2.into();
193194
let res = apply_updates(
194195
&ctx,
@@ -226,7 +227,7 @@ mod tests {
226227
}
227228
{
228229
// store_period + 1 == finalized_period == attested_period == signature_period
229-
let update = to_consensus_update_info(gen_light_client_update_with_params::<32, _>(
230+
let (update, _) = gen_light_client_update_with_params::<32, _>(
230231
&ctx,
231232
base_signature_slot + slots_per_period,
232233
base_attested_slot + slots_per_period,
@@ -237,7 +238,8 @@ mod tests {
237238
scm.get_committee(base_store_period + 2),
238239
true,
239240
32,
240-
));
241+
);
242+
let update = to_consensus_update_info(update);
241243
let new_block_number = 2.into();
242244
let res = apply_updates(
243245
&ctx,
@@ -276,7 +278,7 @@ mod tests {
276278
{
277279
// store_period + 1 == finalized_period == attested_period == signature_period
278280
// but the update has no next sync committee
279-
let update = to_consensus_update_info(gen_light_client_update_with_params::<32, _>(
281+
let (update, _) = gen_light_client_update_with_params::<32, _>(
280282
&ctx,
281283
base_signature_slot + slots_per_period,
282284
base_attested_slot + slots_per_period,
@@ -287,7 +289,8 @@ mod tests {
287289
scm.get_committee(base_store_period + 2),
288290
false,
289291
32,
290-
));
292+
);
293+
let update = to_consensus_update_info(update);
291294
let new_block_number = 2.into();
292295
let res = apply_updates(
293296
&ctx,
@@ -314,7 +317,7 @@ mod tests {
314317
}
315318
{
316319
// finalized_period - 1 == store_period == attested_period == signature_period
317-
let update = to_consensus_update_info(gen_light_client_update_with_params::<32, _>(
320+
let (update, _) = gen_light_client_update_with_params::<32, _>(
318321
&ctx,
319322
base_signature_slot,
320323
base_attested_slot,
@@ -325,7 +328,8 @@ mod tests {
325328
scm.get_committee(base_store_period),
326329
true,
327330
32,
328-
));
331+
);
332+
let update = to_consensus_update_info(update);
329333
let new_block_number = 2.into();
330334
let res = apply_updates(
331335
&ctx,

0 commit comments

Comments
 (0)