Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions aggregator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ zkevm-circuits = { path = "../zkevm-circuits" }
ark-std = "0.3.0"
env_logger = "0.10.0"
ethers-core = "0.17.0"
hex = "0.4.3"
log = "0.4"
itertools = "0.10.3"
serde = { version = "1.0", features = ["derive"] }
Expand Down
32 changes: 29 additions & 3 deletions aggregator/src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,35 @@ impl ChunkHash {
pub fn from_witness_block(block: &Block<Fr>, is_padding: bool) -> Self {
// <https://github.com/scroll-tech/zkevm-circuits/blob/25dd32aa316ec842ffe79bb8efe9f05f86edc33e/bus-mapping/src/circuit_input_builder.rs#L690>

let mut total_l1_popped = block.start_l1_queue_index;
log::debug!("chunk-hash: start_l1_queue_index = {}", total_l1_popped);
let data_bytes = iter::empty()
// .chain(block_headers.iter().flat_map(|(&block_num, block)| {
.chain(block.context.ctxs.iter().flat_map(|(b_num, b_ctx)| {
let num_txs = block
let num_l2_txs = block
.txs
.iter()
.filter(|tx| tx.block_number == *b_num)
.count() as u16;
.filter(|tx| !tx.tx_type.is_l1_msg() && tx.block_number == *b_num)
.count() as u64;
let num_l1_msgs = block
.txs
.iter()
.filter(|tx| tx.tx_type.is_l1_msg() && tx.block_number == *b_num)
// tx.nonce alias for queue_index for l1 msg tx
.map(|tx| tx.nonce)
.max()
.map_or(0, |max_queue_index| max_queue_index - total_l1_popped + 1);
total_l1_popped += num_l1_msgs;

let num_txs = (num_l2_txs + num_l1_msgs) as u16;
log::debug!(
"chunk-hash: [block {}] total_l1_popped = {}, num_l1_msgs = {}, num_l2_txs = {}, num_txs = {}",
b_num,
total_l1_popped,
num_l1_msgs,
num_l2_txs,
num_txs,
);

iter::empty()
// Block Values
Expand All @@ -56,6 +78,10 @@ impl ChunkHash {
.collect::<Vec<u8>>();

let data_hash = H256(keccak256(data_bytes));
log::debug!(
"chunk-hash: data hash = {}",
hex::encode(data_hash.to_fixed_bytes())
);

let post_state_root = block
.context
Expand Down
37 changes: 33 additions & 4 deletions bus-mapping/src/circuit_input_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,7 @@ pub fn keccak_inputs(block: &Block, code_db: &CodeDB) -> Result<Vec<Vec<u8>>, Er
// PI circuit
keccak_inputs.extend(keccak_inputs_pi_circuit(
block.chain_id,
block.start_l1_queue_index,
block.prev_state_root,
block.withdraw_root,
&block.headers,
Expand Down Expand Up @@ -736,17 +737,41 @@ pub fn get_dummy_tx_hash() -> H256 {

fn keccak_inputs_pi_circuit(
chain_id: u64,
start_l1_queue_index: u64,
prev_state_root: Word,
withdraw_trie_root: Word,
block_headers: &BTreeMap<u64, BlockHead>,
transactions: &[Transaction],
) -> Vec<Vec<u8>> {
let mut total_l1_popped = start_l1_queue_index;
log::debug!(
"start_l1_queue_index in keccak_inputs: {}",
start_l1_queue_index
);
let data_bytes = iter::empty()
.chain(block_headers.iter().flat_map(|(block_num, block)| {
let num_txs = transactions
.chain(block_headers.iter().flat_map(|(&block_num, block)| {
let num_l2_txs = transactions
.iter()
.filter(|tx| tx.block_num == *block_num)
.count() as u16;
.filter(|tx| !tx.tx_type.is_l1_msg() && tx.block_num == block_num)
.count() as u64;
let num_l1_msgs = transactions
.iter()
.filter(|tx| tx.tx_type.is_l1_msg() && tx.block_num == block_num)
// tx.nonce alias for queue_index for l1 msg tx
.map(|tx| tx.nonce)
.max()
.map_or(0, |max_queue_index| max_queue_index - total_l1_popped + 1);
total_l1_popped += num_l1_msgs;

let num_txs = (num_l2_txs + num_l1_msgs) as u16;
log::debug!(
"[block {}] total_l1_popped: {}, num_l1_msgs: {}, num_l2_txs: {}, num_txs: {}",
block_num,
total_l1_popped,
num_l1_msgs,
num_l2_txs,
num_txs,
);

iter::empty()
// Block Values
Expand All @@ -760,6 +785,10 @@ fn keccak_inputs_pi_circuit(
.chain(transactions.iter().flat_map(|tx| tx.hash.to_fixed_bytes()))
.collect::<Vec<u8>>();
let data_hash = H256(keccak256(&data_bytes));
log::debug!(
"chunk data hash: {}",
hex::encode(data_hash.to_fixed_bytes())
);
let after_state_root = block_headers
.last_key_value()
.map(|(_, blk)| blk.eth_block.state_root)
Expand Down
82 changes: 82 additions & 0 deletions bus-mapping/src/circuit_input_builder/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ pub struct BlockHead {
pub difficulty: Word,
/// base fee
pub base_fee: Word,
/// start l1 queue index
pub start_l1_queue_index: u64,
/// Original block from geth
pub eth_block: eth_types::Block<eth_types::Transaction>,
}
Expand All @@ -108,6 +110,49 @@ impl BlockHead {
Ok(Self {
chain_id,
history_hashes,
start_l1_queue_index: 0,
coinbase: eth_block
.author
.ok_or(Error::EthTypeError(eth_types::Error::IncompleteBlock))?,
gas_limit: eth_block.gas_limit.low_u64(),
number: eth_block
.number
.ok_or(Error::EthTypeError(eth_types::Error::IncompleteBlock))?
.low_u64()
.into(),
timestamp: eth_block.timestamp,
difficulty: if eth_block.difficulty.is_zero() {
eth_block
.mix_hash
.unwrap_or_default()
.to_fixed_bytes()
.into()
} else {
eth_block.difficulty
},
base_fee: eth_block.base_fee_per_gas.unwrap_or_default(),
eth_block: eth_block.clone(),
})
}

/// Create a new block.
pub fn new_with_l1_queue_index(
chain_id: u64,
start_l1_queue_index: u64,
history_hashes: Vec<Word>,
eth_block: &eth_types::Block<eth_types::Transaction>,
) -> Result<Self, Error> {
if eth_block.base_fee_per_gas.is_none() {
// FIXME: resolve this once we have proper EIP-1559 support
log::debug!(
"This does not look like a EIP-1559 block - base_fee_per_gas defaults to zero"
);
}

Ok(Self {
chain_id,
history_hashes,
start_l1_queue_index,
coinbase: eth_block
.author
.ok_or(Error::EthTypeError(eth_types::Error::IncompleteBlock))?,
Expand Down Expand Up @@ -163,6 +208,8 @@ pub struct Block {
pub circuits_params: CircuitsParams,
/// chain id
pub chain_id: u64,
/// start_l1_queue_index
pub start_l1_queue_index: u64,
/// IO to/from the precompiled contract calls.
pub precompile_events: PrecompileEvents,
}
Expand Down Expand Up @@ -217,6 +264,41 @@ impl Block {
Ok(block)
}

/// Create a new block.
pub fn new_with_l1_queue_index(
chain_id: u64,
start_l1_queue_index: u64,
history_hashes: Vec<Word>,
eth_block: &eth_types::Block<eth_types::Transaction>,
circuits_params: CircuitsParams,
) -> Result<Self, Error> {
let mut block = Self {
block_steps: BlockSteps {
end_block_not_last: ExecStep {
exec_state: ExecState::EndBlock,
..ExecStep::default()
},
end_block_last: ExecStep {
exec_state: ExecState::EndBlock,
..ExecStep::default()
},
},
exp_events: Vec::new(),
chain_id,
start_l1_queue_index,
circuits_params,
..Default::default()
};
let info = BlockHead::new_with_l1_queue_index(
chain_id,
start_l1_queue_index,
history_hashes,
eth_block,
)?;
block.headers.insert(info.number.as_u64(), info);
Ok(block)
}

/// Return the list of transactions of this block.
pub fn txs(&self) -> &[Transaction] {
&self.txs
Expand Down
Loading