Skip to content

Commit befc4ba

Browse files
committed
prove: mpt library is not robust either :)
1 parent cfe6d42 commit befc4ba

File tree

3 files changed

+146
-10
lines changed

3 files changed

+146
-10
lines changed

Cargo.lock

Lines changed: 62 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

trace_decoder/Cargo.toml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ bitvec = { workspace = true }
1818
bytes = { workspace = true }
1919
ciborium = { workspace = true }
2020
ciborium-io = { workspace = true }
21-
copyvec = "0.2.0"
21+
copyvec = { version = "0.2.0", features = ["quickcheck"] }
2222
either = { workspace = true }
2323
enum-as-inner = { workspace = true }
2424
ethereum-types = { workspace = true }
@@ -34,7 +34,7 @@ serde = { workspace = true }
3434
stackstack = "0.3.0"
3535
strum = { version = "0.26.3", features = ["derive"] }
3636
thiserror = { workspace = true }
37-
u4 = { workspace = true }
37+
u4 = { workspace = true, features = ["quickcheck"] }
3838
winnow = { workspace = true }
3939

4040
# Local dependencies
@@ -56,20 +56,15 @@ plonky2_maybe_rayon = { workspace = true }
5656
pretty_assertions = "1.4.0"
5757
pretty_env_logger = { workspace = true }
5858
prover = { workspace = true }
59+
quickcheck = "1.0.3"
5960
serde_json = { workspace = true }
6061
serde_path_to_error = { workspace = true }
6162

6263

6364
[features]
6465
default = ["eth_mainnet"]
65-
eth_mainnet = [
66-
"evm_arithmetization/eth_mainnet",
67-
"prover/eth_mainnet",
68-
]
69-
cdk_erigon = [
70-
"evm_arithmetization/cdk_erigon",
71-
"prover/cdk_erigon",
72-
]
66+
eth_mainnet = ["evm_arithmetization/eth_mainnet", "prover/eth_mainnet"]
67+
cdk_erigon = ["evm_arithmetization/cdk_erigon", "prover/cdk_erigon"]
7368

7469
[[bench]]
7570
name = "block_processing"

trace_decoder/src/typed_mpt.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,3 +500,82 @@ fn node_deletion_resulted_in_a_branch_collapse(
500500
// collapse.
501501
branch_collapse_occurred.then(|| mpt_trie::utils::IntoTrieKey::into_key(new_path.iter()))
502502
}
503+
504+
#[cfg(test)]
505+
mod tests {
506+
use std::array;
507+
508+
use itertools::Itertools as _;
509+
use quickcheck::Arbitrary;
510+
511+
use super::*;
512+
513+
quickcheck::quickcheck! {
514+
fn quickcheck(
515+
kvs: Vec<(TrieKey, Vec<u8>)>,
516+
mask_kvs: Vec<(TrieKey, Vec<u8>)>,
517+
khs: Vec<(TrieKey, ArbitraryHash)>
518+
) -> () {
519+
do_quickcheck(kvs, mask_kvs, khs)
520+
}
521+
}
522+
523+
fn do_quickcheck(
524+
kvs: Vec<(TrieKey, Vec<u8>)>,
525+
mask_kvs: Vec<(TrieKey, Vec<u8>)>,
526+
khs: Vec<(TrieKey, ArbitraryHash)>,
527+
) {
528+
let mut mpt = HashedPartialTrie::default();
529+
let mask = mask_kvs
530+
.iter()
531+
.map(|(k, _)| k.into_nibbles())
532+
.collect::<Vec<_>>();
533+
for (k, v) in kvs.into_iter().chain(mask_kvs) {
534+
let _ = mpt.insert(k.into_nibbles(), v);
535+
}
536+
for (k, ArbitraryHash(h)) in khs {
537+
let _ = mpt.insert(k.into_nibbles(), h);
538+
}
539+
let root = mpt.hash();
540+
if let Ok(sub) = mpt_trie::trie_subsets::create_trie_subset(&mpt, mask) {
541+
assert_eq!(sub.hash(), root)
542+
}
543+
}
544+
545+
impl Arbitrary for TrieKey {
546+
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
547+
Self(Arbitrary::arbitrary(g))
548+
}
549+
550+
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
551+
let Self(comps) = *self;
552+
Box::new(comps.shrink().map(Self))
553+
}
554+
}
555+
556+
#[derive(Debug, Clone, Copy)]
557+
struct ArbitraryHash(H256);
558+
impl ArbitraryHash {
559+
pub fn new((a, b, c, d): (u64, u64, u64, u64)) -> Self {
560+
let mut iter = [a, b, c, d].into_iter().flat_map(u64::to_ne_bytes);
561+
let h = H256(array::from_fn(|_| iter.next().unwrap()));
562+
assert_eq!(iter.count(), 0);
563+
Self(h)
564+
}
565+
}
566+
impl Arbitrary for ArbitraryHash {
567+
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
568+
Self::new(Arbitrary::arbitrary(g))
569+
}
570+
571+
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
572+
let Self(H256(bytes)) = self;
573+
let (a, b, c, d) = bytes
574+
.chunks_exact(8)
575+
.map(|it| u64::from_ne_bytes(it.try_into().unwrap()))
576+
.collect_tuple()
577+
.unwrap();
578+
Box::new((a, b, c, d).shrink().map(Self::new))
579+
}
580+
}
581+
}

0 commit comments

Comments
 (0)