Skip to content

Commit d622d66

Browse files
feat: stack reconstruct (#993)
* init reconstruct * add StackPopOnlyOpcode * impl arthmetic opcode stack output * impl get block header field opcode * impl blockhash * impl PC, MSIZE, GAS * remove StackOnlyOpcode * add strict check * impl PUSHn * impl Address * cleanup stack usage * impl ORIGIN * use prestate * rename to enable-stack * cleanup stack usage * disable trace_tests * fix and add assert * fix doc test * fix cfg * use callTracer * do not parse call when is_precheck not ok * do not parse call in create precheck not ok * fix offset * fix compile * disable tracer_tests * fix test * fix caller_address * fix parse_call * silent more fields * unbound recursion * remove stack usage * update LoggerConfig * cleanup * fix root * fix test * fix doc test * cleanup * upgrade geth version * add feature switch * add missing * add call tracer and prestate tracer * handle precheck failed call * why ignore not working * add l2 prestate * use go1.20 * 0x5c/5e assigned by cankun * update l2geth * fix merge * clippy * fix call trace * fix call trace * fix merge * recover test * fix stack_pointer * fix update_codedb * handle last step error * fix order * fix order * skip empty * fix oog step * fix stack_pointer * fix create empty * fix ErrorCreationCode * try fix call empty * try fix call empty * fix precompile fail * fix precompile fail * fix create in tx * fix output * fix test * fix call to self in create * clippy * downgrade submodule * clippy --------- Co-authored-by: DreamWuGit <[email protected]>
1 parent e90ea7e commit d622d66

Some content is hidden

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

70 files changed

+1223
-925
lines changed

bus-mapping/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ rand.workspace = true
4040
rayon.workspace = true
4141

4242
[features]
43-
default = ["test", "enable-stack", "enable-storage"]
43+
default = ["test", "enable-storage"]
4444
test = ["mock", "rand"]
4545
scroll = ["eth-types/scroll", "mock?/scroll"]
4646
# Enable shanghai feature of mock only if mock is enabled (by test).

bus-mapping/src/circuit_input_builder.rs

+66-55
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ pub use call::{Call, CallContext, CallKind};
2727
use core::fmt::Debug;
2828
use eth_types::{
2929
self,
30-
evm_types::{GasCost, OpcodeId},
30+
evm_types::GasCost,
3131
geth_types,
3232
sign_types::{pk_bytes_le, pk_bytes_swap_endianness, SignData},
33-
Address, GethExecStep, GethExecTrace, ToBigEndian, ToWord, Word, H256,
33+
Address, GethExecTrace, ToBigEndian, ToWord, Word, H256,
3434
};
3535
use ethers_providers::JsonRpcClient;
3636
pub use execution::{
@@ -55,6 +55,9 @@ pub use transaction::{
5555
Transaction, TransactionContext, TxL1Fee, TX_L1_COMMIT_EXTRA_COST, TX_L1_FEE_PRECISION,
5656
};
5757

58+
#[cfg(feature = "enable-stack")]
59+
use eth_types::evm_types::OpcodeId;
60+
5861
/// Setup parameters for ECC-related precompile calls.
5962
#[derive(Debug, Clone, Copy)]
6063
pub struct PrecompileEcParams {
@@ -616,53 +619,58 @@ impl<'a> CircuitInputBuilder {
616619
state_ref.call().map(|c| c.call_id).unwrap_or(0),
617620
state_ref.call_ctx()?.memory.len(),
618621
geth_step.refund.0,
619-
if geth_step.op.is_push_with_data() {
620-
format!("{:?}", geth_trace.struct_logs.get(index + 1).map(|step| step.stack.last()))
621-
} else if geth_step.op.is_call_without_value() {
622-
format!(
623-
"{:?} {:40x} {:?} {:?} {:?} {:?}",
624-
geth_step.stack.last(),
625-
geth_step.stack.nth_last(1).unwrap_or_default(),
626-
geth_step.stack.nth_last(2),
627-
geth_step.stack.nth_last(3),
628-
geth_step.stack.nth_last(4),
629-
geth_step.stack.nth_last(5)
630-
)
631-
} else if geth_step.op.is_call_with_value() {
632-
format!(
633-
"{:?} {:40x} {:?} {:?} {:?} {:?} {:?}",
634-
geth_step.stack.last(),
635-
geth_step.stack.nth_last(1).unwrap_or_default(),
636-
geth_step.stack.nth_last(2),
637-
geth_step.stack.nth_last(3),
638-
geth_step.stack.nth_last(4),
639-
geth_step.stack.nth_last(5),
640-
geth_step.stack.nth_last(6),
641-
)
642-
} else if geth_step.op.is_create() {
643-
format!(
644-
"value {:?} offset {:?} size {:?} {}",
645-
geth_step.stack.last(),
646-
geth_step.stack.nth_last(1),
647-
geth_step.stack.nth_last(2),
648-
if geth_step.op == OpcodeId::CREATE2 {
649-
format!("salt {:?}", geth_step.stack.nth_last(3))
650-
} else {
651-
"".to_string()
652-
}
653-
)
654-
} else if matches!(geth_step.op, OpcodeId::SSTORE) {
655-
format!(
656-
"{:?} {:?} {:?}",
657-
state_ref.call().map(|c| c.address),
658-
geth_step.stack.last(),
659-
geth_step.stack.nth_last(1),
660-
)
661-
} else {
662-
let stack_input_num = 1024 - geth_step.op.valid_stack_ptr_range().1 as usize;
663-
(0..stack_input_num).map(|i|
664-
format!("{:?}", geth_step.stack.nth_last(i))
665-
).collect_vec().join(" ")
622+
{
623+
#[cfg(feature = "enable-stack")]
624+
if geth_step.op.is_push_with_data() {
625+
format!("{:?}", geth_trace.struct_logs.get(index + 1).map(|step| step.stack.last()))
626+
} else if geth_step.op.is_call_without_value() {
627+
format!(
628+
"{:?} {:40x} {:?} {:?} {:?} {:?}",
629+
geth_step.stack.last(),
630+
geth_step.stack.nth_last(1).unwrap_or_default(),
631+
geth_step.stack.nth_last(2),
632+
geth_step.stack.nth_last(3),
633+
geth_step.stack.nth_last(4),
634+
geth_step.stack.nth_last(5)
635+
)
636+
} else if geth_step.op.is_call_with_value() {
637+
format!(
638+
"{:?} {:40x} {:?} {:?} {:?} {:?} {:?}",
639+
geth_step.stack.last(),
640+
geth_step.stack.nth_last(1).unwrap_or_default(),
641+
geth_step.stack.nth_last(2),
642+
geth_step.stack.nth_last(3),
643+
geth_step.stack.nth_last(4),
644+
geth_step.stack.nth_last(5),
645+
geth_step.stack.nth_last(6),
646+
)
647+
} else if geth_step.op.is_create() {
648+
format!(
649+
"value {:?} offset {:?} size {:?} {}",
650+
geth_step.stack.last(),
651+
geth_step.stack.nth_last(1),
652+
geth_step.stack.nth_last(2),
653+
if geth_step.op == OpcodeId::CREATE2 {
654+
format!("salt {:?}", geth_step.stack.nth_last(3))
655+
} else {
656+
"".to_string()
657+
}
658+
)
659+
} else if matches!(geth_step.op, OpcodeId::SSTORE) {
660+
format!(
661+
"{:?} {:?} {:?}",
662+
state_ref.call().map(|c| c.address),
663+
geth_step.stack.last(),
664+
geth_step.stack.nth_last(1),
665+
)
666+
} else {
667+
let stack_input_num = 1024 - geth_step.op.valid_stack_ptr_range().1 as usize;
668+
(0..stack_input_num).map(|i|
669+
format!("{:?}", geth_step.stack.nth_last(i))
670+
).collect_vec().join(" ")
671+
}
672+
#[cfg(not(feature = "enable-stack"))]
673+
"N/A".to_string()
666674
}
667675
);
668676
debug_assert_eq!(
@@ -910,9 +918,9 @@ pub fn keccak_inputs_tx_circuit(txs: &[geth_types::Transaction]) -> Result<Vec<V
910918
}
911919

912920
/// Retrieve the init_code from memory for {CREATE, CREATE2}
913-
pub fn get_create_init_code(call_ctx: &CallContext, step: &GethExecStep) -> Result<Vec<u8>, Error> {
914-
let offset = step.stack.nth_last(1)?.low_u64() as usize;
915-
let length = step.stack.nth_last(2)?.as_usize();
921+
pub fn get_create_init_code(call_ctx: &CallContext) -> Result<Vec<u8>, Error> {
922+
let offset = call_ctx.stack.nth_last(1)?.low_u64() as usize;
923+
let length = call_ctx.stack.nth_last(2)?.as_usize();
916924

917925
let mem_len = call_ctx.memory.0.len();
918926
let mut result = vec![0u8; length];
@@ -925,9 +933,12 @@ pub fn get_create_init_code(call_ctx: &CallContext, step: &GethExecStep) -> Resu
925933
}
926934

927935
/// Retrieve the memory offset and length of call.
928-
pub fn get_call_memory_offset_length(step: &GethExecStep, nth: usize) -> Result<(u64, u64), Error> {
929-
let offset = step.stack.nth_last(nth)?;
930-
let length = step.stack.nth_last(nth + 1)?;
936+
pub fn get_call_memory_offset_length(
937+
call_ctx: &CallContext,
938+
nth: usize,
939+
) -> Result<(u64, u64), Error> {
940+
let offset = call_ctx.stack.nth_last(nth)?;
941+
let length = call_ctx.stack.nth_last(nth + 1)?;
931942
if length.is_zero() {
932943
Ok((0, 0))
933944
} else {

bus-mapping/src/circuit_input_builder/call.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::CodeSource;
22
use crate::{exec_trace::OperationRef, Error};
33
use eth_types::{
4-
evm_types::{Memory, OpcodeId},
4+
evm_types::{Memory, OpcodeId, Stack},
55
Address, Hash, Word,
66
};
77

@@ -130,7 +130,7 @@ impl Call {
130130
}
131131

132132
/// Context of a [`Call`].
133-
#[derive(Debug, Default)]
133+
#[derive(Debug, Clone, Default)]
134134
pub struct CallContext {
135135
/// Index of call
136136
pub index: usize,
@@ -143,6 +143,8 @@ pub struct CallContext {
143143
pub call_data: Vec<u8>,
144144
/// memory context of current call
145145
pub memory: Memory,
146+
/// stack context of current call
147+
pub stack: Stack,
146148
/// return data buffer
147149
pub return_data: Vec<u8>,
148150
}

bus-mapping/src/circuit_input_builder/execution.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl ExecStep {
8181
ExecStep {
8282
exec_state: ExecState::Op(step.op),
8383
pc: step.pc,
84-
stack_size: step.stack.0.len(),
84+
stack_size: call_ctx.stack.0.len(),
8585
memory_size: call_ctx.memory.len(),
8686
gas_left: step.gas,
8787
gas_cost: step.gas_cost,

0 commit comments

Comments
 (0)