deps: alloy-trie@0.6.0 (#11260)

This commit is contained in:
Roman Krasiuk
2024-09-26 20:30:48 +02:00
committed by GitHub
parent f4cbfbcd79
commit 77992e3254
6 changed files with 53 additions and 36 deletions

View File

@ -101,6 +101,9 @@ pub enum TrieWitnessError {
/// Missing target node.
#[display("target node missing from proof {_0:?}")]
MissingTargetNode(Nibbles),
/// Unexpected empty root.
#[display("unexpected empty root: {_0:?}")]
UnexpectedEmptyRoot(Nibbles),
}
impl From<TrieWitnessError> for ProviderError {

View File

@ -5,12 +5,13 @@ use alloy_primitives::{keccak256, Address, Bytes, B256, U256};
use alloy_rlp::{encode_fixed_size, Decodable};
use alloy_trie::{
nodes::TrieNode,
proof::{verify_proof, ProofVerificationError},
proof::{verify_proof, ProofNodes, ProofVerificationError},
EMPTY_ROOT_HASH,
};
use itertools::Itertools;
use reth_primitives_traits::{constants::KECCAK_EMPTY, Account};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use std::collections::HashMap;
/// The state multiproof of target accounts and multiproofs of their storage tries.
/// Multiproof is effectively a state subtrie that only contains the nodes
@ -18,7 +19,7 @@ use std::collections::{BTreeMap, HashMap};
#[derive(Clone, Default, Debug)]
pub struct MultiProof {
/// State trie multiproof for requested accounts.
pub account_subtree: BTreeMap<Nibbles, Bytes>,
pub account_subtree: ProofNodes,
/// Storage trie multiproofs.
pub storages: HashMap<B256, StorageMultiProof>,
}
@ -36,8 +37,8 @@ impl MultiProof {
// Retrieve the account proof.
let proof = self
.account_subtree
.iter()
.filter(|(path, _)| nibbles.starts_with(path))
.matching_nodes_iter(&nibbles)
.sorted_by(|a, b| a.0.cmp(b.0))
.map(|(_, node)| node.clone())
.collect::<Vec<_>>();
@ -82,12 +83,12 @@ pub struct StorageMultiProof {
/// Storage trie root.
pub root: B256,
/// Storage multiproof for requested slots.
pub subtree: BTreeMap<Nibbles, Bytes>,
pub subtree: ProofNodes,
}
impl Default for StorageMultiProof {
fn default() -> Self {
Self { root: EMPTY_ROOT_HASH, subtree: BTreeMap::default() }
Self { root: EMPTY_ROOT_HASH, subtree: Default::default() }
}
}
@ -99,8 +100,8 @@ impl StorageMultiProof {
// Retrieve the storage proof.
let proof = self
.subtree
.iter()
.filter(|(path, _)| nibbles.starts_with(path))
.matching_nodes_iter(&nibbles)
.sorted_by(|a, b| a.0.cmp(b.0))
.map(|(_, node)| node.clone())
.collect::<Vec<_>>();

View File

@ -136,7 +136,7 @@ where
}
}
let _ = hash_builder.root();
Ok(MultiProof { account_subtree: hash_builder.take_proofs(), storages })
Ok(MultiProof { account_subtree: hash_builder.take_proof_nodes(), storages })
}
/// Generate a storage multiproof according to specified targets.
@ -181,6 +181,6 @@ where
}
let root = hash_builder.root();
Ok(StorageMultiProof { root, subtree: hash_builder.take_proofs() })
Ok(StorageMultiProof { root, subtree: hash_builder.take_proof_nodes() })
}
}

View File

