2022-09-18 09:45:31 -07:00
|
|
|
use eth_trie_utils::partial_trie::PartialTrie;
|
2022-10-04 15:12:44 -07:00
|
|
|
use ethereum_types::{BigEndianHash, H256, U256};
|
|
|
|
|
use rlp_derive::{RlpDecodable, RlpEncodable};
|
2022-09-18 09:45:31 -07:00
|
|
|
|
|
|
|
|
use crate::cpu::kernel::constants::trie_type::PartialTrieType;
|
2022-09-22 20:09:48 -07:00
|
|
|
use crate::generation::TrieInputs;
|
2022-09-18 09:45:31 -07:00
|
|
|
|
2022-10-04 15:12:44 -07:00
|
|
|
#[derive(RlpEncodable, RlpDecodable, Debug)]
|
|
|
|
|
pub(crate) struct AccountRlp {
|
|
|
|
|
pub(crate) nonce: U256,
|
|
|
|
|
pub(crate) balance: U256,
|
|
|
|
|
pub(crate) storage_root: H256,
|
|
|
|
|
pub(crate) code_hash: H256,
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-22 20:09:48 -07:00
|
|
|
pub(crate) fn all_mpt_prover_inputs_reversed(trie_inputs: &TrieInputs) -> Vec<U256> {
|
|
|
|
|
let mut inputs = all_mpt_prover_inputs(trie_inputs);
|
|
|
|
|
inputs.reverse();
|
|
|
|
|
inputs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Generate prover inputs for the initial MPT data, in the format expected by `mpt/load.asm`.
|
|
|
|
|
pub(crate) fn all_mpt_prover_inputs(trie_inputs: &TrieInputs) -> Vec<U256> {
|
2022-09-18 09:45:31 -07:00
|
|
|
let mut prover_inputs = vec![];
|
|
|
|
|
|
2022-09-22 20:09:48 -07:00
|
|
|
mpt_prover_inputs(&trie_inputs.state_trie, &mut prover_inputs, &|rlp| {
|
2022-10-04 15:12:44 -07:00
|
|
|
let account: AccountRlp = rlp::decode(rlp).expect("Decoding failed");
|
|
|
|
|
vec![
|
|
|
|
|
account.nonce,
|
|
|
|
|
account.balance,
|
|
|
|
|
account.storage_root.into_uint(),
|
|
|
|
|
account.code_hash.into_uint(),
|
|
|
|
|
]
|
2022-09-22 20:09:48 -07:00
|
|
|
});
|
2022-09-18 09:45:31 -07:00
|
|
|
|
2022-09-22 20:09:48 -07:00
|
|
|
mpt_prover_inputs(&trie_inputs.transactions_trie, &mut prover_inputs, &|rlp| {
|
|
|
|
|
rlp::decode_list(rlp)
|
|
|
|
|
});
|
2022-09-18 09:45:31 -07:00
|
|
|
|
2022-09-22 20:09:48 -07:00
|
|
|
mpt_prover_inputs(&trie_inputs.receipts_trie, &mut prover_inputs, &|_rlp| {
|
|
|
|
|
// TODO: Decode receipt RLP.
|
|
|
|
|
vec![]
|
|
|
|
|
});
|
2022-09-18 09:45:31 -07:00
|
|
|
|
2022-09-22 20:09:48 -07:00
|
|
|
prover_inputs.push(trie_inputs.storage_tries.len().into());
|
|
|
|
|
for (addr, storage_trie) in &trie_inputs.storage_tries {
|
|
|
|
|
prover_inputs.push(addr.0.as_ref().into());
|
2022-09-18 09:45:31 -07:00
|
|
|
mpt_prover_inputs(storage_trie, &mut prover_inputs, &|leaf_be| {
|
|
|
|
|
vec![U256::from_big_endian(leaf_be)]
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
prover_inputs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Given a trie, generate the prover input data for that trie. In essence, this serializes a trie
|
|
|
|
|
/// into a `U256` array, in a simple format which the kernel understands. For example, a leaf node
|
|
|
|
|
/// is serialized as `(TYPE_LEAF, key, value)`, where key is a `(nibbles, depth)` pair and `value`
|
|
|
|
|
/// is a variable-length structure which depends on which trie we're dealing with.
|
|
|
|
|
pub(crate) fn mpt_prover_inputs<F>(
|
|
|
|
|
trie: &PartialTrie,
|
|
|
|
|
prover_inputs: &mut Vec<U256>,
|
|
|
|
|
parse_leaf: &F,
|
|
|
|
|
) where
|
|
|
|
|
F: Fn(&[u8]) -> Vec<U256>,
|
|
|
|
|
{
|
|
|
|
|
prover_inputs.push((PartialTrieType::of(trie) as u32).into());
|
|
|
|
|
match trie {
|
|
|
|
|
PartialTrie::Empty => {}
|
2022-09-29 17:24:23 -06:00
|
|
|
PartialTrie::Hash(h) => prover_inputs.push(U256::from_big_endian(h.as_bytes())),
|
2022-09-18 09:45:31 -07:00
|
|
|
PartialTrie::Branch { children, value } => {
|
|
|
|
|
for child in children {
|
|
|
|
|
mpt_prover_inputs(child, prover_inputs, parse_leaf);
|
|
|
|
|
}
|
2022-09-22 20:09:48 -07:00
|
|
|
let leaf = parse_leaf(value);
|
|
|
|
|
prover_inputs.push(leaf.len().into());
|
|
|
|
|
prover_inputs.extend(leaf);
|
2022-09-18 09:45:31 -07:00
|
|
|
}
|
|
|
|
|
PartialTrie::Extension { nibbles, child } => {
|
|
|
|
|
prover_inputs.push(nibbles.count.into());
|
|
|
|
|
prover_inputs.push(nibbles.packed);
|
|
|
|
|
mpt_prover_inputs(child, prover_inputs, parse_leaf);
|
|
|
|
|
}
|
|
|
|
|
PartialTrie::Leaf { nibbles, value } => {
|
|
|
|
|
prover_inputs.push(nibbles.count.into());
|
|
|
|
|
prover_inputs.push(nibbles.packed);
|
2022-09-22 20:09:48 -07:00
|
|
|
let leaf = parse_leaf(value);
|
|
|
|
|
prover_inputs.push(leaf.len().into());
|
|
|
|
|
prover_inputs.extend(leaf);
|
2022-09-18 09:45:31 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|