From df4bb4f2fa541e60c9ac1cb6efe8d3c16fcf73f1 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Tue, 1 Feb 2022 15:08:44 +0800 Subject: [PATCH 1/7] fix empty branch check The code erroneously assumed that the inner op has the correct padding for the side it is checking. e.g. during IsLeftMost: when hasPadding(step) == false, leftBranchesAreEmpty(step, 0) is called, but 0 indicates a left-branch, and hasPadding == false implies this is _not_ a left branch. Instead, we must detect the branch index from the op's padding, since the caller does not know which, if any, branch this padding is valid for. --- go/proof.go | 30 +++++++++------- go/proof_test.go | 8 ++--- rust/src/verify.rs | 90 +++++++++++++++++++--------------------------- 3 files changed, 56 insertions(+), 72 deletions(-) diff --git a/go/proof.go b/go/proof.go index 8e40d768d..24cf9b595 100644 --- a/go/proof.go +++ b/go/proof.go @@ -216,7 +216,7 @@ func IsLeftMost(spec *InnerSpec, path []*InnerOp) bool { // ensure every step has a prefix and suffix defined to be leftmost, unless it is a placeholder node for _, step := range path { - if !hasPadding(step, minPrefix, maxPrefix, suffix) && !leftBranchesAreEmpty(spec, step, 0) { + if !hasPadding(step, minPrefix, maxPrefix, suffix) && !leftBranchesAreEmpty(spec, step) { return false } } @@ -230,7 +230,7 @@ func IsRightMost(spec *InnerSpec, path []*InnerOp) bool { // ensure every step has a prefix and suffix defined to be rightmost, unless it is a placeholder node for _, step := range path { - if !hasPadding(step, minPrefix, maxPrefix, suffix) && !rightBranchesAreEmpty(spec, step, int32(last)) { + if !hasPadding(step, minPrefix, maxPrefix, suffix) && !rightBranchesAreEmpty(spec, step) { return false } } @@ -310,12 +310,15 @@ func getPadding(spec *InnerSpec, branch int32) (minPrefix, maxPrefix, suffix int return } -// leftBranchesAreEmpty returns true if the padding bytes correspond to all empty children -// on the left side of this branch, ie. it's a valid placeholder on a leftmost path -func leftBranchesAreEmpty(spec *InnerSpec, op *InnerOp, branch int32) bool { - idx := getPosition(spec.ChildOrder, branch) +// leftBranchesAreEmpty returns true if the padding bytes correspond to all empty siblings +// on the left side of a branch, ie. it's a valid placeholder on a leftmost path +func leftBranchesAreEmpty(spec *InnerSpec, op *InnerOp) bool { + idx, err := orderFromPadding(spec, op) + if err != nil { + return false + } // count branches to left of this - leftBranches := idx + leftBranches := int(idx) if leftBranches == 0 { return false } @@ -333,12 +336,15 @@ func leftBranchesAreEmpty(spec *InnerSpec, op *InnerOp, branch int32) bool { return true } -// rightBranchesAreEmpty returns true if the padding bytes correspond to all empty children -// on the right side of this branch, ie. it's a valid placeholder on a rightmost path -func rightBranchesAreEmpty(spec *InnerSpec, op *InnerOp, branch int32) bool { - idx := getPosition(spec.ChildOrder, branch) +// rightBranchesAreEmpty returns true if the padding bytes correspond to all empty siblings +// on the right side of a branch, ie. it's a valid placeholder on a rightmost path +func rightBranchesAreEmpty(spec *InnerSpec, op *InnerOp) bool { + idx, err := orderFromPadding(spec, op) + if err != nil { + return false + } // count branches to right of this one - rightBranches := len(spec.ChildOrder) - 1 - idx + rightBranches := len(spec.ChildOrder) - 1 - int(idx) if rightBranches == 0 { return false } diff --git a/go/proof_test.go b/go/proof_test.go index e67aedf65..337982d30 100644 --- a/go/proof_test.go +++ b/go/proof_test.go @@ -63,14 +63,10 @@ func TestEmptyBranch(t *testing.T) { if err := tc.Op.CheckAgainstSpec(tc.Spec); err != nil { t.Errorf("Invalid InnerOp: %v", err) } - order, err := orderFromPadding(tc.Spec.InnerSpec, tc.Op) - if err != nil { - t.Errorf("Cannot get orderFromPadding: %v", err) - } - if leftBranchesAreEmpty(tc.Spec.InnerSpec, tc.Op, order) != tc.IsLeft { + if leftBranchesAreEmpty(tc.Spec.InnerSpec, tc.Op) != tc.IsLeft { t.Errorf("Expected leftBranchesAreEmpty to be %t but it wasn't", tc.IsLeft) } - if rightBranchesAreEmpty(tc.Spec.InnerSpec, tc.Op, order) != tc.IsRight { + if rightBranchesAreEmpty(tc.Spec.InnerSpec, tc.Op) != tc.IsRight { t.Errorf("Expected rightBranchesAreEmpty to be %t but it wasn't", tc.IsRight) } }) diff --git a/rust/src/verify.rs b/rust/src/verify.rs index b9231b319..1131a39ca 100644 --- a/rust/src/verify.rs +++ b/rust/src/verify.rs @@ -171,7 +171,7 @@ fn ensure_left_most(spec: &ics23::InnerSpec, path: &[ics23::InnerOp]) -> Result< let pad = get_padding(spec, 0)?; // ensure every step has a prefix and suffix defined to be leftmost, unless it is a placeholder node for step in path { - if !has_padding(step, &pad) && !left_branches_are_empty(spec, step, 0)? { + if !has_padding(step, &pad) && !left_branches_are_empty(spec, step)? { bail!("step not leftmost") } } @@ -184,7 +184,7 @@ fn ensure_right_most(spec: &ics23::InnerSpec, path: &[ics23::InnerOp]) -> Result let pad = get_padding(spec, idx as i32)?; // ensure every step has a prefix and suffix defined to be rightmost, unless it is a placeholder node for step in path { - if !has_padding(step, &pad) && !right_branches_are_empty(spec, step, idx as i32)? { + if !has_padding(step, &pad) && !right_branches_are_empty(spec, step)? { bail!("step not leftmost") } } @@ -264,62 +264,48 @@ fn get_padding(spec: &ics23::InnerSpec, branch: i32) -> Result { // left_branches_are_empty returns true if the padding bytes correspond to all empty children // on the left side of this branch, ie. it's a valid placeholder on a leftmost path -fn left_branches_are_empty( - spec: &ics23::InnerSpec, - op: &ics23::InnerOp, - branch: i32, -) -> Result { - if let Some(&idx) = spec.child_order.iter().find(|&&x| x == branch) { - // count branches to left of this - let left_branches = idx as usize; - if left_branches == 0 { +fn left_branches_are_empty(spec: &ics23::InnerSpec, op: &ics23::InnerOp) -> Result { + let idx = order_from_padding(spec, op)?; + // count branches to left of this + let left_branches = idx as usize; + if left_branches == 0 { + return Ok(false); + } + let child_size = spec.child_size as usize; + // compare prefix with the expected number of empty branches + let actual_prefix = match op.prefix.len().checked_sub(left_branches * child_size) { + Some(n) => n, + _ => return Ok(false), + }; + for i in 0..left_branches { + let from = actual_prefix + i * child_size; + if spec.empty_child != op.prefix[from..from + child_size] { return Ok(false); } - let child_size = spec.child_size as usize; - // compare prefix with the expected number of empty branches - let actual_prefix = match op.prefix.len().checked_sub(left_branches * child_size) { - Some(n) => n, - _ => return Ok(false), - }; - for i in 0..left_branches { - let from = actual_prefix + i * child_size; - if spec.empty_child != op.prefix[from..from + child_size] { - return Ok(false); - } - } - Ok(true) - } else { - bail!("Branch {} not found", branch); } + Ok(true) } // right_branches_are_empty returns true if the padding bytes correspond to all empty children // on the right side of this branch, ie. it's a valid placeholder on a rightmost path -fn right_branches_are_empty( - spec: &ics23::InnerSpec, - op: &ics23::InnerOp, - branch: i32, -) -> Result { - if let Some(&idx) = spec.child_order.iter().find(|&&x| x == branch) { - // count branches to right of this one - let right_branches = spec.child_order.len() - 1 - idx as usize; - // compare suffix with the expected number of empty branches - if right_branches == 0 { - return Ok(false); - } - if op.suffix.len() != spec.child_size as usize { +fn right_branches_are_empty(spec: &ics23::InnerSpec, op: &ics23::InnerOp) -> Result { + let idx = order_from_padding(spec, op)?; + // count branches to right of this one + let right_branches = spec.child_order.len() - 1 - idx as usize; + // compare suffix with the expected number of empty branches + if right_branches == 0 { + return Ok(false); + } + if op.suffix.len() != spec.child_size as usize { + return Ok(false); + } + for i in 0..right_branches { + let from = i * spec.child_size as usize; + if spec.empty_child != op.suffix[from..from + spec.child_size as usize] { return Ok(false); } - for i in 0..right_branches { - let from = i * spec.child_size as usize; - if spec.empty_child != op.suffix[from..from + spec.child_size as usize] { - return Ok(false); - } - } - Ok(true) - } else { - bail!("Branch {} not found", branch); } + Ok(true) } #[cfg(test)] @@ -719,19 +705,15 @@ mod tests { for (i, case) in cases.iter().enumerate() { ensure_inner(&case.op, case.spec)?; let inner = &case.spec.inner_spec.as_ref().unwrap(); - let order = match order_from_padding(inner, &case.op) { - Ok(branch) => branch, - _ => bail!("invalid op"), - }; assert_eq!( case.is_left, - left_branches_are_empty(inner, &case.op, order)?, + left_branches_are_empty(inner, &case.op)?, "case {}", i ); assert_eq!( case.is_right, - right_branches_are_empty(inner, &case.op, order)?, + right_branches_are_empty(inner, &case.op)?, "case {}", i ); From c60c04886b8f40db418fffb8091a6e47bab8ccb4 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Mon, 22 Nov 2021 19:32:54 +0800 Subject: [PATCH 2/7] add SmtSpec --- go/proof.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/go/proof.go b/go/proof.go index 24cf9b595..c59da2128 100644 --- a/go/proof.go +++ b/go/proof.go @@ -40,6 +40,26 @@ var TendermintSpec = &ProofSpec{ }, } +// SmtSpec constrains the format for SMT proofs (as implemented by github.com/celestiaorg/smt) +var SmtSpec = &ProofSpec{ + LeafSpec: &LeafOp{ + Hash: HashOp_SHA256, + PrehashKey: HashOp_NO_HASH, + PrehashValue: HashOp_SHA256, + Length: LengthOp_NO_PREFIX, + Prefix: []byte{0}, + }, + InnerSpec: &InnerSpec{ + ChildOrder: []int32{0, 1}, + ChildSize: 32, + MinPrefixLength: 1, + MaxPrefixLength: 1, + EmptyChild: make([]byte, 32), + Hash: HashOp_SHA256, + }, + MaxDepth: 256, +} + // Calculate determines the root hash that matches a given Commitment proof // by type switching and calculating root based on proof type // NOTE: Calculate will return the first calculated root in the proof, From 05d4f0347cc71743de8ab10ce9e251f3551148c7 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Sun, 12 Dec 2021 21:35:14 +0800 Subject: [PATCH 3/7] add testdata/smt --- testdata/smt/batch_exist.json | 86 +++++++++++++++++++++++++++++++ testdata/smt/batch_nonexist.json | 86 +++++++++++++++++++++++++++++++ testdata/smt/exist_left.json | 6 +++ testdata/smt/exist_middle.json | 6 +++ testdata/smt/exist_right.json | 6 +++ testdata/smt/nonexist_left.json | 6 +++ testdata/smt/nonexist_middle.json | 6 +++ testdata/smt/nonexist_right.json | 6 +++ 8 files changed, 208 insertions(+) create mode 100644 testdata/smt/batch_exist.json create mode 100644 testdata/smt/batch_nonexist.json create mode 100644 testdata/smt/exist_left.json create mode 100644 testdata/smt/exist_middle.json create mode 100644 testdata/smt/exist_right.json create mode 100644 testdata/smt/nonexist_left.json create mode 100644 testdata/smt/nonexist_middle.json create mode 100644 testdata/smt/nonexist_right.json diff --git a/testdata/smt/batch_exist.json b/testdata/smt/batch_exist.json new file mode 100644 index 000000000..6bd3b26f3 --- /dev/null +++ b/testdata/smt/batch_exist.json @@ -0,0 +1,86 @@ +{ + "items": [ + { + "key": "002c041fe1df37d806cc5b493bed02222d83b25ffebf9cb529b4524cc547fbeb", + "value": "76616c75655f666f725f636c536e4d46714a4e6162776a7a5134356e6d4d" + }, + { + "key": "fffa9eb3a5e49b7261d86e27c0e1c17f39215887308f5e3ca48e3264b03d2a2f", + "value": "76616c75655f666f725f6b63395874466e5a4645784d416f4b6f37566c5a" + }, + { + "key": "d905fdfb0063d1ae1cfb60037460005c24e77d0214d3f88f17e44ccfa302c533", + "value": "76616c75655f666f725f426f4c4f5279574251784c695835754c7257524a" + }, + { + "key": "85e3ed5362f3659ec475645ad63d9f23a1ce81cfdcbd17318768ea8133871a7d", + "value": "76616c75655f666f725f483977566967584c6d3330756f726a4b53423371" + }, + { + "key": "3df3a2ba5c2e903ce8a4f8fe8dda64f5973de99cdea4361a4873a00e0783ee06", + "value": "76616c75655f666f725f687848476735394278645a725657575647366239" + }, + { + "key": "a66a205c2b5a6101ceb0c39823500f9b10681e2c4ae2efa5f977a871faf77b1d", + "value": "76616c75655f666f725f6f62695655544657735949374a7a6c62654e3074" + }, + { + "key": "16659734ab7c95e3043ae7896fea9191a6a4d79186ea87e11c0414c2511d7e7f", + "value": "76616c75655f666f725f683139594138737249614956386b557936315672" + }, + { + "key": "b2943d32dde246b9140e0d97dbb1061ea681a385eca7abcc6d6b2b88ba4d5dbd", + "value": "76616c75655f666f725f6e586b6e744366514d53436a39625963516e325a" + }, + { + "key": "50ce16abe59462be0c5e6c67c865a281b91cf99d0e30bb324c97d69d611d9b70", + "value": "76616c75655f666f725f7542684a444c57425a7338765569786e6b314449" + }, + { + "key": "35684a8bb5bab8674ec7e6f19efc5cac19a2d6df21b8156bf86f6e86ab19d2e1", + "value": "76616c75655f666f725f56336e7859534c6c4a6b3739646d776b3330634b" + }, + { + "key": "153b5591bd409f92b9ac8a997abaab4cd79b6c41f923b8541c3ba5a1dd26953f", + "value": "76616c75655f666f725f395277644d4b354e786d506942755950454e695a" + }, + { + "key": "266c8f74eb0f2d19314153c5ec74aa343e79064bee1bd4280a5e3d2bb121dc27", + "value": "76616c75655f666f725f746b425246386e79314e4f35775244514d376c46" + }, + { + "key": "c7bcf000bd45ae83a6020d590a9d33cd29dfef1bdb2e98ba2482a489a48a8c13", + "value": "76616c75655f666f725f4e41334178576a42485233524b746a5071306575" + }, + { + "key": "d6f4d73207bcd05b9306710c8bd012bd198dd0383255ae72b56aa70850dfa1d6", + "value": "76616c75655f666f725f5559656353686a697731476b3942494b66686f6d" + }, + { + "key": "a57e080d7762b2ba42323ac47592708945ed6821687ab5e7f99a7d937d6a5c93", + "value": "76616c75655f666f725f3132784670387270355134664e3261577974774f" + }, + { + "key": "10afae10cb45e26a4ff4fe5ed2625de6b8171f00acef0a473fab915a2dd84f77", + "value": "76616c75655f666f725f324a69467553376255364f56343448423558524d" + }, + { + "key": "7ff463bd7f1f977b6fcb2b0d09dc84b56a7e8a7533c3b7619bb77de8691500fe", + "value": "76616c75655f666f725f637250313164794e664e506a3945484842753030" + }, + { + "key": "4b26caa4ea17fbecc86c3b18d9e9a60f5e9bb3f8df77bf886b23314de612b5ae", + "value": "76616c75655f666f725f5a78556e76433766477562364539325034455361" + }, + { + "key": "1d042634447135086099546f3cb98b482bf913f2be2bfeabc1fd828c842b6915", + "value": "76616c75655f666f725f3256386d7459664e6e3644566f556866636f516e" + }, + { + "key": "72a9edf278b5e09c2d3c9526f1345b1c862a9ead8e1a95621629b139684be33c", + "value": "76616c75655f666f725f504e4a4276453936456c66326559513643643939" + } + ], + "proof": "22b3430a5f0a5d0a20002c041fe1df37d806cc5b493bed02222d83b25ffebf9cb529b4524cc547fbeb121e76616c75655f666f725f636c536e4d46714a4e6162776a7a5134356e6d4d1a07080118012a01002210000102020102030405060708090a0b0c0a5b0a590a20fffa9eb3a5e49b7261d86e27c0e1c17f39215887308f5e3ca48e3264b03d2a2f121e76616c75655f666f725f6b63395874466e5a4645784d416f4b6f37566c5a1a07080118012a0100220c0d020e0f10111213141516170a600a5e0a20d905fdfb0063d1ae1cfb60037460005c24e77d0214d3f88f17e44ccfa302c533121e76616c75655f666f725f426f4c4f5279574251784c695835754c7257524a1a07080118012a0100221118190102011a1b1c1d1e1f2021222316170a590a570a2085e3ed5362f3659ec475645ad63d9f23a1ce81cfdcbd17318768ea8133871a7d121e76616c75655f666f725f483977566967584c6d3330756f726a4b534233711a07080118012a0100220a2425262728292a2b2c170a5b0a590a203df3a2ba5c2e903ce8a4f8fe8dda64f5973de99cdea4361a4873a00e0783ee06121e76616c75655f666f725f687848476735394278645a7256575756473662391a07080118012a0100220c2d02022e2f30313233340b0c0a5b0a590a20a66a205c2b5a6101ceb0c39823500f9b10681e2c4ae2efa5f977a871faf77b1d121e76616c75655f666f725f6f62695655544657735949374a7a6c62654e30741a07080118012a0100220c35363738393a3b3c3d3e2c170a5b0a590a2016659734ab7c95e3043ae7896fea9191a6a4d79186ea87e11c0414c2511d7e7f121e76616c75655f666f725f683139594138737249614956386b5579363156721a07080118012a0100220c3f40414243444546470a0b0c0a5b0a590a20b2943d32dde246b9140e0d97dbb1061ea681a385eca7abcc6d6b2b88ba4d5dbd121e76616c75655f666f725f6e586b6e744366514d53436a39625963516e325a1a07080118012a0100220c48494a4b4c4d4e4f503e2c170a5b0a590a2050ce16abe59462be0c5e6c67c865a281b91cf99d0e30bb324c97d69d611d9b70121e76616c75655f666f725f7542684a444c57425a7338765569786e6b3144491a07080118012a0100220c5152535455565758595a5b0c0a5b0a590a2035684a8bb5bab8674ec7e6f19efc5cac19a2d6df21b8156bf86f6e86ab19d2e1121e76616c75655f666f725f56336e7859534c6c4a6b3739646d776b3330634b1a07080118012a0100220c5c025d5e5f60616233340b0c0a590a570a20153b5591bd409f92b9ac8a997abaab4cd79b6c41f923b8541c3ba5a1dd26953f121e76616c75655f666f725f395277644d4b354e786d506942755950454e695a1a07080118012a0100220a636465664546470a0b0c0a5b0a590a20266c8f74eb0f2d19314153c5ec74aa343e79064bee1bd4280a5e3d2bb121dc27121e76616c75655f666f725f746b425246386e79314e4f35775244514d376c461a07080118012a0100220c670268696a6b6c6d6e340b0c0a590a570a20c7bcf000bd45ae83a6020d590a9d33cd29dfef1bdb2e98ba2482a489a48a8c13121e76616c75655f666f725f4e41334178576a42485233524b746a50713065751a07080118012a0100220a6f7071727374752316170a590a570a20d6f4d73207bcd05b9306710c8bd012bd198dd0383255ae72b56aa70850dfa1d6121e76616c75655f666f725f5559656353686a697731476b3942494b66686f6d1a07080118012a0100220a767778797a7b222316170a5b0a590a20a57e080d7762b2ba42323ac47592708945ed6821687ab5e7f99a7d937d6a5c93121e76616c75655f666f725f3132784670387270355134664e3261577974774f1a07080118012a0100220c7c7d7e7f80013b3c3d3e2c170a620a600a2010afae10cb45e26a4ff4fe5ed2625de6b8171f00acef0a473fab915a2dd84f77121e76616c75655f666f725f324a69467553376255364f56343448423558524d1a07080118012a01002213810101820101830184018501860146470a0b0c0a650a630a207ff463bd7f1f977b6fcb2b0d09dc84b56a7e8a7533c3b7619bb77de8691500fe121e76616c75655f666f725f637250313164794e664e506a39454848427530301a07080118012a0100221687010288010289018a018b018c018d018e018f015b0c0a650a630a204b26caa4ea17fbecc86c3b18d9e9a60f5e9bb3f8df77bf886b23314de612b5ae121e76616c75655f666f725f5a78556e764337664775623645393250344553611a07080118012a01002216900191010292019301940195019601970198015a5b0c0a660a640a201d042634447135086099546f3cb98b482bf913f2be2bfeabc1fd828c842b6915121e76616c75655f666f725f3256386d7459664e6e3644566f556866636f516e1a07080118012a010022179901019a019b019c019d019e019f01a001a101470a0b0c0a630a610a2072a9edf278b5e09c2d3c9526f1345b1c862a9ead8e1a95621629b139684be33c121e76616c75655f666f725f504e4a4276453936456c663265595136436439391a07080118012a01002214a2010201a301a401a501a601a7018e018f015b0c122708011201011a204c27b74a03394f254117dc2dd4aaa27ad2a3eccb0fa6f23dfc52eea501d133cd122708011201011a200000000000000000000000000000000000000000000000000000000000000000122508011221010000000000000000000000000000000000000000000000000000000000000000122708011201011a207a9e6f4327be207f312a80fecec582699f45b35e7fd2c3357c9c5ff7432f36f6122708011201011a206732b1eaa2cf07fbc94599aecc2df057d8efb0ccd775d86b6ea176bfaad367ad122708011201011a202267b5ddaf71187e34cc533c3e7ee25dfd386a3698249a482c28b4c4016389f1122708011201011a20d80dd2a33eba727f1464bc6ae82a164d56f057cbcfd68e8e5e01b16d62ca28f8122708011201011a2024f1a08038cec03788d6692c5f6581ab50318277ed47932e6d3bcf750df64141122708011201011a20050961036298f28b550ce8123f9f9ccfefcaf1059808c2f285bd24915da7ca80122708011201011a20b735a57c73e8399b6c4105d07aab95b2a7ff7fa7dd6bb3ee40ad21d157c55b84122708011201011a20eaac481f8ac8418ee1eabde1459b6ff7369b5ce8c034d63fc0169d49f9827bb4122708011201011a20207bedb000df636941dfcd8393a399cca2f3eea7013beb04c8257e36aa11f03a122708011201011a20be47d8a61c2acd356be44e9c83ed51bfa13503fded1ea8965d1dd9a721d98f9f12250801122101b76263b0c4e8438e81f21cdbff1e21b894a3c0e4ea08a0deab7c1de3292cd16a122508011221013ae2d90a118dd6f8a42f4006817e777f22540e921df1d97ed334a8b9de92c6cd1225080112210156a62a015a84af9a33ca716f52ed414382bed27a70b00391f15a5471f94443d31225080112210144c48bf2a802195fba5164a7a6c171a9af7a114c7880136108a5544d82fbacba1225080112210146eaec810967e45673028074c769ca2a8ddb3a5dbd47eab5cb6c5ccce3496eab122508011221013ff09e39daa0a77181976e045c441e4716144988ccf7cb308ef9820f40111437122508011221018228a63b956885383bb6168a8bc57b1edff829e2a2caee5200a600fbcc8b3d2512250801122101676d00d395acdcc0dec167c1a3ccf45fa415737faee5b74e8754df794a88b64d12250801122101ab73d025c6345f219bcc724c954729edaa496884d0f693c7645a8884fa0f298a1225080112210165a967ceeaf481cd2f5e2bc6d8f0435f5721b0739c3a4731f37ab11783133cbc122508011221011b8fec5bff949ff2c00ceed5c620f33c808249dccb408b623db89fa764a6ac5b12250801122101f46a611d5e06078694b314729936c2e52471923e187dbd5d71c74be963c22417122508011221012d2ed3841fb3fb2fdae10a427542a0a7e4932dc01c27c154c19610d205c3a22c122708011201011a208eeb8a660fbf34aeecaa4509aa72332a12beee8fc4e020938bb6ca1a69a4fbe5122708011201011a20cf24fd569b70a3903246200ff8f8d903eeaa2c5e35cffb65074bdcd7a4eb3b0c122708011201011a201862b3a21bd284386453f0734a4678b59b5411beee348419e2c138bce866709b122708011201011a2073b86c9d198aa201c55751b86fd99b341cfb288957cfb5270116a777993929d912250801122101cf53354a8ddd4d319a94a6505e41da6593291c434bdee02fada71d57cb432f3c122708011201011a20c43fb9e3554b3d229bb7a6633a4109a69cc926daff778ca7e1c80ee27ec1b283122708011201011a2054e7420dac859c97f26b8f0f73e4bf058ef2eaf6af66e63b27c02c3b33ad7adf122508011221013d0540608befb7ab726d97d0b44535a738ac3daa5cf362855a6060f56cd47a5c12250801122101a6900433c8bea8425e65d4fedf061073fa4f3c96d14b55272a6a4bee4112422d122708011201011a20133ce60dbeaff551d506eb85faf19a08d88c1aabc7a579b6a260b474bfe1976f122508011221013c6a80e5249148dd9db50e75bb37cc9bf00696a66af293ad42bb9fbbc1981c5012250801122101048117ba2b17332819e7b3afa6ee881356edf33fb28e78e5b555644d4db8109e12250801122101bd67b20b17090592c5f5eee64e8f9d24cd4807eb8d08224d730a25725ff105b2122708011201011a2038f93f3dbfd74b0545510d22698a4277cd2825fbf250efcf0db605fc12ec6319122508011221013d8771384f9457f041fa2259609025fb25480ead83819eb418050cc0079b133e122708011201011a202b2520f45c94631a59b98227c7747a212e4fcb5e4d524464c84e67ae67e1c28e122708011201011a20d4a6e9e4496a7cd271b0e307292f254b38499c76ab01dc848331527e069b093b122708011201011a20dbfb4b9dc45de4ba516bbbf08ddde13e5fa408500ef27423ad4d3a2147b7bea5122708011201011a2036e9058727831dbca632c540b911facabe0bb512ce623052f57fae7449be7a9d12250801122101ca23541c87a7f1c08e35aec96771b3c6e642a991a23f5a71982299237b9c7c1c1225080112210159d8ca1196e3cb12f21b1a275e58588d569c0253a3ce5bf19b5e29e08f8884b01225080112210199e76c784c50b3e2c1570d6d70fc98ef981ca02f85338d9900a1d52cbea46d01122708011201011a20e980532774bf16dceab254f91fcc05eedab3211ccc6c0d69f3717da1b9939478122508011221016744b9107f5be01d11cc98986bf40c7dd49bc257bf968a5b160b446cff18c8ab122508011221010693b77fd489e95f8cf1861fde23de6339cb359f1ecdf909c68b69843ab96e0a12250801122101058c30e22e96a0f99122609f4a6e50c6815240818eaddfa56c8ad9067da15e3512250801122101bfd69f527d0f170f15b1f4ac3bbaac0ca91560db2b77004722b9b94c2acc394b122708011201011a204128d7ac80e352269ece997a95565f9b606a4fa0890abf9b0cbf48e5a4eaad281225080112210160ad388ac451adb2074de377928b89211f49ae2d5f6e7b73c81035cfd2cfd709122508011221018c3d52acaf872248183fe11cd8f7541288040cd6ff05084e37ad92e94619f536122708011201011a20b3c4c041a69d63a5d978a67f6cffb1936dd81d43afec5e9c0aed9b34d4f931b4122708011201011a20a9e31a0ce8cfd15ffbed5aa7a32fd20e203f24cf5b7cc3ef05de2cdcf4f7529e122508011221011f7275251a725c43e8f9f829bc615ce3362ce8425af0cccd34643d72a5fa8b0b122508011221017562485b760afbcf9bdfa72c824f44b762187d254ad2526ef10731217cea0285122708011201011a202290d78dffcbd7c5d71e41ac7308d6a38ff8c4acef31f43e4ec08f9e9f13cb36122708011201011a2085bc034ff3b2d35bd6c722717f18cfb54aec81b93dd276ca2693f7553c80346c12250801122101ced5a0edfbcbb8e31f8bb407ee4b0adb3589d4212526f21fa96902a6cca63e39122708011201011a2024e0dc8ecb29d05f5e666ff9f48986369fa2cc4684945615d6a6e90c36676dcd122508011221012da3225bb1c80352a797e2a684dc842651368f0a4ce80de00d9d15b80bc0c89812250801122101483c72ce68ddcab1dc34b612173ef08a1e72e0f700e590742dc0377aca1a6433122708011201011a2053ef26fcc8a46af6cf1dfdbf40316ddf263c1bd507273e41e8c4107303343347122708011201011a20b9e15e2e63188aba2af500e8516cfebf7c65d9e038b0a4a442d774bcc05202971225080112210188f330dc91c6a3f114763242241dbc84fa5b80facb7f8a4ba249ec6e586eac6c122508011221016aa0a28b470b18ac7cf16ec89fe83cad82cfddcce596239f4414515575d8b422122708011201011a20cf58d802a5b45a1310985c5165c0870d54e17679917c590998aea8e7cc9b408012250801122101afa7971e8ac0609e2709ae13f218c83c632264c318291b2327c1e163305be47b12250801122101f32645861c9e82cf56bf46036d155b818c2cc2caa1bbcc7a43e836ce07d807ca122708011201011a2095f93afeb4bb39b73b8230931d17e78d2f4cc169c4bfec76f1d2f3a6fb21d0ff122708011201011a208ac52074530ae19b4ec74b68b18f8c667ef9769d25f95d7fa7f26e83533ae92112250801122101ebc209c74dae2128a7d333fc416d473b983ced345696e93ca927c81a18d95580122708011201011a2091ae2d65ad7c3dbb8beef46d09b6c5c3cdebe6e2c13317ccbf23169125a484f412250801122101b2b42e90de76bb2a06044a1aa5bf11fead5f5de8d4c74f8bc1a648921599bfdd122708011201011a20f8d08696b7dce82ddd748e84c8515d5d024aa7194124cd0b33655f6bd844705d122708011201011a20579c8ed83742c9bed43c204d30221f649ca130ccfb42dd857e5729b8a8e8a34f1225080112210155066699266cf25025b198ae536d48be0ee48a15a2f3dad9de43265be576bad8122708011201011a20401797c0f62b5f2e33337c584cfb78057e3bcb99f54815eb50ef359f26664a56122708011201011a20b77f3050d43d37012c9e96ba9e6fc532a4942ddde3ecdb5e4433bf24d7dd8b31122508011221015cd0738a9f9fbdabb5654c5d07469a2ed956c62d0a0b23df18e893db6904938512250801122101c3dd840575e9df89717bea07ab3aab4854f7008a3859d47e75eda84640427c0e122708011201011a20db586278ea6abb5683694e3d214c86e762709356ed2f44f8c9090ae7c95f1b77122708011201011a206b2f11e284032cf7920a95ea4b28434e3c37b95fea292684bfdf99cc25610db1122708011201011a206056323234df9abbeb02389c808c4f90f94a8705c6fae3cba93483410e30dda8122708011201011a20bd4eb1a98ba8e2fcb5b2c51f243cd217147e89eae0c93465042b264298e8af6312250801122101e03bc85478a74a95761b1d2a9438bd7341ae5532f171be75128907f45e027d9f122708011201011a20986ab3a15460d46f0ed38afbe9387d768fe219c118d0ccf70577ba4f12c3ec9612250801122101a490bedac9cc306dc7721bde73b8416e9f9564a298d1b2d37410a3f90135c216122708011201011a202e6b805bb42e7eea0487251c2332f61fd9ac55926a3e668251ae1f23d3a812a512250801122101b1222b2963878020e021dd28d2df05b4f8307084d13029c3915865f84afd56c0122708011201011a20efbef68b9a5b015b4a00d10037bb66ad245b5e30861eb64696934d889baea1a7122508011221018c24741b30a9c36ba0fcd873f4e21d98a80b8040761e2ea2d34332eeed6ee81b122708011201011a20b5a93de5e8dda4769f9c3397dd4b2638e7a437263f29f58de02d0d17932e449012250801122101ff1322a499933052c2e966eb031fc912d71ddbdde3a369f76ac826bfe05a27c8122708011201011a207c1990a63b7833bfd1d390e2e782483593dcef7067e4f587d6929bb48a3a2b03122708011201011a20b2c66013204af0eda043edb68c51524bc675b4fae5f6510af7eefe12b14ddd78122708011201011a2031825b5f7715b2a91d296b932050295634a3b922ef10922f6291ae7e9faef67f122508011221016cc9226a6d6f383c45f3912f9e0a2d4be5dfdfdbee09e04743d2fb22660d37ce122708011201011a20122193d0faace84387851c6dc891694f8d2ed47f41dba25881379197301a27aa122708011201011a2055b48726e5f1f8aecfece9471c8c6cce0a4ba4f5f77c7c611a097fa0fead749c12250801122101019363b91ed17ce573438eb65bbda4ea0e5482fda22bd96ed91a330bdf313c46122708011201011a205e053c924a657d6edd8810c12eddceee548ac86057f66a72e67745d0c03af09e122708011201011a204eb906b4d01cc39e57d88b28102cf543be7421282081b9fb727b2bba31f10bb7122508011221017a58369140367959e1cf1009e8b71d4c0d62a079a9bf0102f330aaf245cb13ed1225080112210119a4d2d17a37faf0605c8ac65cb4aac72de3d7779c64c8b78577df090685d442122708011201011a206db2b5ae7a1de14f4a8f779f0f12a4b67357945d3c15ecd7271aaf07a74e2dfa122708011201011a20d19a3c11a42b447b179bcfc7431a943cc3f597981a6c6dd91f994e1901e752d4122708011201011a20998c71664d07489f1856c64ab887a857547ac89df9a86c6b92da530cc36ec36c12250801122101076db06367bceb7bcc32067228a106cee4f2c8e6ea3c89cb71e47c9c248266281225080112210132606896f001c9d8dcd265d930d18e94582a3d52fb030da76a5dbb8f1cbcd432122508011221018aca2c209020a57524148ccab47c928969956a5978b2b6031dfe3580373065f912250801122101ce7c5c7aae73f63bdb4aee0d33ce99d1bbf659fc0d3caf444529c5bb015d66a3122708011201011a207829c213824cc50a7705b799054a848decd28dd78183683ec6b3b57e1a207f5d122708011201011a20b0d25f9fe186304e97f7a1892ac21caa48deac5750adba83e8e7a3ab68ae294e1225080112210145931a787b170595efe766b69445c8fff0f34bb32aa09c25c1fd832e25f9dbe31225080112210102a3bd7d067f1dd1e320c2cab008c73fcb9e090122ecd9510a1fd70408ddd61b122708011201011a2029c314de40783a3b5b2b0b0c9c0b2fd2cdc1fc85e1f9565a5e5d0577711f501c122508011221015a4b2962e8c1ec371e6e3cdc01f3e7385c77c6321bd995024a9e69ed3b90033712250801122101fafc67202686918c548c03e413e266a9178e61c3b7dd50b3cd058d2a78a646d5122708011201011a203978d57f079ea09d6d6d32710f019c4b09315375ed3ce1173e0667becb564c9312250801122101921da87ca3b5fcb796e07a7fbf7580e6d8c72e90d33e1bd46974c9360b45454412250801122101ad4ae81872a0132f51cd6ea883426f7e00030aec8c12779493007478ed85deac122708011201011a205302d42be40f87ac957be75c3c668ad4c91bae6eb1ed56e26c0d60eefba964fa122508011221013f1c8d8acbb5c8ad98797ba5e046bf6670121e97a351ba0781c6386d9afd8bbe122708011201011a20f8ff09744ca36902b580c24ca166418affc46818120d1d435b2d09bd8448317612250801122101e7fa82c24f93c1690f3e564b0a3f1b45eaed3c8f06bdcbc59a1fa416d7d5c820122508011221019efbbbf59c7ed77a5d3dc61b8b6f77178c2a2ed3ba6dc7fa61fffde02d19d3ee1225080112210185e5a25bf7906404130d2b57db9e68d8192919cf0ff186e694b1b019fd58ac88122708011201011a20388c501b4bda0c64c0a85d74d9ad1e7608de52b067a5d893ad83042aa0ffe5ad122708011201011a207b652e83c4d49c7f9476079ebde01742b61f724d51b8550d44ad2fa16e7d1044122708011201011a20879c5704e1df82bba5645ab26fce2d587d5a6f02079d0f43c349e9a4535672b8122708011201011a20f1ff26854e0c6e83717c88f7e4cee8369d046dbd9bacbdb6f278d2e29cf1135f122508011221016b905beec1e895cd07612a113f10a8a941391e4cf6c1c3319db4e00904e19bfd1225080112210171b33a17bab7756fc50d898e77689f22c2b6819ca0ca4bf53d57b6d080dc24d4122508011221018c9dedcadf0b0fb4013aca1a520143bdb24afda97fa33cc6e6c426648b2d641e12250801122101d41a8431fa556ce77f080be32758a8186d9544886e969b7341031982cbee336b12250801122101919dc73a4d6f20bb5fe14a4bbd57c1c58c52ac9ecd9cc167d1e4b0b013d9c264122508011221017f42ba0ab9cf7c3328509a669ff3f005fff65768eda3c78a08b507aa291e9f6d12250801122101550e4a13c7e10998bd0f28e012103c375eb83d02f870868e199a7c32d741c9b012250801122101ad81a0c099cd1f93e449fa2f4aa848c28e34fb0e4abc32d88fa05507418592cd122708011201011a20263b61b05d34033be1a2337b31aaab56b45283006b7c726b5bff4927810a9a77122708011201011a20900384b9152038b0ea841ab3fdd1719a75f60556fd7444c7c75b50111bdbf939122708011201011a203fe233a95d2d4cfde64850c9ff8280b74d060f6a575267cb78269709aaad7cd0122708011201011a201a6e8fc11ab2f3eb98d93c19ddb1534dd2753266373b7549ed3e2cb98adac735122508011221018384754befba9655eacc0c46ccb0c72344b710c4bf6ab42883fb0709634a4c4c1225080112210131734bd84fbc3542040ec104a6ab5378b8f5106ab621ee42f9f8f42e18a0db94122708011201011a20853799f77971e980c5f85e3e69b5bc3e7c86c223ba99395899f070fa0a14949912250801122101c4c4b88cd764772b9a4129ff4f9be42f795624b85f043b17afff7862bbc4ba9a122708011201011a204a1f1d9534fd0fe7df108acb235054232bf7378508c6f10dec6fe47bc01d151d12250801122101186fa2307c9f24158c61639492143e8940a466163d056c22db6cb8c0655af90a122708011201011a203313bb9fb8c001cf54523a2c896d1cad8d0a1c5ac12547c3bd66e93aa16345c0122708011201011a205d0119e99e0c4ffed7df85ccd6d3526d8ef09b1c352c21b2d520c4bbaa246f04122708011201011a203317850ab321269b8658e79bc7e07a5b5fd8335989d802c6610092fef9d7a875122708011201011a200f2c5d4672c826239e69174d3656f0d849ac37dd7c321504e409a26488a2d3d6122508011221019f1f6aa3dbfb07ce8a770510115ba4a0c8738586999c74fb01d07a407c796241122708011201011a20041132c96dc3eaacca49829e001dbc8728103125ee73c503ead0bacc861c774612250801122101c961801e9e3011097a7edc58adda84f3807c74f16cd8b41c6616db13d4a86c471225080112210195d4fff097a4a5b299f8b6c0d3ee99dae37d0170d53df7b32fd37361204cde08122708011201011a20dd19d74f3c321ae47274865e9e4ad151205f51f42fd46144f8b9876c8416479512250801122101a88bda4f1ebf49b72ee3db9b4851df750d8a1286c76ce585b376570ccd49ac68122708011201011a20903838cfa8d373a9fe71cdb27ea7d846f89b7ccb74fc2a963ea06f3af47c15df1225080112210155bb3c92cd308e1939fa9e96a05f072dc4b46a08a5a99eef7ee8c731e820f058122708011201011a209557e9d2ba170d82b0479ba3fdd6c26b846ed8c82d41725c39ec9c82adb42db8122708011201011a20188a65398211152f6c6c86f54023c3a1fb9b2f0b5d63d8f1bc9cd93daaffae94", + "root": "719e886178d2b75293341221dcbf83e81b7413c8c044790591a21cb3539ae8bb" +} diff --git a/testdata/smt/batch_nonexist.json b/testdata/smt/batch_nonexist.json new file mode 100644 index 000000000..b87170048 --- /dev/null +++ b/testdata/smt/batch_nonexist.json @@ -0,0 +1,86 @@ +{ + "items": [ + { + "key": "000da5e41c5fdd943b480cc680a1942d6708140827650e8e551df7b761bf5679", + "value": "" + }, + { + "key": "ffffedc8e4ee7f13c9892bf6277cdd60e4e8fad77abb37ca4f3b888a63b60df4", + "value": "" + }, + { + "key": "2580a152668e225c064e8294c4ac37c0e2e937069585db11bcfaaacc739b0170", + "value": "" + }, + { + "key": "7bb100695dac90a27c6385d20132065a304982c5d526bb410943c77b01772bf3", + "value": "" + }, + { + "key": "c376a2c6b5585e61f94d0dd49f836b6e091f05c716042b816d895803d35da8ff", + "value": "" + }, + { + "key": "685eb20b64a297b022101f367259d787fc6d3ef84daeade729cd71b64b57940f", + "value": "" + }, + { + "key": "990762888677cd36590b778a873bc49872d1f2f6bec43eb3adff3b096af9fcf4", + "value": "" + }, + { + "key": "81ee6f449452c4c3862725c94d2a913c81f7f1d1be7f7b45255214e6f8fcc34a", + "value": "" + }, + { + "key": "d1121ad88eb78aa120d5ca663a8b92b7a34f4c2e1472871e965372802b96cef7", + "value": "" + }, + { + "key": "f95291b046e3edd9e8b157034d6cabf7e150848c9e6c05304514ff2d71ca4b2c", + "value": "" + }, + { + "key": "c556fb88c9ebdc24d01de6f3886ca66c7e3035e41cbac398cd45be4858135d23", + "value": "" + }, + { + "key": "ad474e1cbc6e139fae5b08d013c98f9c788ca2f5816acb1d89f31ac3d33180f6", + "value": "" + }, + { + "key": "f57b12b550d86c56b4deaed234856df8dff1198cc2cea6cb810e6d0ffccf1000", + "value": "" + }, + { + "key": "116a37692d12c0f63e51bc31c9a28f19f35e908beb6c73fdc988c030375cfae4", + "value": "" + }, + { + "key": "8aff23862f54a1b1389cbdd8bba222b3eaefb839aacd862f0e23a5c90dc80b04", + "value": "" + }, + { + "key": "ea8f2dbf774b02bdf8401f778b5e4b814afb6ff48819f4e7a656f8cc46c282b4", + "value": "" + }, + { + "key": "e80dafcaea120e1002d666d4241e53105949d9137d80ac63e962a831ac4f3cf9", + "value": "" + }, + { + "key": "81d2838e71f2d2a1c5fc13d0f0702f19afdb0ac1e90ed5a03b81f2dd34003992", + "value": "" + }, + { + "key": "6e9749e7f0d819136a79c684245a991a0d312cf2052a33b5ad590679794597db", + "value": "" + }, + { + "key": "eb2bce9b290497f29cd3ab28d8887127d1a3850c5194573ea126e69f538438fd", + "value": "" + } + ], + "proof": "22e0600a84011281010a20000da5e41c5fdd943b480cc680a1942d6708140827650e8e551df7b761bf56791a5d0a20002c041fe1df37d806cc5b493bed02222d83b25ffebf9cb529b4524cc547fbeb121e76616c75655f666f725f636c536e4d46714a4e6162776a7a5134356e6d4d1a07080118012a01002210000102020102030405060708090a0b0c0a7f127d0a20ffffedc8e4ee7f13c9892bf6277cdd60e4e8fad77abb37ca4f3b888a63b60df412590a20fffa9eb3a5e49b7261d86e27c0e1c17f39215887308f5e3ca48e3264b03d2a2f121e76616c75655f666f725f6b63395874466e5a4645784d416f4b6f37566c5a1a07080118012a0100220c0d020e0f10111213141516170adb0112d8010a202580a152668e225c064e8294c4ac37c0e2e937069585db11bcfaaacc739b0170125a0a20257d88a052b5f671ee07719f369d3a287d27eb02aa41f2ae717c3470fddcb402121e76616c75655f666f725f6c664e6743464d6c55755443486c5873474d69501a07080118012a0100220d1819021a1b1c1d1e1f20210b0c1a580a202586aa84635b02a6fd9bfd4a645da735891063bbe4735e14a7b937e8308e802e121e76616c75655f666f725f41704f486c45776c50666d6c59565744676437541a07080118012a0100220b2223241c1d1e1f20210b0c0ad60112d3010a207bb100695dac90a27c6385d20132065a304982c5d526bb410943c77b01772bf312560a207b2c032a70a46c912987028dfc8ed989a4f5f5eae1c2626dac69d5d5a607bfc6121e76616c75655f666f725f516f4d41746337385453764c376a4845627630731a07080118012a0100220925262728292a2b2c0c1a570a207bb9257d961f9ea70a91101dd30f96c296226909d31a1b2fb883b002571cd72a121e76616c75655f666f725f394f76546a5573534844734550456d794f3838541a07080118012a0100220a2d2e262728292a2b2c0c0add0112da010a20c376a2c6b5585e61f94d0dd49f836b6e091f05c716042b816d895803d35da8ff125c0a20c35ebaa6d60ec870e48ef65bf2c632ab3d6ac414eb8cef78d4d1af868bc5c1b1121e76616c75655f666f725f443049745348644e4f6435304448566a336d63411a07080118012a0100220f2f02020230313233343536373816171a580a20c37b78696b8c32f1487c15de1bb4941e344f675d7b74b96d2279d2eee6fd8282121e76616c75655f666f725f6f4b32455030396f696a4e585a544e52514a74511a07080118012a0100220b39313233343536373816170adf0112dc010a20685eb20b64a297b022101f367259d787fc6d3ef84daeade729cd71b64b57940f12590a20681557866f464b09f95217deb2a0b9f2da071a3b63e79afc9fb6198d42440939121e76616c75655f666f725f514256456f334771573473697271626368317a5a1a07080118012a0100220c3a01013b3c3d3e3f402b2c0c1a5d0a206888307ec39b834c9597df4005f6b40c6eb3f811810189f98bd6e2f0be8664b5121e76616c75655f666f725f335332696a5a7556314f553159514d4b624836371a07080118012a0100221041010102424344453c3d3e3f402b2c0c0adf0112dc010a20990762888677cd36590b778a873bc49872d1f2f6bec43eb3adff3b096af9fcf4125f0a2098e3e89d1a8514d914757bb7baf58f904e1e377a0d47297d61361a3f208b5377121e76616c75655f666f725f324975527a584e4b46435349324d49457278444e1a07080118012a01002212460202020101014748494a4b4c4d4e4f50171a570a20993543603fa16a93bdd509eb39c746e17b3c05b09ed3b64ff8c78c263eb132e7121e76616c75655f666f725f336a7053783870474d317131534950474f4e496c1a07080118012a0100220a5152534b4c4d4e4f50170adb0112d8010a2081ee6f449452c4c3862725c94d2a913c81f7f1d1be7f7b45255214e6f8fcc34a12590a2081e1fd2fb133c8f844b89a3c65b65dd7d3431304cb2029edb60e797bce18e47b121e76616c75655f666f725f4b7534384848673743474f49686664646a6553581a07080118012a0100220c5455565758595a5b5c4f50171a590a2081fc9839a5d72f3811399f731c8e428712a378f38a218504513dae48d3de6c6d121e76616c75655f666f725f424358687767576e374a65734b7a6c706c4c42421a07080118012a0100220c5d55565758595a5b5c4f50170ad90112d6010a20d1121ad88eb78aa120d5ca663a8b92b7a34f4c2e1472871e965372802b96cef712570a20d10a4c2bc235926e7d2968877c17fd0467cc6e67c5b2c099d45c21027ebe70d1121e76616c75655f666f725f57454c70656b49654673316b4c616f75646572341a07080118012a0100220a5e5f60616263643816171a590a20d1479a9dea95b41d19c215b5773b689d3954c650bc23c9de10fff616c28fb8ba121e76616c75655f666f725f537159466d6456424353586864747332554374371a07080118012a0100220c6566675f60616263643816170ade0112db010a20f95291b046e3edd9e8b157034d6cabf7e150848c9e6c05304514ff2d71ca4b2c125c0a20f943f4c68c88ae09b332a76425bc0da1d53a70a9ad9b7760f5651c8061ae860a121e76616c75655f666f725f42514268305a373267386e6f6a33684161376b551a07080118012a0100220f6801010169026a6b6c6d13141516171a590a20f969519028597e8729814d329b8ee4c64d24b5607eb31a4c6635da5e7858d0fe121e76616c75655f666f725f5a336e767a524763575a755343433337766e37741a07080118012a0100220c6e6f026a6b6c6d13141516170ae20112df010a20c556fb88c9ebdc24d01de6f3886ca66c7e3035e41cbac398cd45be4858135d23125f0a20c539755dcb7ec5e1e1d82ce2fb2212de46ca7b1fe737dcf2a8d6d3289bbc4ae2121e76616c75655f666f725f46796b4f4947794c324858514e7564436d7a64751a07080118012a010022127001710101020272017374757636373816171a5a0a20c5906d4a8ffbd182cf176a3c9cda00ba86e2a897a811da9db5fd6dd6ac4a7f1a121e76616c75655f666f725f4c386c597650653343495a5850795378347742651a07080118012a0100220d770278797a74757636373816170ae90112e6010a20ad474e1cbc6e139fae5b08d013c98f9c788ca2f5816acb1d89f31ac3d33180f612610a20ad43956581bb53f5b800c23dce36827aec61fc8d9a365c4aa76a805f7b87f19b121e76616c75655f666f725f3665793451614e70465257686f536857434638351a07080118012a010022147b01017c7d027e7f8001810182018301840150171a5f0a20ad5dbc2b233ea6c3a89d822a1e6ad058ea600033a2f3a21409100e1439bd0021121e76616c75655f666f725f6572596b334c6769664a4f57625164374159726c1a07080118012a0100221285017d027e7f8001810182018301840150170ae20112df010a20f57b12b550d86c56b4deaed234856df8dff1198cc2cea6cb810e6d0ffccf1000125c0a20f579ad5e63b2aca7b4bccc38d4b9c898b527e5afca7cf173e6bbd37132742ce2121e76616c75655f666f725f35456b71304b5735714e36354c6d7435487737491a07080118012a0100220f8601018701880189018a01141516171a5d0a20f6149f6a0cef987e8f199242ec188118f466d8fb4e0ffec09f01d4cb9f74ac69121e76616c75655f666f725f6164574972434771563431584870586d696741581a07080118012a010022108b018c018d018e0189018a01141516170aeb0112e8010a20116a37692d12c0f63e51bc31c9a28f19f35e908beb6c73fdc988c030375cfae412620a2010afae10cb45e26a4ff4fe5ed2625de6b8171f00acef0a473fab915a2dd84f77121e76616c75655f666f725f324a69467553376255364f56343448423558524d1a07080118012a010022158f01019001019101920193019401950196010a0b0c1a600a2011a28bd9aaed0166c6e9de5229bd7eaf0a1621fd1a86536e28aed2ce3c31b465121e76616c75655f666f725f376834676464386433646a5435306a4d4f5337691a07080118012a01002213970102980102990193019401950196010a0b0c0ae80112e5010a208aff23862f54a1b1389cbdd8bba222b3eaefb839aacd862f0e23a5c90dc80b04125f0a208aea038c3c1f56c5025d4182c2b4d4f836bef3d0ee155cfddbfe004ed61903ea121e76616c75655f666f725f666634634357546a67437a654f67546e765275741a07080118012a010022129a019b019c019d019e019f01a0015c4f50171a600a208b4ee3b5d19a4cc2805f4f68bf08acd0a12ce5d545fe506edd3e1fc014972f5b121e76616c75655f666f725f46665549363845687639674c51553850467761691a07080118012a01002213a101a20102a301a4019e019f01a0015c4f50170ae70112e4010a20ea8f2dbf774b02bdf8401f778b5e4b814afb6ff48819f4e7a656f8cc46c282b412620a20ea5a4ff69887238f1a2bd469ed6bd1366709a052a43f3c29c68609b3415dcd92121e76616c75655f666f725f4f6c31483132613334593051426d3654305049581a07080118012a01002215a5010201a601a701a801a901aa01ab01ac011516171a5c0a20eadab42ea68ad2a847112884cd39e1f4c8ce2968f8ba00ddb5ff866c1613f9d9121e76616c75655f666f725f666a794f71705976756c774247776e7044734d4d1a07080118012a0100220fad01a801a901aa01ab01ac011516170ae70112e4010a20e80dafcaea120e1002d666d4241e53105949d9137d80ac63e962a831ac4f3cf912600a20e7fca8dbbceac9c969b98cc35a2225c70d3a7587c7b1758c60d79bec603217a6121e76616c75655f666f725f625755566e6438414a37524c6e397a62794f4b551a07080118012a01002213ae01af01b001b101b201b301b401ac011516171a5e0a20e83b9516c1667a669b72245f90800570cc35f69eb24afdc4adc038f80d97fdba121e76616c75655f666f725f5a61536b5339414d375a74446c773347473775361a07080118012a01002211b501b601b701b801aa01ab01ac011516170adf0112dc010a2081d2838e71f2d2a1c5fc13d0f0702f19afdb0ac1e90ed5a03b81f2dd34003992125d0a2081c49917599f2a0f69e96abff5cf3bc788dff54ccf13024a910b062d594f2517121e76616c75655f666f725f424f32476a67513549544565697530686a4675461a07080118012a01002210b9010101ba01565758595a5b5c4f50171a590a2081e1fd2fb133c8f844b89a3c65b65dd7d3431304cb2029edb60e797bce18e47b121e76616c75655f666f725f4b7534384848673743474f49686664646a6553581a07080118012a0100220c5455565758595a5b5c4f50170ae50112e2010a206e9749e7f0d819136a79c684245a991a0d312cf2052a33b5ad590679794597db12600a206e3d9be1203153c9f9800d3a59b643070303a8eff375fc446d40a0bb4aff025c121e76616c75655f666f725f42655937654e5442385a4a4572474c45346132341a07080118012a01002213bb0102bc0101bd01be01bf01c0013f402b2c0c1a5c0a206ea196ac35de1b8866853a28b8c3e961eb15d7c4fc624ebcd1ee5d31144a196a121e76616c75655f666f725f57726b7036354c654934787268506270744776541a07080118012a0100220fc101c201be01bf01c0013f402b2c0c0aec0112e9010a20eb2bce9b290497f29cd3ab28d8887127d1a3850c5194573ea126e69f538438fd125c0a20eadab42ea68ad2a847112884cd39e1f4c8ce2968f8ba00ddb5ff866c1613f9d9121e76616c75655f666f725f666a794f71705976756c774247776e7044734d4d1a07080118012a0100220fad01a801a901aa01ab01ac011516171a670a20eb3b19ad17f8a2567235d253276e827eb4d93edf9e487bede18260a0a6ffb77a121e76616c75655f666f725f7a48744a4d34333865764d526d515151673947371a07080118012a0100221ac3010202c401020202c501c601c701a901aa01ab01ac01151617122708011201011a204c27b74a03394f254117dc2dd4aaa27ad2a3eccb0fa6f23dfc52eea501d133cd122708011201011a200000000000000000000000000000000000000000000000000000000000000000122508011221010000000000000000000000000000000000000000000000000000000000000000122708011201011a207a9e6f4327be207f312a80fecec582699f45b35e7fd2c3357c9c5ff7432f36f6122708011201011a206732b1eaa2cf07fbc94599aecc2df057d8efb0ccd775d86b6ea176bfaad367ad122708011201011a202267b5ddaf71187e34cc533c3e7ee25dfd386a3698249a482c28b4c4016389f1122708011201011a20d80dd2a33eba727f1464bc6ae82a164d56f057cbcfd68e8e5e01b16d62ca28f8122708011201011a2024f1a08038cec03788d6692c5f6581ab50318277ed47932e6d3bcf750df64141122708011201011a20050961036298f28b550ce8123f9f9ccfefcaf1059808c2f285bd24915da7ca80122708011201011a20657d93a7331d35712e8480057c06baf379c8a2aada48365bfc943cc7b36af94e122708011201011a20eaac481f8ac8418ee1eabde1459b6ff7369b5ce8c034d63fc0169d49f9827bb4122708011201011a20207bedb000df636941dfcd8393a399cca2f3eea7013beb04c8257e36aa11f03a122708011201011a20e49182ab61bee9b787132b4092c4b3014f170ee3e845786f362998a9122984e612250801122101b76263b0c4e8438e81f21cdbff1e21b894a3c0e4ea08a0deab7c1de3292cd16a122508011221013ae2d90a118dd6f8a42f4006817e777f22540e921df1d97ed334a8b9de92c6cd1225080112210156a62a015a84af9a33ca716f52ed414382bed27a70b00391f15a5471f94443d31225080112210144c48bf2a802195fba5164a7a6c171a9af7a114c7880136108a5544d82fbacba1225080112210146eaec810967e45673028074c769ca2a8ddb3a5dbd47eab5cb6c5ccce3496eab122508011221013ff09e39daa0a77181976e045c441e4716144988ccf7cb308ef9820f4011143712250801122101ffdcb7da910966808d2d3bb3fd307b689c3ad49b9fde1424896c12063a84b75f12250801122101676d00d395acdcc0dec167c1a3ccf45fa415737faee5b74e8754df794a88b64d1225080112210105ed2c700945fe28a9fd7552975cd76e047454319f029bbf5be265c9bc54554b1225080112210154350e9d386d3ec494f76d0ce140dccb32a12fcf150745aab95471a2cee21fb1122508011221015a82302f68e12cbba17ccab8920ab5a100d9770a1504fe6b8d066beccd659745122508011221012d64758d6682c0d72a498d55be1ec1447b47cd6abf1d4ea8d4872c68dfdd11ef1225080112210116dc6e2093bc12c50a487ce251d8f1a5b3a1af59c3eb7132adbcba9f1fa778bb122508011221012dc2849158c9807287ecad05813a751ad863c4b7f66a243b66e991586bfccaf5122708011201011a20b6741f49d2db5052180ad02cca231c6aeac1333d515d6c490dac6e770278f638122508011221019a586bc3ee20b13fd03bf5b2a4461d5dd6fc5cf05c4c9c57303216e99dfbe239122708011201011a206dfada962670bb53945431e85063e191d5dc0fb6f19207d0a03d1055f801ad911225080112210119a4d2d17a37faf0605c8ac65cb4aac72de3d7779c64c8b78577df090685d442122708011201011a206db2b5ae7a1de14f4a8f779f0f12a4b67357945d3c15ecd7271aaf07a74e2dfa122708011201011a20d19a3c11a42b447b179bcfc7431a943cc3f597981a6c6dd91f994e1901e752d41225080112210118a3123f008e521520843625006577c5112f13fe624851e68a75613b7ac1a9e8122708011201011a2007b9aed070bfa3929d6dd5a4ab0d002c36e8a467f3d94e0d1b0d31773fd704d1122708011201011a207ec97d7e83fc505c030b81e395a5b19c1be86ed9f9dcd1fbb88e5edc5cbc6ad51225080112210168b051546044bfd33fc353d9a1b51b3afb762d3e27bfc475857f4295038e3254122708011201011a20eceb5dad8441fb687bf912c86ef77e3450902da06974913d4cb9881edd19a25212250801122101023ab1561db5979c5f009da8950a89b1b2c46bfe483bfda8d74d408a9564f04012250801122101ad0c58847b38b345ddd65b451ba0718df445572144eb2d5bab8225320a4d3869122708011201011a20a9672370788bd4c3b21487e1ff7daf9fd29055c33ef245e0d7ffbf29423afa0a122508011221017f42ba0ab9cf7c3328509a669ff3f005fff65768eda3c78a08b507aa291e9f6d12250801122101550e4a13c7e10998bd0f28e012103c375eb83d02f870868e199a7c32d741c9b012250801122101ad81a0c099cd1f93e449fa2f4aa848c28e34fb0e4abc32d88fa05507418592cd122508011221014fbe2d9c3066bf90ee87f5286b5adbe15b2b24ee71d39d1e975e24c964aef074122708011201011a200279a632ab7ad843f7aefc02c89d48423f765997719f2307177f9434e9f5845a122508011221010a5a5481f3a9523d353374777c2824c8487e4fad776105fb77d7fa2a11ab5732122508011221018015c60e22701c790051b93199dcd790c1733d79910898c85ced29e2ea03c464122708011201011a2046580f4438d7970a757449a1a8d7ab19b278ba7c5fd5041ed202dbfb62cfe66612250801122101e78070ad5b6a3392a54d1b7f541ee6ffc0a80b4f1dcd0286095a8f6330ef8fb2122708011201011a20cad792e7f4ee64cce5847de67882c26578efbd13700c7b032979c711e838445512250801122101f00585ec6dba7a13f34f71b9493a0d6fc5591638b51848d004702ccd4f697a50122508011221010efd2907c3aff8dafb0f72da84ceb19376fa1bec5d305c32101885b61aad5e7b122708011201011a20beb48a5b68c0fe3e514b4de894c96364087812a55e8dbb81a25a9976d91ea839122708011201011a207829c213824cc50a7705b799054a848decd28dd78183683ec6b3b57e1a207f5d122708011201011a20b0d25f9fe186304e97f7a1892ac21caa48deac5750adba83e8e7a3ab68ae294e122708011201011a2093fe012ca5775953d19f43e1e12752b88532608588f6b07b0cda97014579d37e12250801122101ad0e0a75d718ee8919e1ec2dd1b8ca45166f8868bdec7f52cd9a09aa2953a946122508011221019f6407dbbfd7317dbbda4d25ed767c45e897bc245a5051f2e7d9f1ccd9afbdfa122708011201011a207a147bea1ab0387504da2f907246d88cb8fd53ddb2cf994f9f7a86a053a18deb122708011201011a2001e07e7bf8b20cf9066b74cddee526edd36d760371a64bd11ba37339a4996b56122708011201011a20378eed6ef4ef986fd3d7ecc60b06fcb5bd991c51cc3b5fe7c2bb1ba5737f8ee4122708011201011a20ab1fbe82c840394b173785b166a6b40a71a3aedc24faed220c9d33d93501aec0122508011221018b014adefc2221a8fcda04c892040142485f69b15d85328789f94c9c6d65ce4c122708011201011a20d05bd5732fc00ecb341952f6f55240f00e795da842cdc333d3e21502620c6c03122708011201011a20cb5777a5c3853d79d3ba5a6a3bddab7d4bd3a18ef5e643742967b4b51a1f03cf122708011201011a20a6646e092d8a0fcaf26dc966b9b34987fc90bdcd5559a9182ce2671466b333b8122708011201011a20ddf7b89fbbae808f635f9f59f10fe3f29ebe2d9240158c7a0872bbfedcf02836122708011201011a206180367e0ef1e3eeb5b068ab5f27e59a581a516a40da40f4aebb8f6bd29923e912250801122101f28dcc2838635eddf2bc18727e1a0bbe6decb542a24c14f4732f793cc721b5a712250801122101c5b198042ebb553554734a4bfd8e11ff6682d7ee6638843153acce1d3666422f122508011221015074b5597289337449fd4e5198114ee3f8fd435204441bbd95ebc9ef1ba91874122508011221013182a16a4ab4e353d7e1c5f19e4bc32ddc94edc6ed22e1c82e28bf15733725a71225080112210115ea70cee62d2f5efdcb63881f3b493d1996f7ad61fed31af16f3d164229e481122708011201011a20d58a02ed02aa73394de38e275f99d8dd5ea5e71d5dd673bcb403e66b304294bf122708011201011a20c95ac9668a34761ccdd111d856992b20a0846b3e5e0e0a22121b752c591b7613122708011201011a203ae55f08905c68a2adbcdeacb26de2d609bd3e869ac66bac631e9502c92ae8f512250801122101fb082f2df8a2307274e40a7016cee71ade05e54f5558ed4f6c39991d4eb5c117122508011221018b7196f52f76efcbb7ab0467d1414a38bdc3301c978dbc5b326795d1bf431482122708011201011a20c4921f1afa5739d3a359f971e40a431a98b0188dd4b18f160ded84545769ba34122708011201011a20f8077d7c466da631d21ca54e1544db9ce6a2a4fd15145ec12fbc4adfc8e26628122708011201011a20d36e2a921c9f7e87f5b765185a991a4749ade4f99a6d5ac857f38665ae2ac3cc122708011201011a200ce4eb85cd6410e4c5e303948cae5a95522127b5a7fb491bf067f99e95ab6b6a12250801122101dbbc1bb871e574e1e708abf438782a09b4d4b6e8286c50a388e9ee5e4852b390122708011201011a2041e849a4259c8a305a7759e67a8e6fc95bb621a07a471ecfd3dacd9e353d824f122508011221012b5a98832c7bc5dd54801e7e100706332d58e560208fb62b06f3a77ddbecf075122508011221010ae70fac14ef0aa1b4051938569745fb3eb470675659b974f4bf68bf9706a7c012250801122101be4bf66cd45a4c4aaa7ff3857c3a42814555c7f7ec772bb1064dba946c6b328312250801122101eaf378c5c63442c551b21d5b6e43d54be67d451e2d26908afc2ea2cc3ffe3b7d122708011201011a20950e2179c815bfd8907d58128a7ae7c97daa5ab575af4171f644c8099010ad6f122708011201011a20d47d2c30c8448077ffa573c2c35a006220d7608a871e818ad29d3716daf485b9122708011201011a202b2520f45c94631a59b98227c7747a212e4fcb5e4d524464c84e67ae67e1c28e122708011201011a20d4a6e9e4496a7cd271b0e307292f254b38499c76ab01dc848331527e069b093b12250801122101168ddc9f9d7a14ab6353e9d31cb9b26fd91d2752bc8c5e7414d1e1cc4161e9fb122708011201011a200c9b1918cd04d1dc8de6b4fbb6a971f78bac178c5321f963df0b59606148cf5c122708011201011a2008bec402582cd245831ef538bb6dcfb9f3de2e7c8cd3e4077ea056998dc379591225080112210151dd9cb84f73eb1fba6f402ab9c79de2f5e4808612f3a209764790c661c8328d122708011201011a201e1efde4d1f12bbfceef37c9d9ffb43116624975f0a9a28ca642d9c500a7c8c0122708011201011a206e668cd3ff566cbbebdc256e9fe214a381079b6b9f4377909b76cceab49952f6122708011201011a203978d57f079ea09d6d6d32710f019c4b09315375ed3ce1173e0667becb564c93122508011221011aeb41adebc824fb9df4b0f004133ea0068f8d6048dcb3435af8d7e803710dd4122708011201011a20bbaf5df03403cb51ddf9090316fd0d0ed1077412394f7a2861b5da7d8bc98ebf122708011201011a2043d773c45158fdb231c1ea4ebd2ec61457fa77a886abea1981a6de4d263d4e8b12250801122101265936384fa658c0148f1842b942b9a2b5ff05f91edba9b997984aa9780cb3821225080112210157204e13cd8146b61b0864d4ec1fb2926bc4207ce3729b716f225b346edef077122708011201011a204aa1b82cd090ce99c3666f16b801cf28efa0e1dacdd91b46348aaa36117ae997122708011201011a20932fa47c2c8611b852545d85a3714e5b84102a1817b3d32ea359fee69376fcc0122508011221014a7fb59a20c67de5c95d701741dcafb0b2b424587d95ba08a48ea2887cc0be9c122708011201011a20ded91efa4177fffdac2795e86b73c57c25b6e5e77d390c3877859b791f385811122708011201011a20a3ed532793078461e21b64376577f3789338ec5bab6cc6559aeb306e7f9e3242122708011201011a207169495e53d639cb5f13e370c122e8266a3430217295336f77b592dd39bfa701122508011221011a5daddc81b3d7410433820681e37ab2437f978703ca2775f844a2992cd5595d1225080112210109e6a3c6b1dbc32d1af5178a7baa3df1e31ccf8520255a4aca37e649d62fa3c612250801122101001dd12ced870d2db0527fcd98cfb45f1c04a8211ab7292374010b6b8f0c01d812250801122101e2579b69672d24b2c8ace967126eb5c293ef978e3938ea2d94eed4f5dbae70b3122708011201011a20e98e3bc7a05844a192e2a9361f277188aab93853abdf34419ddd7098c090d8f51225080112210184c49247fdc0aef20e8dfaf047010764e084c4ae6b8a449eaebd1a6927c1bc63122708011201011a205431165031aa3557730f1f05b3dc36c981a29816f4851814838017203f34627a12250801122101983b2afefe44d668c42a75d72a4b1a06facc2dc38610acef33a7438fa918a98b122708011201011a20eb3e05749d936ecf8b5c5a09c52b9b58a8895be01c96bad625bdb7cc5135693e122708011201011a206c3c861f0d62e4945af0703f988a1c8571c1fbbdaee993f8d8114642374952ea122708011201011a2021e74bfc0537e1797d39980b1199b995c02a3d00dd4e7a84e72dbe8bc5aaf1d11225080112210137bef4dd27c2de86a41e7d487c2948ac12513bc72e3412ede04ca8526d102620122508011221010d1c82784b297bc946c7374232bdd741b26c73254271bc1d76c9e5e15e639ff6122708011201011a20579bf4a18e5abe8afdae625fd7bb4a4f341079bb104e1885fb322bd003c570a4122708011201011a20ae1285d65eb55c18dea08d4f2ef0a28791036650049025ec07fe0697c0a35cfc122708011201011a207a249163982a35cb260955598c1b1f143ff4bbb2fca0464f39315bc57012023a12250801122101dbfdb2c64bddc6cfd01e6f3c0ddfd36b13de2fc4315bc269901623bfff6027a1122708011201011a2081ca61864da86da04206d60b2939fba9a6ad4bb870eef466817b0e30c24c00471225080112210187642824cab7c3bca0044843945dcd350c5a61c7906792127d671f48de5d74b612250801122101e4feb818b7962b4c285c88154e13c8f6abe76d423ac20625d203a0405515cde4122708011201011a20925fb91059591774f00c6811e744444d43a09871a3be861325a404e0e1c406bf12250801122101ced5a0edfbcbb8e31f8bb407ee4b0adb3589d4212526f21fa96902a6cca63e39122508011221014c577d59f564ec54507d8161e5b79d5a411f2c4b1ddf46610d8b5c85c77c0abf12250801122101ce89e96deed4edb3294ee79b61ef950658df0430643d7f8315f39328d782dc9f1225080112210153783e42e17fc0eb36a3f982a3fc1ddac5481ce0f32dc9c2ccef4242044c03cb122708011201011a202b71ecd92886968bec1e3fed4e38fc54970c5007afa577c986316ba7635e355b1225080112210145200a18f2534749cbae17b829c2017b9c5609f480f091174df38f22416796c0122708011201011a2025f9d3d32e3ef8611589c63760b1a0e529028e17fbb1d557f8d753744dd56a8a122708011201011a206cb1efe64f6a744a6df7eae9b5e4f3f6c8eace5fd8e62e39ca2efa55cdbd7716122708011201011a20d978e2a4250873127c9f23c6424683557785624be9d66ccd62fa3404c4a743ec122708011201011a20f454e11d5c5030462b435f2677d7514c96629d4cf97b6a7e7c6a0cd894e3bba912250801122101124e9eb2c6a0ec7f465527caf0d9f3bfbd26568d78f5dcaafac599ce22d59eef12250801122101e7fa82c24f93c1690f3e564b0a3f1b45eaed3c8f06bdcbc59a1fa416d7d5c820122508011221019efbbbf59c7ed77a5d3dc61b8b6f77178c2a2ed3ba6dc7fa61fffde02d19d3ee1225080112210185e5a25bf7906404130d2b57db9e68d8192919cf0ff186e694b1b019fd58ac88122708011201011a20388c501b4bda0c64c0a85d74d9ad1e7608de52b067a5d893ad83042aa0ffe5ad122708011201011a207b652e83c4d49c7f9476079ebde01742b61f724d51b8550d44ad2fa16e7d1044122708011201011a20879c5704e1df82bba5645ab26fce2d587d5a6f02079d0f43c349e9a4535672b8122708011201011a203ad0761e4792bc789662828ab3983b31f4a93acec2f90306139bf8f85269a30912250801122101afa7971e8ac0609e2709ae13f218c83c632264c318291b2327c1e163305be47b122708011201011a207a4bce1ca4d1704903682e21f34eee82624907005e9ddd04b9fb084a87ba90d4122708011201011a20fa1881d8ea106faf335443cf0d5d84527c9dd421261a90b47ef3329bd9e843021225080112210189ac47f9679cb5136d295b78135c584eedad4123f92fcc94a64042e6823b0d6d12250801122101b6932938bdc08d6c13168390915b0b25d3c1d7951f3c61fc1c8fa49aa83cd4cc12250801122101d1995a2c320859d1bd9aa030124ab0517efe6944199877d95e46f6f964b5675612250801122101f881a68647ce50b69bf6be83bae146818eff71f878fa8c4c029c55b5b74dd9a3122708011201011a2054d77251f3b9f9c182a697d6f7edb95df5c43b38fed17c1974de6173efd979b412250801122101881c6394330f1602650a5226eac69263760f6303c6fe57088eae4b7d2809c0fa122708011201011a2009584133a128b5cdd27d1902cd73bb26ba479f1465a45990745e1bfe1c0b364f12250801122101bd64f703ec247f0d05a2877cba5fd9054f906c77fc3c00748f9c70a293a69fa6122708011201011a2077171562898b61be985cac22245826cd3799c3f0d9e0c09b7bb189e507c9edc5122708011201011a2016755dc9c634c80daf33278047ecbb82c8c542f71f144df20174128a3c904b76122708011201011a20eec0fe7410e008660595e66453704a4b2cad1cbb0a2420587b671bcaad1a8fc412250801122101414e30f086e99fd26c84b8fc04a4e1c38c49391eb921a588b3da49266a4a81f7122508011221011218b892bcd51b07b3b3850a448137ae28d1069d52bfbdb4a089c63fd40c368e1225080112210133568cec91245ccfd99f706c0563da48ce20cbadd2b51e1321ca54d045a9eb69122708011201011a20387d3570b66fa4e33a67e0f9d1fae695ab443a2f390e85b33a9427e546a8aec5122708011201011a2072c11303abe2de4843f725e40b00c9a2dff73ad8d4154521023ed8c8739ff68d12250801122101fdbceb97af12f8a1b83c3b759c1fc825e88c6090dc0d6b9caea961f68dc72c87122708011201011a20d3ed620e0d585ba618305f599988e15462ec48a24f3ec7ce2a00dddbdab7d09312250801122101668e2886cb8f73ae5295f09f20c316c21d7e633be2dae7b5a01b7c01d2830634122708011201011a20cc864565c845b4b53f083f69dec68438cd7ec8b848d485ffb6e893fe23f7e9481225080112210164ee33c6aa4304be656d80def8076791f2dbc6b54dc0fa997b0a9115747946bc1225080112210177556c07ad032fd183a1978441759260a29024cad7bf3740a5ee6cdd430ce91b122508011221017c057e865671e80b6dcda27d853772a1dff6fb41a6faac19af955678c77777b0122508011221015703835cdc085a48af6a648f43cf8420e4c81b503bd027c04211ef214b16172612250801122101315cd538f57e740ae25dc64464e6d7e1046a8c0777d9bec2e43886fa93e806a91225080112210124658892b5eb1979411d9bd12c643c70ccc1b336019df99471052dbca80aadd61225080112210142da6f06c33256fe77868c5812f6670713cae0b316425a77095a4b6166144e11122708011201011a20912a404f9b2dc0f3f92bec59ce1c9fb4c996a7170ada989eed88ce99628d17b8122708011201011a20d4eb294bdcea1065c8b24d57b4d1cd26b78f5345876907eda5eadb3e3976711c122708011201011a20160954659cb302bdd5cdafba68e113d9722394d9123a9cad87d7f128b0ce82c8122708011201011a20dd3fb99172a19ad6216c1c37aa45454d1803edf2f8e7dad77183928e017d9b8d122708011201011a2094650fcc185f666d229c717f56d44c0f40e96edc97dc22241c12178bac1b7c2812250801122101081c87cf7e23e1684a1886c0b22632f781bfde116fe2532e9256745f387811fe122708011201011a20fa6fa443a12c046fde4c437512f93fa6298ef6caeb1a99a01ed4ec062e5c2cfb12250801122101027b83e2628c39fb8340f33201a369fd6829ab6bf8e377bcde10412edbe5d9cd122508011221014f7ff1a0ef376fc76fe17953326045fc55d15e0042bd2160a8ebe01707d5a010122708011201011a201bf04c90368e4d72789b28f7b92bd582ce1a57a0f7cca50354511301fc360954122708011201011a20cb212bf4e11cd0a802dac501b71e877a669972f5d5e42c872ca9a7212ce79f25122508011221010b0dd000cbdfaa449f6356d4c710f88fece010774a9cc37dc656006b6c57577e12250801122101d60ca8a578c0ff7c0ca1024e5f66384ba4b8d85b6eda74f9464a43802e099391122708011201011a20d48ecb49a8205bf745d2963dd049a18b1db6ecbb20804d3b082c35f223b45f1412250801122101781d8d6f9695c35e68f320e3c2c07daf4c2fcfc5424527eba12aaf3a5dee8cc1122708011201011a206a6a5ce23cfb2174b88722a33bebc75e6b19ddc2391b973765032589793e32e0122708011201011a208894e9af93c88db14468a9c521af8e9894dd83079685a9f5d7a96ed4354d736a122708011201011a20e130943aa2036bb38beb3a5a8c0adf3530e8faa8aa592631fab0bcdd4bdf3472122708011201011a2012e560a1834e04950797d61ad16ddca9afc18c7979b5b9334608d04dcd870c69122508011221013be828dff60654f87ea63d50ff15c8549c2f92f8091cdaf0c579c24e00dde22c", + "root": "91343e9496c6b33823f631cfd502fe1c3c606bf9688c45e7514afe7401790f52" +} diff --git a/testdata/smt/exist_left.json b/testdata/smt/exist_left.json new file mode 100644 index 000000000..7a852e694 --- /dev/null +++ b/testdata/smt/exist_left.json @@ -0,0 +1,6 @@ +{ + "key": "002de9b963c4dacf518eeea7b754d2baac1886ef2f2a8ac704c05a692f4bedd5", + "proof": "0ae5030a20002de9b963c4dacf518eeea7b754d2baac1886ef2f2a8ac704c05a692f4bedd5121e76616c75655f666f725f4445687a30613576355036616536514c376d64451a07080118012a0100222708011201011a20bc79ee59a60c4f08cc0216a5f64d39f871cd730b6983079429e91d9bcd57d470222708011201011a206732b1eaa2cf07fbc94599aecc2df057d8efb0ccd775d86b6ea176bfaad367ad222708011201011a203112ffea611a3ef030f5ed8dafb8bcaf8e33bec16fff9027b1a0c718136de2d3222708011201011a20480983a2541b5527e1b5607e32f0597b12204d4973b5d9b498d1ff2a2350352b222708011201011a2097058f1bf50e2b47ad129fdaf2dfd53f88f81467dad54dabfcf0fbe8330c4e4c222708011201011a2008f6f1e45958b4780e1e0f7791315d44355eba4e519e2fb25c3dc48627a59a45222708011201011a20bb4f607cb62f20e673fdfad3e40a8b596db50dc7c34e65aba74eec37f791e886222708011201011a20fe97c3211b6a7eb3d859e754b373e89897a54f74244f0a84defc1df2a203dfd8222708011201011a202cab93bf9b91d25010972968d69b47ca9dfd5b4cea0c71310e0adced33acb19d222708011201011a2069ca519f1f2528c971a930cdd00b65c41762e8510ce3d4a998d4ad8ccf598984", + "root": "432d73b49019d8df5c7e38fd93288d0240a62a3c010e7217a4a74f5885c391d5", + "value": "76616c75655f666f725f4445687a30613576355036616536514c376d6445" +} diff --git a/testdata/smt/exist_middle.json b/testdata/smt/exist_middle.json new file mode 100644 index 000000000..90c0fba9e --- /dev/null +++ b/testdata/smt/exist_middle.json @@ -0,0 +1,6 @@ +{ + "key": "e369afec196c525d9e7ce3a6a94c325d3fd29b3d863c9463c939e8c085ae8e1a", + "proof": "0a80040a20e369afec196c525d9e7ce3a6a94c325d3fd29b3d863c9463c939e8c085ae8e1a121e76616c75655f666f725f464a544d75787a575873713470436c46506e6b481a07080118012a010022250801122101c607dff72d77496a8088f58c886a59e2c2e115c18688c1ea21007fa8a9c884da2225080112210152491dba094231188b893d16b0b08ad25246d5147a7a62149186518712618054222708011201011a20000000000000000000000000000000000000000000000000000000000000000022250801122101e3a85febd896e193b7ba37bc638c46d69530de820647fccb40da8583473c8feb222508011221014baf41d85dc399f406edbe4374e6b767663e4680fee217bfbca889618b7a83dc222708011201011a204ed121ef20f0e1d65a8a5e7d9ed86844de0bfd82621f3325f60eb872e9e738ea222708011201011a20a7cd5e87f54353e0b8d36901ba175daf7c00ff05c00183f522e94850a39ac4ce222708011201011a205a927fe700b5feacbf30a7cd160533e326c513eedc8e1d000cd8a71abd8480f522250801122101d9423c60941997d2078abd897d53f09cb4a844c684bc6a38140c04d6869809de22250801122101b1de51ac7abc0e0e5bc6955c4223228d16aba8cdb6e59bfd111d0901595bc32b22250801122101edbbd22b093f48404d082448bd335028477d700b449450b6800708095f78b9d6", + "root": "d32dd06714f3cee110cdb37ad7bc4760d4e291a555160f54429f9f15ddb04c4d", + "value": "76616c75655f666f725f464a544d75787a575873713470436c46506e6b48" +} diff --git a/testdata/smt/exist_right.json b/testdata/smt/exist_right.json new file mode 100644 index 000000000..5aaad154f --- /dev/null +++ b/testdata/smt/exist_right.json @@ -0,0 +1,6 @@ +{ + "key": "ffed47aeb9697fed0b7cb34fbe32e1659869afc95034196e43ab30653e7002b0", + "proof": "0ad1030a20ffed47aeb9697fed0b7cb34fbe32e1659869afc95034196e43ab30653e7002b0121e76616c75655f666f725f796c52704356713162706b4575786b526b68644f1a07080118012a0100222508011221013ae2d90a118dd6f8a42f4006817e777f22540e921df1d97ed334a8b9de92c6cd2225080112210156a62a015a84af9a33ca716f52ed414382bed27a70b00391f15a5471f94443d32225080112210144c48bf2a802195fba5164a7a6c171a9af7a114c7880136108a5544d82fbacba22250801122101c0bda8822a881b6a6a1dc5016bb062a9dd434ee3fe1c9bfb5bc0247bd6aeb5b42225080112210138cb0f6ef907a179a530fba848bae9547bcc37b9207aead6f7ef44064900386c2225080112210108f120d84fa1d8b2e7cc080673b382cb29169dd6e954b090f9cb7a25195d59a422250801122101ad476a123e0e8fbbbd4a225e29b193af4ae64600ccba4cc37922fc5d09159963222508011221013ad52a705d9b923dd07047aea6ad1bc1327e7557210c77cf06bcab7833ae313622250801122101c3a40ac7ab7c6cd3f267981dcd75158053dcad700af423ac0541ac0d315b4e7b222508011221017176acbe6927c4797f9e0456b7073802ad015fa8a915712e87b22830b72a1f94", + "root": "6177836ac520808df67bc402ae76382282f4f07a526a2ac25c409cf0380cad97", + "value": "76616c75655f666f725f796c52704356713162706b4575786b526b68644f" +} diff --git a/testdata/smt/nonexist_left.json b/testdata/smt/nonexist_left.json new file mode 100644 index 000000000..338596737 --- /dev/null +++ b/testdata/smt/nonexist_left.json @@ -0,0 +1,6 @@ +{ + "key": "002c041fe1df37d806cc5b493bed02222d83b25ffebf9cb529b4524cc547fbeb", + "proof": "128a040a20002c041fe1df37d806cc5b493bed02222d83b25ffebf9cb529b4524cc547fbeb1ae5030a20002de9b963c4dacf518eeea7b754d2baac1886ef2f2a8ac704c05a692f4bedd5121e76616c75655f666f725f4445687a30613576355036616536514c376d64451a07080118012a0100222708011201011a205aa5f240071f196e8d21e38b3fa6e942d5c529cd5fa0eec85607ba8cd8e37985222708011201011a206732b1eaa2cf07fbc94599aecc2df057d8efb0ccd775d86b6ea176bfaad367ad222708011201011a20074e19b2ce9887b188cabd61f0af10d699c206d4eee9c5e914bcfea5960439f8222708011201011a208c8012ca455d57135bea305ad1080cc0a9d8dec078a7813736ff871b40708a72222708011201011a200c70649c4ea15de4a2f2087a340fa93adb880f851d5465481349803315201ecd222708011201011a20ca5d1f4ee19172af78ff61c113336292c11c89884ead5b541f54cc53449e2edf222708011201011a2091a26f99a2852c72dd4a15c6b0444421a6d033f7f570f10c8c564bc3dce2fbc3222708011201011a206bdf78f09ef3fc2789b9a48e5e741e722dbf44050ec052de79135fbabf10ccd6222708011201011a20ecbc7b302eae49d180b8d1f1fb36e7c5d19f84ce3c5d9a84e4913ef73a9cbab2222708011201011a2010d3a9e28ea143c3b9910b1d40e6087e97520bc2a3dbe66a806bf214039fdb1b", + "root": "50be82f8013965f595392462f6c68b4c1d3d3401210a1084f6f73e3e2caf0648", + "value": "" +} diff --git a/testdata/smt/nonexist_middle.json b/testdata/smt/nonexist_middle.json new file mode 100644 index 000000000..7813be6b8 --- /dev/null +++ b/testdata/smt/nonexist_middle.json @@ -0,0 +1,6 @@ +{ + "key": "ba46e91ed56ac7bea290f31a5b5492090243f111a536c49f589e978f2d3ee8df", + "proof": "12d1080a20ba46e91ed56ac7bea290f31a5b5492090243f111a536c49f589e978f2d3ee8df12b2030a20ba43cb0567c827f469cf599f2a9756a0da1793edb84b4821ec1f62d2c3798ae4121e76616c75655f666f725f676e4e34356d52326831367467786a646f38544e1a07080118012a0100222708011201011a20d9948e386372dc85899e1890e988d8e47677c0bc211c65b55b5f70134dc15b0f222708011201011a201c2caf7504cfca30f253fce9c82051c3dd167058b0e22d840f4d90d0a0b2a9f7222508011221012db282d912c7d3f1dfd2750db451ad6e8176abddef45eb41fe1830c8789c1700222708011201011a200bd4fd01f2784fc637cc886ec0db6c4465cd4b4c8eb7266aaf84e0127740af2c222508011221018bf18f4ddf61ff31cb450737f6cf733d53d40f99bc3da526071755c37cc08ee1222508011221017bc720cf72271f5ac20af7962453209d5278965672e2cfebe5135bf85187681222250801122101f8500cdcf5ae664bdefce1221c42a69cf057b071e34a0ab946526525d6f3bc4d222708011201011a2027e93aecb0ea7d88fc13ce568017187ee5f07361f4d90e03866fb7f3f37a396622250801122101346d7d14c3a5521852f37261f20e91af45c5c0f772c13917b67d6eb6be9171ea1af7040a20bad9d45cc85eb8f5f14437c4328664e61dc03c06d21d8930986ddc86381ad0ac121e76616c75655f666f725f7252507a47715765774a6d6a38706b43453274641a07080118012a0100222708011201011a2003414f6402648178d0e76d39250d2e4cee54ec1f16e451cb602756a0a3044507222508011221010000000000000000000000000000000000000000000000000000000000000000222508011221010000000000000000000000000000000000000000000000000000000000000000222708011201011a20000000000000000000000000000000000000000000000000000000000000000022250801122101000000000000000000000000000000000000000000000000000000000000000022250801122101f18e35df2f213a21db25d856f3532afb9b1f7f47073f6f009507ddacd6d7457c222708011201011a201c2caf7504cfca30f253fce9c82051c3dd167058b0e22d840f4d90d0a0b2a9f7222508011221012db282d912c7d3f1dfd2750db451ad6e8176abddef45eb41fe1830c8789c1700222708011201011a200bd4fd01f2784fc637cc886ec0db6c4465cd4b4c8eb7266aaf84e0127740af2c222508011221018bf18f4ddf61ff31cb450737f6cf733d53d40f99bc3da526071755c37cc08ee1222508011221017bc720cf72271f5ac20af7962453209d5278965672e2cfebe5135bf85187681222250801122101f8500cdcf5ae664bdefce1221c42a69cf057b071e34a0ab946526525d6f3bc4d222708011201011a2027e93aecb0ea7d88fc13ce568017187ee5f07361f4d90e03866fb7f3f37a396622250801122101346d7d14c3a5521852f37261f20e91af45c5c0f772c13917b67d6eb6be9171ea", + "root": "771301eae8764c6147399a9944dd4454e865db8bc33e60f22bebea1c9bf7021e", + "value": "" +} diff --git a/testdata/smt/nonexist_right.json b/testdata/smt/nonexist_right.json new file mode 100644 index 000000000..0140f01dd --- /dev/null +++ b/testdata/smt/nonexist_right.json @@ -0,0 +1,6 @@ +{ + "key": "ffffedc8e4ee7f13c9892bf6277cdd60e4e8fad77abb37ca4f3b888a63b60df4", + "proof": "12c4040a20ffffedc8e4ee7f13c9892bf6277cdd60e4e8fad77abb37ca4f3b888a63b60df4129f040a20fffa9eb3a5e49b7261d86e27c0e1c17f39215887308f5e3ca48e3264b03d2a2f121e76616c75655f666f725f6b63395874466e5a4645784d416f4b6f37566c5a1a07080118012a010022250801122101b76263b0c4e8438e81f21cdbff1e21b894a3c0e4ea08a0deab7c1de3292cd16a222508011221010000000000000000000000000000000000000000000000000000000000000000222508011221013ae2d90a118dd6f8a42f4006817e777f22540e921df1d97ed334a8b9de92c6cd2225080112210156a62a015a84af9a33ca716f52ed414382bed27a70b00391f15a5471f94443d32225080112210144c48bf2a802195fba5164a7a6c171a9af7a114c7880136108a5544d82fbacba22250801122101354656582d1a82da7965901b2035596704419e5d238def48fdc03950624ee5182225080112210123ea47d69d737db4713327399685b2b15fc605d8b9fc63dad042cc7e2ca86b88222508011221010f0393085c3dd349cc0f45cb559fae81a1c4f24231afcb2b5ae51fd89262149322250801122101c5c632712f2341f6a31c3db7420c52c8d34df31704ce55856377cd9f23226469222508011221019209817b26ad0a91845bcbbd42453be5a6ba6f1c47e462014d6de896feede6522225080112210146446f4723153a265d03a7a20f4b906738d1af822434e77189134f45f2b2a80f22250801122101680acaa83722e275ea78c80914940c67efd48e5da6b331c821aaa2eb0ae184ed", + "root": "7bfe3d7630eb1f47be11d1724abad7a1b5de70c7131e7ed8ed60d9656ea49886", + "value": "" +} From c02d0292ac7b2bec0d3cc7f6f49fdbcd9be3ee36 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Mon, 13 Dec 2021 13:20:37 +0800 Subject: [PATCH 4/7] add smt to vector tests --- go/vectors_data_test.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/go/vectors_data_test.go b/go/vectors_data_test.go index d203ef7d0..ce12b7dc9 100644 --- a/go/vectors_data_test.go +++ b/go/vectors_data_test.go @@ -32,6 +32,7 @@ type TestVectorsStruct struct { func VectorsTestData() []TestVectorsStruct { iavl := filepath.Join("..", "testdata", "iavl") tendermint := filepath.Join("..", "testdata", "tendermint") + smt := filepath.Join("..", "testdata", "smt") cases := []TestVectorsStruct{ {Dir: iavl, Filename: "exist_left.json", Spec: IavlSpec}, {Dir: iavl, Filename: "exist_right.json", Spec: IavlSpec}, @@ -45,6 +46,12 @@ func VectorsTestData() []TestVectorsStruct { {Dir: tendermint, Filename: "nonexist_left.json", Spec: TendermintSpec}, {Dir: tendermint, Filename: "nonexist_right.json", Spec: TendermintSpec}, {Dir: tendermint, Filename: "nonexist_middle.json", Spec: TendermintSpec}, + {Dir: smt, Filename: "exist_left.json", Spec: SmtSpec}, + {Dir: smt, Filename: "exist_right.json", Spec: SmtSpec}, + {Dir: smt, Filename: "exist_middle.json", Spec: SmtSpec}, + {Dir: smt, Filename: "nonexist_left.json", Spec: SmtSpec}, + {Dir: smt, Filename: "nonexist_right.json", Spec: SmtSpec}, + {Dir: smt, Filename: "nonexist_middle.json", Spec: SmtSpec}, } return cases } @@ -69,6 +76,7 @@ type BatchVectorData struct { func BatchVectorsTestData(t *testing.T) map[string]BatchVectorData { iavl := filepath.Join("..", "testdata", "iavl") tendermint := filepath.Join("..", "testdata", "tendermint") + smt := filepath.Join("..", "testdata", "smt") // Note that each item has a different commitment root, // so maybe not ideal (cannot check multiple entries) batchIAVL, refsIAVL := buildBatch(t, iavl, []string{ @@ -87,10 +95,22 @@ func BatchVectorsTestData(t *testing.T) map[string]BatchVectorData { "nonexist_right.json", "nonexist_middle.json", }) + batchSMT, refsSMT := buildBatch(t, smt, []string{ + "exist_left.json", + "exist_right.json", + "exist_middle.json", + "nonexist_left.json", + "nonexist_right.json", + "nonexist_middle.json", + }) + batchTMExist, refsTMExist := loadBatch(t, tendermint, "batch_exist.json") batchTMNonexist, refsTMNonexist := loadBatch(t, tendermint, "batch_nonexist.json") batchIAVLExist, refsIAVLExist := loadBatch(t, iavl, "batch_exist.json") batchIAVLNonexist, refsIAVLNonexist := loadBatch(t, iavl, "batch_nonexist.json") + batchSMTexist, refsSMTexist := loadBatch(t, smt, "batch_exist.json") + batchSMTnonexist, refsSMTnonexist := loadBatch(t, smt, "batch_nonexist.json") + return map[string]BatchVectorData{ "iavl 0": {Spec: IavlSpec, Proof: batchIAVL, Ref: refsIAVL[0]}, "iavl 1": {Spec: IavlSpec, Proof: batchIAVL, Ref: refsIAVL[1]}, @@ -114,18 +134,32 @@ func BatchVectorsTestData(t *testing.T) map[string]BatchVectorData { "tm invalid 2": {Spec: TendermintSpec, Proof: refsTML, Ref: refsIAVL[0], Invalid: true}, "tm batch exist": {Spec: TendermintSpec, Proof: batchTMExist, Ref: refsTMExist[10]}, "tm batch nonexist": {Spec: TendermintSpec, Proof: batchTMNonexist, Ref: refsTMNonexist[3]}, + "smt 0": {Spec: SmtSpec, Proof: batchSMT, Ref: refsSMT[0]}, + "smt 1": {Spec: SmtSpec, Proof: batchSMT, Ref: refsSMT[1]}, + "smt 2": {Spec: SmtSpec, Proof: batchSMT, Ref: refsSMT[2]}, + "smt 3": {Spec: SmtSpec, Proof: batchSMT, Ref: refsSMT[3]}, + "smt 4": {Spec: SmtSpec, Proof: batchSMT, Ref: refsSMT[4]}, + "smt 5": {Spec: SmtSpec, Proof: batchSMT, Ref: refsSMT[5]}, + // Note this spec only differs for non-existence proofs + "smt invalid 1": {Spec: IavlSpec, Proof: batchSMT, Ref: refsSMT[4], Invalid: true}, + "smt invalid 2": {Spec: SmtSpec, Proof: batchSMT, Ref: refsIAVL[0], Invalid: true}, + "smt batch exist": {Spec: SmtSpec, Proof: batchSMTexist, Ref: refsSMTexist[10]}, + "smt batch nonexist": {Spec: SmtSpec, Proof: batchSMTnonexist, Ref: refsSMTnonexist[3]}, } } func DecompressBatchVectorsTestData(t *testing.T) map[string]*CommitmentProof { iavl := filepath.Join("..", "testdata", "iavl") tendermint := filepath.Join("..", "testdata", "tendermint") + smt := filepath.Join("..", "testdata", "smt") // note that these batches are already compressed batchIAVL, _ := loadBatch(t, iavl, "batch_exist.json") batchTM, _ := loadBatch(t, tendermint, "batch_nonexist.json") + batchSMT, _ := loadBatch(t, smt, "batch_nonexist.json") return map[string]*CommitmentProof{ "iavl": batchIAVL, "tendermint": batchTM, + "smt": batchSMT, } } From 7a381557b18389b4deecfc59a6790e1378e12867 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Wed, 15 Dec 2021 18:10:11 +0800 Subject: [PATCH 5/7] rust add smt spec --- rust/src/api.rs | 24 ++++++++++++++++++++++++ rust/src/lib.rs | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/rust/src/api.rs b/rust/src/api.rs index befb109ee..cfb335763 100644 --- a/rust/src/api.rs +++ b/rust/src/api.rs @@ -204,6 +204,30 @@ pub fn tendermint_spec() -> ics23::ProofSpec { } } +pub fn smt_spec() -> ics23::ProofSpec { + let leaf = ics23::LeafOp { + hash: ics23::HashOp::Sha256.into(), + prehash_key: 0, + prehash_value: ics23::HashOp::Sha256.into(), + length: 0, + prefix: vec![0_u8], + }; + let inner = ics23::InnerSpec { + child_order: vec![0, 1], + min_prefix_length: 1, + max_prefix_length: 1, + child_size: 32, + empty_child: vec![0; 32], + hash: ics23::HashOp::Sha256.into(), + }; + ics23::ProofSpec { + leaf_spec: Some(leaf), + inner_spec: Some(inner), + min_depth: 0, + max_depth: 0, + } +} + #[cfg(feature = "std")] #[cfg(test)] mod tests { diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 77eeee13c..d6a932458 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -15,7 +15,7 @@ mod verify; pub use crate::ics23::*; pub use api::{ - iavl_spec, tendermint_spec, verify_batch_membership, verify_batch_non_membership, + iavl_spec, smt_spec, tendermint_spec, verify_batch_membership, verify_batch_non_membership, verify_membership, verify_non_membership, }; pub use compress::{compress, decompress, is_compressed}; From ac18e0426b9bf4ee6e2bfb0b23d4216629c3e4cc Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Wed, 15 Dec 2021 12:58:35 +0800 Subject: [PATCH 6/7] rust port smt vector tests --- rust/src/api.rs | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/rust/src/api.rs b/rust/src/api.rs index cfb335763..f1e596d0d 100644 --- a/rust/src/api.rs +++ b/rust/src/api.rs @@ -383,6 +383,48 @@ mod tests { verify_test_vector("../testdata/tendermint/nonexist_middle.json", &spec) } + #[test] + #[cfg(feature = "std")] + fn test_vector_smt_left() -> Result<()> { + let spec = smt_spec(); + verify_test_vector("../testdata/smt/exist_left.json", &spec) + } + + #[test] + #[cfg(feature = "std")] + fn test_vector_smt_right() -> Result<()> { + let spec = smt_spec(); + verify_test_vector("../testdata/smt/exist_right.json", &spec) + } + + #[test] + #[cfg(feature = "std")] + fn test_vector_smt_middle() -> Result<()> { + let spec = smt_spec(); + verify_test_vector("../testdata/smt/exist_middle.json", &spec) + } + + #[test] + #[cfg(feature = "std")] + fn test_vector_smt_left_non() -> Result<()> { + let spec = smt_spec(); + verify_test_vector("../testdata/smt/nonexist_left.json", &spec) + } + + #[test] + #[cfg(feature = "std")] + fn test_vector_smt_right_non() -> Result<()> { + let spec = smt_spec(); + verify_test_vector("../testdata/smt/nonexist_right.json", &spec) + } + + #[test] + #[cfg(feature = "std")] + fn test_vector_smt_middle_non() -> Result<()> { + let spec = smt_spec(); + verify_test_vector("../testdata/smt/nonexist_middle.json", &spec) + } + #[cfg(feature = "std")] fn load_batch(files: &[&str]) -> Result<(ics23::CommitmentProof, Vec)> { let mut entries = Vec::new(); @@ -529,4 +571,66 @@ mod tests { ])?; verify_batch(&spec, &proof, &data[5]) } + + #[test] + #[cfg(feature = "std")] + fn test_vector_smt_batch_exist() -> Result<()> { + let spec = smt_spec(); + let (proof, data) = load_batch(&[ + "../testdata/smt/exist_left.json", + "../testdata/smt/exist_right.json", + "../testdata/smt/exist_middle.json", + "../testdata/smt/nonexist_left.json", + "../testdata/smt/nonexist_right.json", + "../testdata/smt/nonexist_middle.json", + ])?; + verify_batch(&spec, &proof, &data[0]) + } + + #[test] + #[cfg(feature = "std")] + fn compressed_smt_batch_exist() -> Result<()> { + let spec = smt_spec(); + let (proof, data) = load_batch(&[ + "../testdata/smt/exist_left.json", + "../testdata/smt/exist_right.json", + "../testdata/smt/exist_middle.json", + "../testdata/smt/nonexist_left.json", + "../testdata/smt/nonexist_right.json", + "../testdata/smt/nonexist_middle.json", + ])?; + let comp = compress(&proof)?; + verify_batch(&spec, &comp, &data[0]) + } + + #[test] + #[cfg(feature = "std")] + fn test_vector_smt_batch_nonexist() -> Result<()> { + let spec = smt_spec(); + let (proof, data) = load_batch(&[ + "../testdata/smt/exist_left.json", + "../testdata/smt/exist_right.json", + "../testdata/smt/exist_middle.json", + "../testdata/smt/nonexist_left.json", + "../testdata/smt/nonexist_right.json", + "../testdata/smt/nonexist_middle.json", + ])?; + verify_batch(&spec, &proof, &data[4]) + } + + #[test] + #[cfg(feature = "std")] + fn compressed_smt_batch_nonexist() -> Result<()> { + let spec = smt_spec(); + let (proof, data) = load_batch(&[ + "../testdata/smt/exist_left.json", + "../testdata/smt/exist_right.json", + "../testdata/smt/exist_middle.json", + "../testdata/smt/nonexist_left.json", + "../testdata/smt/nonexist_right.json", + "../testdata/smt/nonexist_middle.json", + ])?; + let comp = compress(&proof)?; + verify_batch(&spec, &comp, &data[4]) + } } From 01524aea841a1adba20a93eaa77ed3b427f7e6a6 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Wed, 15 Dec 2021 21:42:29 +0800 Subject: [PATCH 7/7] js smt spec --- js/src/proofs.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/js/src/proofs.ts b/js/src/proofs.ts index 17ada7590..3c93ce01a 100644 --- a/js/src/proofs.ts +++ b/js/src/proofs.ts @@ -42,6 +42,25 @@ export const tendermintSpec: ics23.IProofSpec = { }, }; +export const smtSpec: ics23.IProofSpec = { + leafSpec: { + hash: ics23.HashOp.SHA256, + prehashKey: ics23.HashOp.NO_HASH, + prehashValue: ics23.HashOp.SHA256, + length: ics23.LengthOp.NO_PREFIX, + prefix: Uint8Array.from([0]), + }, + innerSpec: { + childOrder: [0, 1], + childSize: 32, + minPrefixLength: 1, + maxPrefixLength: 1, + emptyChild: new Uint8Array(32), + hash: ics23.HashOp.SHA256 + }, + maxDepth: 256, +}; + export type CommitmentRoot = Uint8Array; // verifyExistence will throw an error if the proof doesn't link key, value -> root