Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.

Commit 98fba48

Browse files
authored
Merge branch 'develop' into pi-aggregation-circuit
2 parents e76e424 + 44000e5 commit 98fba48

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+2267
-893
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bus-mapping/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,5 @@ rand = "0.8"
4444
default = ["test"]
4545
test = ["mock", "rand"]
4646
scroll = ["eth-types/scroll"]
47+
# Enable shanghai feature of mock only if mock is enabled (by test).
48+
shanghai = ["eth-types/shanghai", "mock?/shanghai"]

bus-mapping/src/circuit_input_builder.rs

+127-12
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub use self::block::BlockHead;
1515
use crate::{
1616
error::Error,
1717
evm::opcodes::{gen_associated_ops, gen_begin_tx_ops, gen_end_tx_ops},
18-
operation::{CallContextField, Operation, RWCounter, StartOp, RW},
18+
operation::{self, CallContextField, Operation, RWCounter, StartOp, StorageOp, RW},
1919
rpc::GethClient,
2020
state_db::{self, CodeDB, StateDB},
2121
};
@@ -48,7 +48,7 @@ use std::{
4848
collections::{BTreeMap, HashMap},
4949
iter,
5050
};
51-
pub use transaction::{Transaction, TransactionContext};
51+
pub use transaction::{Transaction, TransactionContext, TxL1Fee, TX_L1_FEE_PRECISION};
5252