@ -10,8 +10,8 @@ use alloy_primitives::{
Bytes, B256,
};
use alloy_rlp::{BufMut, Decodable, Encodable};
use itertools::Either;
use reth_execution_errors::{StateProofError, TrieWitnessError};
use itertools::{Either, Itertools};
use reth_execution_errors::TrieWitnessError;
use reth_primitives::constants::EMPTY_ROOT_HASH;
use reth_trie_common::{
BranchNode, HashBuilder, Nibbles, TrieAccount, TrieNode, CHILD_INDEX_RANGE,
@ -120,24 +120,36 @@ where
None
};
let key = Nibbles::unpack(hashed_address);
let proof = account_multiproof.account_subtree.iter().filter(|e| key.starts_with(e.0));
account_trie_nodes.extend(self.target_nodes(key.clone(), value, proof)?);
account_trie_nodes.extend(
self.target_nodes(
key.clone(),
value,
account_multiproof
.account_subtree
.matching_nodes_iter(&key)
.sorted_by(|a, b| a.0.cmp(b.0)),
)?,
);
// Gather and record storage trie nodes for this account.
let mut storage_trie_nodes = BTreeMap::default();
let storage = state.storages.get(&hashed_address);
for hashed_slot in hashed_slots {
let slot_key = Nibbles::unpack(hashed_slot);
let slot_nibbles = Nibbles::unpack(hashed_slot);
let slot_value = storage
.and_then(|s| s.storage.get(&hashed_slot))
.filter(|v| !v.is_zero())
.map(|v| alloy_rlp::encode_fixed_size(v).to_vec());
let proof = storage_multiproof.subtree.iter().filter(|e| slot_key.starts_with(e.0));
storage_trie_nodes.extend(self.target_nodes(
slot_key.clone(),
slot_value,
proof,
)?);
storage_trie_nodes.extend(
self.target_nodes(
slot_nibbles.clone(),
slot_value,
storage_multiproof
.subtree
.matching_nodes_iter(&slot_nibbles)
.sorted_by(|a, b| a.0.cmp(b.0)),
)?,
);
}
Self::next_root_from_proofs(storage_trie_nodes, |key: Nibbles| {
@ -145,7 +157,7 @@ where
let mut padded_key = key.pack();
padded_key.resize(32, 0);
let target_key = B256::from_slice(&padded_key);
let mut proof = Proof::new(
let proof = Proof::new(
self.trie_cursor_factory.clone(),
self.hashed_cursor_factory.clone(),
)
@ -155,9 +167,9 @@ where
// The subtree only contains the proof for a single target.
let node =
proof.subtree.remove(&key).ok_or(TrieWitnessError::MissingTargetNode(key))?;
proof.subtree.get(&key).ok_or(TrieWitnessError::MissingTargetNode(key))?;
self.witness.insert(keccak256(node.as_ref()), node.clone()); // record in witness
Ok(node)
Ok(node.clone())
})?;
}
@ -165,19 +177,17 @@ where
// Right pad the target with 0s.
let mut padded_key = key.pack();
padded_key.resize(32, 0);
let mut proof =
let proof =
Proof::new(self.trie_cursor_factory.clone(), self.hashed_cursor_factory.clone())
.with_prefix_sets_mut(self.prefix_sets.clone())
.with_target((B256::from_slice(&padded_key), HashSet::default()))
.multiproof()?;
// The subtree only contains the proof for a single target.
let node = proof
.account_subtree
.remove(&key)
.ok_or(TrieWitnessError::MissingTargetNode(key))?;
let node =
proof.account_subtree.get(&key).ok_or(TrieWitnessError::MissingTargetNode(key))?;
self.witness.insert(keccak256(node.as_ref()), node.clone()); // record in witness
Ok(node)
Ok(node.clone())
})?;
Ok(self.witness)
@ -190,7 +200,7 @@ where
key: Nibbles,
value: Option<Vec<u8>>,
proof: impl IntoIterator<Item = (&'b Nibbles, &'b Bytes)>,
) -> Result<BTreeMap<Nibbles, Either<B256, Vec<u8>>>, StateProofError> {
) -> Result<BTreeMap<Nibbles, Either<B256, Vec<u8>>>, TrieWitnessError> {
let mut trie_nodes = BTreeMap::default();
for (path, encoded) in proof {
// Record the node in witness.
@ -216,6 +226,7 @@ where
trie_nodes.insert(next_path.clone(), Either::Right(leaf.value.clone()));
}
}
TrieNode::EmptyRoot => return Err(TrieWitnessError::UnexpectedEmptyRoot(next_path)),
};
}
@ -273,6 +284,9 @@ where
TrieNode::Extension(ext) => {
path.extend_from_slice(&ext.key);
}
TrieNode::EmptyRoot => {
return Err(TrieWitnessError::UnexpectedEmptyRoot(path))
}
}
}
}