From 4bdc29fde132a4107768eeff2cb84dff49dafe82 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Tue, 27 Feb 2024 11:20:37 +0900 Subject: [PATCH] Trim leading zeros for expected value (#42) * trim left zero for expected value Signed-off-by: Naohiro Yoshida --- light-client/src/commitment.rs | 122 ++++++++++++++++++++++++++++++++- light-client/src/errors.rs | 14 ++-- 2 files changed, 130 insertions(+), 6 deletions(-) diff --git a/light-client/src/commitment.rs b/light-client/src/commitment.rs index fea4254..20b50f3 100644 --- a/light-client/src/commitment.rs +++ b/light-client/src/commitment.rs @@ -52,13 +52,16 @@ pub fn verify_proof( ) -> Result<(), Error> { let value = verify(root, proof, key)?; - let expected_value = expected_value.as_ref().map(|e| rlp::encode(e).to_vec()); + let expected_value = expected_value + .as_ref() + .map(|e| rlp::encode(&trim_left_zero(e)).to_vec()); if value != expected_value { return Err(Error::UnexpectedStateValue( *root, proof.to_vec(), expected_value, key.to_vec(), + value, )); } Ok(()) @@ -71,6 +74,17 @@ fn verify(root: &Hash, proof: &[Vec], key: &[u8]) -> Result>, trie.get(&keccak_256(key)).map_err(Error::TrieError) } +fn trim_left_zero(value: &[u8]) -> &[u8] { + let mut pos = 0; + for v in value.iter() { + if *v != 0 { + break; + } + pos += 1; + } + &value[pos..] +} + #[cfg(test)] mod test { use alloc::borrow::ToOwned as _; @@ -81,8 +95,9 @@ mod test { use crate::commitment::{ calculate_ibc_commitment_storage_key, decode_eip1184_rlp_proof, resolve_account, - verify_proof, + trim_left_zero, verify_proof, }; + use crate::errors::Error; use crate::misc::{Account, Hash}; #[test] @@ -118,6 +133,30 @@ mod test { } } + #[test] + fn test_verify_error() { + let key = hex!("0000000000000000000000000000000000000000000000000000000000000000"); + let root = hex!("c5bbc7e086abad66f3d4b49cc39c27e4864834ce3d21d91692c513481bf9de1b"); + let proof = vec![ + hex!("f8518080a051c7191217d318e27eed8b8f0b2c81df8ad258037ecdb3ee8808ab982623adba8080808080808080a028e886a776e1a5ccaf6819bc26ae7f83616639014e9751eb8d68eaaac54966448080808080").to_vec(), + hex!("f7a0390decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5639594ebed59a7f647152af99ef0fd8e3f7e81bd7b1fd7").to_vec(), + ]; + let expected = hex!("fbed59a7f647152af99ef0fd8e3f7e81bd7b1fd7"); + match verify_proof(&root, &proof, &key, &Some(expected.to_vec())).unwrap_err() { + Error::UnexpectedStateValue(e1, e2, e3, e4, e5) => { + assert_eq!(root, e1); + assert_eq!(proof, e2); + assert_eq!(rlp::encode(&expected.as_slice()), e3.unwrap()); + assert_eq!(key, e4.as_slice()); + assert_eq!( + rlp::encode(&hex!("ebed59a7f647152af99ef0fd8e3f7e81bd7b1fd7").as_slice()), + e5.unwrap() + ); + } + err => unreachable!("{:?}", err), + } + } + #[test] fn test_verify_commitment_with_lcp_data() { let storage_root: Hash = [ @@ -267,4 +306,83 @@ mod test { unreachable!("{:?}", e); } } + + #[test] + fn test_verify_with_left_zero() { + let storage_root: Hash = [ + 168, 105, 232, 135, 230, 245, 248, 79, 115, 67, 172, 247, 33, 207, 55, 158, 86, 149, + 132, 227, 147, 238, 198, 180, 47, 29, 218, 84, 139, 33, 181, 95, + ]; + let key: Hash = [ + 169, 21, 106, 163, 236, 80, 251, 216, 119, 110, 40, 43, 67, 76, 199, 200, 217, 131, 89, + 39, 240, 116, 104, 135, 170, 105, 69, 65, 171, 60, 50, 220, + ]; + let proof = vec![ + vec![ + 249, 1, 145, 160, 237, 65, 114, 78, 179, 29, 45, 55, 177, 252, 192, 57, 61, 189, + 254, 163, 46, 173, 183, 234, 50, 175, 31, 88, 20, 182, 117, 26, 53, 131, 20, 244, + 128, 128, 160, 217, 87, 240, 147, 120, 91, 216, 55, 83, 73, 206, 238, 1, 102, 181, + 50, 2, 74, 71, 64, 197, 237, 68, 169, 76, 26, 239, 37, 153, 92, 220, 113, 160, 216, + 212, 96, 41, 186, 243, 127, 252, 208, 26, 34, 20, 186, 30, 191, 52, 2, 220, 19, + 242, 76, 78, 226, 14, 172, 57, 53, 201, 47, 11, 15, 153, 160, 167, 92, 79, 208, 96, + 165, 234, 64, 80, 127, 165, 227, 164, 155, 99, 128, 30, 139, 93, 87, 118, 169, 233, + 241, 254, 76, 96, 65, 218, 188, 52, 252, 160, 238, 223, 128, 255, 50, 42, 169, 98, + 225, 114, 201, 135, 113, 214, 235, 46, 158, 215, 179, 18, 28, 2, 42, 207, 120, 188, + 138, 162, 63, 132, 117, 1, 160, 251, 56, 65, 100, 82, 159, 84, 95, 43, 67, 84, 246, + 177, 74, 231, 199, 242, 53, 159, 97, 153, 197, 36, 123, 105, 107, 102, 136, 128, + 190, 59, 88, 160, 67, 76, 154, 154, 112, 58, 176, 167, 174, 126, 79, 134, 194, 208, + 154, 245, 161, 106, 236, 125, 64, 136, 202, 72, 61, 70, 170, 12, 109, 132, 68, 213, + 160, 175, 251, 37, 136, 180, 2, 187, 116, 68, 53, 156, 120, 112, 109, 23, 255, 14, + 160, 160, 225, 226, 77, 8, 255, 178, 118, 39, 248, 88, 56, 217, 113, 160, 209, 8, + 0, 140, 126, 171, 172, 12, 93, 82, 67, 64, 234, 3, 152, 165, 245, 137, 166, 131, + 218, 2, 177, 29, 84, 166, 186, 8, 42, 245, 54, 145, 160, 126, 86, 61, 131, 89, 22, + 160, 114, 81, 76, 246, 11, 153, 34, 100, 184, 198, 43, 2, 180, 83, 193, 165, 54, + 37, 212, 204, 215, 49, 39, 116, 222, 160, 126, 251, 244, 122, 135, 211, 3, 252, 89, + 162, 34, 15, 235, 205, 93, 159, 171, 6, 213, 189, 213, 223, 17, 136, 199, 254, 127, + 150, 153, 242, 158, 7, 160, 0, 53, 8, 236, 247, 236, 248, 247, 225, 155, 146, 46, + 95, 246, 225, 44, 111, 43, 92, 252, 212, 58, 208, 125, 204, 149, 39, 112, 188, 138, + 177, 107, 128, 128, 128, + ], + vec![ + 248, 113, 128, 128, 128, 128, 128, 160, 90, 69, 107, 219, 253, 138, 22, 197, 123, + 169, 48, 208, 29, 244, 54, 64, 26, 33, 180, 155, 153, 221, 168, 40, 98, 182, 91, + 178, 43, 170, 115, 153, 128, 128, 160, 148, 29, 172, 220, 20, 75, 103, 125, 205, + 59, 18, 1, 190, 50, 143, 224, 94, 172, 183, 211, 109, 156, 45, 19, 41, 85, 73, 3, + 225, 115, 167, 54, 128, 128, 128, 128, 128, 128, 160, 55, 161, 114, 79, 30, 112, + 182, 164, 75, 220, 84, 123, 141, 161, 31, 21, 13, 106, 247, 163, 245, 230, 99, 156, + 152, 95, 61, 127, 120, 150, 38, 56, 128, + ], + vec![ + 248, 81, 128, 128, 160, 16, 199, 4, 245, 162, 194, 163, 175, 45, 227, 201, 130, 93, + 89, 14, 146, 105, 114, 253, 197, 180, 187, 144, 5, 16, 54, 62, 149, 197, 213, 157, + 198, 128, 128, 128, 128, 128, 160, 252, 84, 179, 32, 171, 137, 126, 173, 198, 115, + 136, 179, 5, 108, 247, 113, 181, 223, 103, 47, 138, 160, 241, 123, 74, 243, 254, + 87, 209, 203, 77, 195, 128, 128, 128, 128, 128, 128, 128, 128, + ], + vec![ + 248, 65, 159, 60, 3, 201, 167, 144, 148, 99, 114, 173, 5, 157, 47, 119, 81, 218, + 54, 108, 248, 45, 205, 32, 185, 55, 231, 180, 251, 129, 223, 7, 32, 85, 160, 159, + 111, 171, 245, 30, 2, 82, 177, 191, 87, 208, 208, 160, 11, 160, 220, 75, 0, 135, + 232, 65, 160, 38, 209, 95, 135, 192, 247, 187, 186, 85, 132, + ], + ]; + let expected_value = Some(vec![ + 0, 111, 171, 245, 30, 2, 82, 177, 191, 87, 208, 208, 160, 11, 160, 220, 75, 0, 135, + 232, 65, 160, 38, 209, 95, 135, 192, 247, 187, 186, 85, 132, + ]); + if let Err(e) = verify_proof(&storage_root, &proof, key.as_slice(), &expected_value) { + unreachable!("{:?}", e); + } + } + + #[test] + fn test_trim_left_zero() { + assert_eq!(trim_left_zero(&[1, 2, 3, 4]), &vec![1, 2, 3, 4]); + assert_eq!(trim_left_zero(&[1, 2, 3, 0]), &vec![1, 2, 3, 0]); + assert_eq!(trim_left_zero(&[0, 2, 3, 0]), &vec![2, 3, 0]); + assert_eq!(trim_left_zero(&[0, 0, 3, 0]), &vec![3, 0]); + assert_eq!(trim_left_zero(&[0, 0, 0, 4]), &vec![4]); + assert!(trim_left_zero(&[0, 0, 0, 0]).is_empty()); + assert!(trim_left_zero(&[]).is_empty()); + } } diff --git a/light-client/src/errors.rs b/light-client/src/errors.rs index db1d934..8de2645 100644 --- a/light-client/src/errors.rs +++ b/light-client/src/errors.rs @@ -32,7 +32,13 @@ pub enum Error { // ConsensusState error AccountNotFound(Address), - UnexpectedStateValue(Hash, Vec>, Option>, Vec), + UnexpectedStateValue( + Hash, + Vec>, + Option>, + Vec, + Option>, + ), IllegalTimestamp(Time, Time), UnexpectedStateRoot(Vec), UnexpectedStorageRoot(Vec), @@ -191,11 +197,11 @@ impl core::fmt::Display for Error { write!(f, "UnexpectedSameBlockHash : {}", e1) } Error::UnknownMisbehaviourType(e1) => write!(f, "UnknownMisbehaviourType : {}", e1), - Error::UnexpectedStateValue(e1, e2, e3, e4) => { + Error::UnexpectedStateValue(e1, e2, e3, e4, e5) => { write!( f, - "UnexpectedStateValue : {:?} {:?} {:?} {:?}", - e1, e2, e3, e4 + "UnexpectedStateValue : {:?} {:?} {:?} {:?} {:?}", + e1, e2, e3, e4, e5 ) } Error::TrieError(e1) => {