Skip to content

Commit

Permalink
wip: interop debug tools
Browse files Browse the repository at this point in the history
  • Loading branch information
0xaatif committed Jun 11, 2024
1 parent 45c30af commit 1df6af4
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 73 deletions.
2 changes: 1 addition & 1 deletion trace_decoder/src/compact/compact_prestate_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ impl Display for NodeEntry {

/// A value of a node data.
#[derive(Clone, Debug)]
pub struct ValueNodeData(pub(super) Vec<u8>);
pub struct ValueNodeData(pub Vec<u8>);

impl From<Vec<u8>> for ValueNodeData {
fn from(v: Vec<u8>) -> Self {
Expand Down
57 changes: 5 additions & 52 deletions trace_decoder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,60 +176,13 @@ mod type1 {
.unwrap()
.into_iter()
.enumerate()
.skip(1)
{
println!("case {}", ix);
let ours = wire::parse(&case.bytes)
.unwrap()
.into_iter()
.map(instruction2instruction)
.collect::<Vec<_>>();
let theirs =
crate::compact::compact_prestate_processing::parse_just_to_instructions(case.bytes)
.unwrap();
pretty_assertions::assert_eq!(theirs, ours);
}
}

use u4::U4;
use wire::Instruction;

fn instruction2instruction(
ours: Instruction,
) -> crate::compact::compact_prestate_processing::Instruction {
use crate::compact::compact_prestate_processing::Instruction as Theirs;
match ours {
Instruction::Leaf { key, value } => {
Theirs::Leaf(nibbles2nibbles(key.into()), value.into())
if ix != 1 {
continue;
}
Instruction::Extension { key } => Theirs::Extension(nibbles2nibbles(key.into())),
Instruction::Branch { mask } => Theirs::Branch(mask.try_into().unwrap()),
Instruction::Hash { raw_hash } => Theirs::Hash(raw_hash.into()),
Instruction::Code { raw_code } => Theirs::Code(raw_code.into()),
Instruction::AccountLeaf {
key,
nonce,
balance,
has_code,
has_storage,
} => Theirs::AccountLeaf(
nibbles2nibbles(key.into()),
nonce.unwrap_or_default().into(),
balance.unwrap_or_default(),
has_code,
has_storage,
),
Instruction::EmptyRoot => Theirs::EmptyRoot,
Instruction::NewTrie => todo!(),
let instructions = wire::parse(&case.bytes).unwrap();
let executions = execution::execute(instructions).unwrap();
}
}

fn nibbles2nibbles(ours: Vec<U4>) -> mpt_trie_type_1::nibbles::Nibbles {
ours.into_iter().fold(
mpt_trie_type_1::nibbles::Nibbles::default(),
|mut acc, el| {
acc.push_nibble_front(el as u8);
acc
},
)
}
}
120 changes: 101 additions & 19 deletions trace_decoder/src/type1/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,48 @@ use nunny::NonEmpty;

use super::{u4::U4, wire::Instruction};

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Hash {
pub raw_hash: [u8; 32],
}

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Value {
pub raw_value: NonEmpty<Vec<u8>>,
}

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Account {
pub nonce: u64,
pub balance: U256,
pub storage: Option<Box<Node>>,
pub code: Option<Either<Hash, Code>>,
}

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Code {
pub code: NonEmpty<Vec<u8>>,
}

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Leaf {
pub key: NonEmpty<Vec<U4>>,
pub value: Either<Value, Account>,
}

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Extension {
pub key: NonEmpty<Vec<U4>>,
pub child: Box<Node>,
}

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Branch {
pub children: [Option<Box<Node>>; 16],
}

/// An interior execution node
#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Node {
Hash(Hash),
// BUG: these are documented, but never constructed during execution
Expand All @@ -63,7 +63,7 @@ pub enum Node {
}

/// A terminal node after [`execute`]-ing
#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Execution {
Leaf(Leaf),
Extension(Extension),
Expand All @@ -83,11 +83,6 @@ pub fn execute(
let mut stack = vec![];

while let Some(instruction) = instructions.pop_front() {
eprintln!("current {:?}", instruction);
eprintln!(
"lookahead {:?}",
instructions.iter().take(2).collect::<Vec<_>>()
);
match instruction {
Instruction::EmptyRoot => stack.push(Node::Empty),
Instruction::Hash { raw_hash } => stack.push(Node::Hash(Hash { raw_hash })),
Expand Down Expand Up @@ -170,7 +165,7 @@ pub fn execute(
Instruction::Branch { mask } => {
use bitvec::{order::Lsb0, view::BitView as _};
let mut children = array::from_fn(|_ix| None);
for (ix, it) in mask.view_bits::<Lsb0>().iter().by_vals().enumerate() {
for (ix, it) in mask.view_bits::<Lsb0>().iter().by_vals().enumerate().rev() {
if it {
*children.get_mut(ix).context("oob mask bit for Branch")? =
Some(Box::new(stack.pop().context("no Node for Branch")?));
Expand All @@ -180,10 +175,18 @@ pub fn execute(
}
Instruction::NewTrie => witnesses.push(finish_stack(&mut stack)?),
}

if let Some(it) = stack.last() {
eprintln!("left: {:?}", it)
}
println!(
"stack: {:?}",
stack.iter().cloned().map(node2node).collect::<Vec<_>>()
);
println!(
"instructions: {:?}",
instructions
.iter()
.cloned()
.map(instruction2instruction)
.collect::<Vec<_>>()
);
}
witnesses.push(finish_stack(&mut stack)?);

Expand Down Expand Up @@ -214,3 +217,82 @@ fn pop2<T>(v: &mut Vec<T>) -> (Option<T>, Option<T>) {
let left = v.pop();
(left, right)
}

fn instruction2instruction(
ours: Instruction,
) -> crate::compact::compact_prestate_processing::Instruction {
use crate::compact::compact_prestate_processing::Instruction as Theirs;
match ours {
Instruction::Leaf { key, value } => Theirs::Leaf(nibbles2nibbles(key.into()), value.into()),
Instruction::Extension { key } => Theirs::Extension(nibbles2nibbles(key.into())),
Instruction::Branch { mask } => Theirs::Branch(mask.try_into().unwrap()),
Instruction::Hash { raw_hash } => Theirs::Hash(raw_hash.into()),
Instruction::Code { raw_code } => Theirs::Code(raw_code.into()),
Instruction::AccountLeaf {
key,
nonce,
balance,
has_code,
has_storage,
} => Theirs::AccountLeaf(
nibbles2nibbles(key.into()),
nonce.unwrap_or_default().into(),
balance.unwrap_or_default(),
has_code,
has_storage,
),
Instruction::EmptyRoot => Theirs::EmptyRoot,
Instruction::NewTrie => todo!(),
}
}

fn nibbles2nibbles(ours: Vec<U4>) -> mpt_trie_type_1::nibbles::Nibbles {
ours.into_iter().fold(
mpt_trie_type_1::nibbles::Nibbles::default(),
|mut acc, el| {
acc.push_nibble_front(el as u8);
acc
},
)
}

fn node2node(ours: Node) -> crate::compact::compact_prestate_processing::NodeEntry {
use crate::compact::compact_prestate_processing::{
AccountNodeCode, AccountNodeData, LeafNodeData, NodeEntry as Theirs, ValueNodeData,
};
match ours {
Node::Hash(Hash { raw_hash }) => Theirs::Hash(raw_hash.into()),
Node::Leaf(Leaf { key, value }) => Theirs::Leaf(
nibbles2nibbles(key.into()),
match value {
Either::Left(Value { raw_value }) => {
LeafNodeData::Value(ValueNodeData(raw_value.into()))
}
Either::Right(Account {
nonce,
balance,
storage,
code,
}) => LeafNodeData::Account(AccountNodeData {
nonce: nonce.into(),
balance,
storage_trie: storage.map(|it| super::reshape::node2trie(*it).unwrap()),
account_node_code: code.map(|it| match it {
Either::Left(Hash { raw_hash }) => {
AccountNodeCode::HashNode(raw_hash.into())
}
Either::Right(Code { code }) => AccountNodeCode::CodeNode(code.into()),
}),
}),
},
),
Node::Extension(Extension { key, child }) => {
Theirs::Extension(nibbles2nibbles(key.into()), Box::new(node2node(*child)))
}
Node::Branch(Branch { children }) => {
Theirs::Branch(children.map(|it| it.map(|it| Box::new(node2node(*it)))))
}
Node::Code(Code { code }) => Theirs::Code(code.into()),
Node::Empty => Theirs::Empty,
}
}
2 changes: 1 addition & 1 deletion trace_decoder/src/type1/reshape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ impl Visitor {
}
}

fn node2trie(node: Node) -> anyhow::Result<HashedPartialTrie> {
pub fn node2trie(node: Node) -> anyhow::Result<HashedPartialTrie> {
let mut visitor = Node2TrieVisitor::default();
visitor.visit_node(node)?;
let Node2TrieVisitor { path, trie } = visitor;
Expand Down

0 comments on commit 1df6af4

Please sign in to comment.