5353
/// Circuit Setup Parameters
5454
#[derive(Debug, Clone, Copy)]
@@ -243,23 +243,28 @@ impl<'a> CircuitInputBuilder {
243243
check_last_tx: bool,
244244
) -> Result<(), Error> {
245245
// accumulates gas across all txs in the block
246-
log::info!("handling block {:?}", eth_block.number);
246+
log::info!(
247+
"handling block {:?}, tx num {}",
248+
eth_block.number,
249+
eth_block.transactions.len()
250+
);
247251
for (tx_index, tx) in eth_block.transactions.iter().enumerate() {
252+
let batch_tx_idx = self.block.txs.len();
248253
if self.block.txs.len() >= self.block.circuits_params.max_txs {
249254
log::warn!(
250-
"skip tx outside MAX_TX limit {}, {}th(inner idx: {}) tx {:?}",
255+
"skip tx outside MAX_TX limit {}, {}th tx(inner idx: {}) {:?}",
251256
self.block.circuits_params.max_txs,
257+
batch_tx_idx,
252258
tx.transaction_index.unwrap_or_default(),
253-
self.block.txs.len(),
254259
tx.hash
255260
);
256261
continue;
257262
}
258263
let geth_trace = &geth_traces[tx_index];
259264
log::info!(
260-
"handling {}th(inner idx: {}) tx: {:?} rwc {:?}, to: {:?}, input_len {:?}",
265+
"handling {}th tx(inner idx: {}): {:?} rwc {:?}, to: {:?}, input_len {:?}",
266+
batch_tx_idx,
261267
tx.transaction_index.unwrap_or_default(),
262-
self.block.txs.len(),
263268
tx.hash,
264269
self.block_ctx.rwc,
265270
tx.to,
@@ -273,6 +278,12 @@ impl<'a> CircuitInputBuilder {
273278
geth_trace,
274279
check_last_tx && tx_index + 1 == eth_block.transactions.len(),
275280
)?;
281+
log::debug!(
282+
"after handle {}th tx: rwc {:?}, block total gas {:?}",
283+
batch_tx_idx,
284+
self.block_ctx.rwc,
285+
self.block_ctx.cumulative_gas_used
286+
);
276287
}
277288
if handle_rwc_reversion {
278289
self.set_value_ops_call_context_rwc_eor();
@@ -285,8 +296,81 @@ impl<'a> CircuitInputBuilder {
285296
Ok(())
286297
}
287298

299+
fn print_rw_usage(&self) {
300+
// opcode -> (count, mem_rw_len, stack_rw_len)
301+
let mut opcode_info_map = BTreeMap::new();
302+
for t in &self.block.txs {
303+
for step in t.steps() {
304+
if let ExecState::Op(op) = step.exec_state {
305+
opcode_info_map.entry(op).or_insert((0, 0, 0));
306+
let mut values = opcode_info_map[&op];
307+
values.0 += 1;
308+
values.1 += step
309+
.bus_mapping_instance
310+
.iter()
311+
.filter(|rw| rw.0 == operation::Target::Memory)
312+
.count();
313+
values.2 += step
314+
.bus_mapping_instance
315+
.iter()
316+
.filter(|rw| rw.0 == operation::Target::Stack)
317+
.count();
318+
opcode_info_map.insert(op, values);
319+
}
320+
}
321+
}
322+
for (op, (count, mem, stack)) in opcode_info_map
323+
.iter()
324+
.sorted_by_key(|(_, (_, m, _))| m)
325+
.rev()
326+
{
327+
log::debug!(
328+
"op {:?}, count {}, mem rw {}(avg {:.2}), stack rw {}(avg {:.2})",
329+
op,
330+
count,
331+
mem,
332+
*mem as f32 / *count as f32,
333+
stack,
334+
*stack as f32 / *count as f32
335+
);
336+
}
337+
log::debug!("memory num: {}", self.block.container.memory.len());
338+
log::debug!("stack num: {}", self.block.container.stack.len());
339+
log::debug!("storage num: {}", self.block.container.storage.len());
340+
log::debug!(
341+
"tx_access_list_account num: {}",
342+
self.block.container.tx_access_list_account.len()
343+
);
344+
log::debug!(
345+
"tx_access_list_account_storage num: {}",
346+
self.block.container.tx_access_list_account_storage.len()
347+
);
348+
log::debug!("tx_refund num: {}", self.block.container.tx_refund.len());
349+
log::debug!("account num: {}", self.block.container.account.len());
350+
log::debug!(
351+
"call_context num: {}",
352+
self.block.container.call_context.len()
353+
);
354+
log::debug!("tx_receipt num: {}", self.block.container.tx_receipt.len());
355+
log::debug!("tx_log num: {}", self.block.container.tx_log.len());
356+
log::debug!("start num: {}", self.block.container.start.len());
357+
}
358+
288359
/// ..
289360
pub fn set_end_block(&mut self) -> Result<(), Error> {
361+
use crate::l2_predeployed::message_queue::{
362+
ADDRESS as MESSAGE_QUEUE, WITHDRAW_TRIE_ROOT_SLOT,
363+
};
364+
365+
let withdraw_root = *self
366+
.sdb
367+
.get_storage(&MESSAGE_QUEUE, &WITHDRAW_TRIE_ROOT_SLOT)
368+
.1;
369+
let withdraw_root_before = *self
370+
.sdb
371+
.get_committed_storage(&MESSAGE_QUEUE, &WITHDRAW_TRIE_ROOT_SLOT)
372+
.1;
373+
290374
let max_rws = self.block.circuits_params.max_rws;
291375
let mut end_block_not_last = self.block.block_steps.end_block_not_last.clone();
292376
let mut end_block_last = self.block.block_steps.end_block_last.clone();
@@ -297,15 +381,30 @@ impl<'a> CircuitInputBuilder {
297381
let mut dummy_tx_ctx = TransactionContext::default();
298382
let mut state = self.state_ref(&mut dummy_tx, &mut dummy_tx_ctx);
299383

384+
let dummy_tx_id = state.block.txs.len();
300385
if let Some(call_id) = state.block.txs.last().map(|tx| tx.calls[0].call_id) {
301386
state.call_context_read(
302387
&mut end_block_last,
303388
call_id,
304389
CallContextField::TxId,
305-
Word::from(state.block.txs.len() as u64),
390+
Word::from(dummy_tx_id as u64),
306391
);
307392
}
308393

394+
// increase the total rwc by 1
395+
state.push_op(
396+
&mut end_block_last,
397+
RW::READ,
398+
StorageOp::new(
399+
*MESSAGE_QUEUE,
400+
*WITHDRAW_TRIE_ROOT_SLOT,
401+
withdraw_root,
402+
withdraw_root,
403+
dummy_tx_id,
404+
withdraw_root_before,
405+
),
406+
);
407+
309408
let mut push_op = |step: &mut ExecStep, rwc: RWCounter, rw: RW, op: StartOp| {
310409
let op_ref = state.block.container.insert(Operation::new(rwc, rw, op));
311410
step.bus_mapping_instance.push(op_ref);
@@ -333,6 +432,8 @@ impl<'a> CircuitInputBuilder {
333432
StartOp {},
334433
);
335434

435+
self.block.withdraw_root = withdraw_root;
436+
self.block.prev_withdraw_root = withdraw_root_before;
336437
self.block.block_steps.end_block_not_last = end_block_not_last;
337438
self.block.block_steps.end_block_last = end_block_last;
338439
Ok(())
@@ -350,6 +451,17 @@ impl<'a> CircuitInputBuilder {
350451
is_last_tx: bool,
351452
) -> Result<(), Error> {
352453
let mut tx = self.new_tx(eth_tx, !geth_trace.failed)?;
454+
455+
// Sanity check for transaction L1 fee.
456+
let tx_l1_fee = tx.l1_fee();
457+
if tx_l1_fee != geth_trace.l1_fee {
458+
log::error!(
459+
"Mismatch tx_l1_fee: calculated = {}, real = {}",
460+
tx_l1_fee,
461+
geth_trace.l1_fee
462+
);
463+
}
464+
353465
let mut tx_ctx = TransactionContext::new(eth_tx, geth_trace, is_last_tx)?;
354466
let mut debug_tx = tx.clone();
355467
debug_tx.input.clear();
@@ -370,19 +482,22 @@ impl<'a> CircuitInputBuilder {
370482
gen_begin_tx_ops(&mut self.state_ref(&mut tx, &mut tx_ctx), geth_trace)?;
371483

372484
for (index, geth_step) in geth_trace.struct_logs.iter().enumerate() {
485+
let tx_gas = tx.gas;
373486
let mut state_ref = self.state_ref(&mut tx, &mut tx_ctx);
374487
log::trace!(
375-
"handle {}th tx depth {} {}th opcode {:?} pc: {} gas_left: {} rwc: {} call_id: {} msize: {} args: {}",
488+
"handle {}th tx depth {} {}th/{} opcode {:?} pc: {} gas_left: {} gas_used: {} rwc: {} call_id: {} msize: {} args: {}",
376489
eth_tx.transaction_index.unwrap_or_default(),
377490
geth_step.depth,
378491
index,
492+
geth_trace.struct_logs.len(),
379493
geth_step.op,
380494
geth_step.pc.0,
381495
geth_step.gas.0,
496+
tx_gas - geth_step.gas.0,
382497
state_ref.block_ctx.rwc.0,
383498
state_ref.call().map(|c| c.call_id).unwrap_or(0),
384499
state_ref.call_ctx()?.memory.len(),
385-
if geth_step.op.is_push() {
500+
if geth_step.op.is_push_with_data() {
386501
format!("{:?}", geth_trace.struct_logs[index + 1].stack.last())
387502
} else if geth_step.op.is_call_without_value() {
388503
format!(
@@ -478,6 +593,7 @@ pub fn keccak_inputs(block: &Block, code_db: &CodeDB) -> Result<Vec<Vec<u8>>, Er
478593
keccak_inputs.push(keccak_inputs_pi_circuit(
479594
block.chain_id().as_u64(),
480595
block.prev_state_root,
596+
block.withdraw_root,
481597
&block.headers,
482598
block.txs(),
483599
block.circuits_params.max_txs,
@@ -564,13 +680,12 @@ pub fn get_dummy_tx_hash(chain_id: u64) -> H256 {
564680
fn keccak_inputs_pi_circuit(
565681
chain_id: u64,
566682
prev_state_root: Word,
683+
withdraw_trie_root: Word,
567684
block_headers: &BTreeMap<u64, BlockHead>,
568685
transactions: &[Transaction],
569686
max_txs: usize,
570687
) -> Vec<u8> {
571688
let dummy_tx_hash = get_dummy_tx_hash(chain_id);
572-
// TODO: use real-world withdraw trie root
573-
let withdraw_trie_root = Word::zero(); // zero for now
574689

575690
let result = iter::empty()
576691
// state roots

bus-mapping/src/circuit_input_builder/block.rs

+4
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ pub struct Block {
139139
pub headers: BTreeMap<u64, BlockHead>,
140140
/// State root of the previous block
141141
pub prev_state_root: Word,
142+
/// Withdraw root
143+
pub withdraw_root: Word,
144+
/// Withdraw roof of the previous block
145+
pub prev_withdraw_root: Word,
142146
/// Container of operations done in this block.
143147
pub container: OperationContainer,
144148
/// Transactions contained in the block

bus-mapping/src/circuit_input_builder/input_state_ref.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,10 @@ impl<'a> CircuitInputStateRef<'a> {
359359
if matches!(rw, RW::WRITE) {
360360
match op.field {
361361
AccountField::Nonce => account.nonce = op.value,
362-
AccountField::Balance => account.balance = op.value,
362+
AccountField::Balance => {
363+
log::trace!("update balance of {:?} to {:?}", &op.address, op.value);
364+
account.balance = op.value;
365+
}
363366
AccountField::KeccakCodeHash => {
364367
account.keccak_code_hash = H256::from(op.value.to_be_bytes())
365368
}

0 commit comments

Comments
 (0)