Skip to content
Merged
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
13 changes: 12 additions & 1 deletion core/token_gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ func GetAltTokenBalanceByEVM(evm *vm.EVM, tokenAddress, userAddress common.Addre
data := append(methodID, paddedAddress...)
// Create a message call context
sender := vm.AccountRef(userAddress)

if evm.Config.Tracer != nil && evm.Config.Tracer.OnSystemCallStartV2 != nil && evm.Config.Tracer.OnSystemCallEnd != nil {
evm.Config.Tracer.OnSystemCallStartV2(evm.GetVMContext())
defer evm.Config.Tracer.OnSystemCallEnd()
}

// Execute the call (using StaticCall since we're only reading state)
ret, _, err := evm.StaticCall(sender, tokenAddress, data, maxGas)
if err != nil {
Expand All @@ -111,7 +117,6 @@ func transferAltTokenByEVM(evm *vm.EVM, tokenAddress, from, to common.Address, a
if amount == nil || amount.Sign() <= 0 {
return fmt.Errorf("invalid transfer amount")
}

var fromBalanceBefore *big.Int
var err error
if userBalanceBefore != nil {
Expand All @@ -137,6 +142,12 @@ func transferAltTokenByEVM(evm *vm.EVM, tokenAddress, from, to common.Address, a
data := append(methodID, append(paddedAddress, paddedAmount...)...)
// Create a message call context
sender := vm.AccountRef(from)

if evm.Config.Tracer != nil && evm.Config.Tracer.OnSystemCallStartV2 != nil && evm.Config.Tracer.OnSystemCallEnd != nil {
evm.Config.Tracer.OnSystemCallStartV2(evm.GetVMContext())
defer evm.Config.Tracer.OnSystemCallEnd()
}

// Execute the call
ret, _, err := evm.Call(sender, tokenAddress, data, maxGas, big.NewInt(0))
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions eth/tracers/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ func (l *StructLogger) OnTxStart(env *tracing.VMContext, tx *types.Transaction,
l.statesAffected[*to] = struct{}{}
}
}

func (l *StructLogger) OnSystemCallStart(env *tracing.VMContext) {
l.skip = true
}
Expand Down
36 changes: 31 additions & 5 deletions eth/tracers/native/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ type callTracer struct {
depth int
interrupt atomic.Bool // Atomic flag to signal execution interruption
reason error // Textual reason for the interruption
skip bool
}

type callTracerConfig struct {
Expand All @@ -135,11 +136,13 @@ func newCallTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *param
}
return &tracers.Tracer{
Hooks: &tracing.Hooks{
OnTxStart: t.OnTxStart,
OnTxEnd: t.OnTxEnd,
OnEnter: t.OnEnter,
OnExit: t.OnExit,
OnLog: t.OnLog,
OnTxStart: t.OnTxStart,
OnTxEnd: t.OnTxEnd,
OnEnter: t.OnEnter,
OnExit: t.OnExit,
OnLog: t.OnLog,
OnSystemCallStartV2: t.OnSystemCall,
OnSystemCallEnd: t.OnSystemCallEnd,
},
GetResult: t.GetResult,
Stop: t.Stop,
Expand All @@ -158,6 +161,9 @@ func newCallTracerObject(ctx *tracers.Context, cfg json.RawMessage) (*callTracer

// OnEnter is called when EVM enters a new scope (via call, create or selfdestruct).
func (t *callTracer) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
if t.skip {
return
}
t.depth = depth
if t.config.OnlyTopCall && depth > 0 {
return
Expand Down Expand Up @@ -185,6 +191,9 @@ func (t *callTracer) OnEnter(depth int, typ byte, from common.Address, to common
// OnExit is called when EVM exits a scope, even if the scope didn't
// execute any code.
func (t *callTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) {
if t.skip {
return
}
if depth == 0 {
t.captureEnd(output, gasUsed, err, reverted)
return
Expand Down Expand Up @@ -218,10 +227,16 @@ func (t *callTracer) captureEnd(output []byte, gasUsed uint64, err error, revert
}

func (t *callTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) {
if t.skip {
return
}
t.gasLimit = tx.Gas()
}

func (t *callTracer) OnTxEnd(receipt *types.Receipt, err error) {
if t.skip {
return
}
// Error happened during tx validation.
if err != nil {
return
Expand All @@ -235,7 +250,18 @@ func (t *callTracer) OnTxEnd(receipt *types.Receipt, err error) {
}
}

func (t *callTracer) OnSystemCall(env *tracing.VMContext) {
t.skip = true
}

func (t *callTracer) OnSystemCallEnd() {
t.skip = false
}

func (t *callTracer) OnLog(log *types.Log) {
if t.skip {
return
}
// Only logs need to be captured via opcode processing
if !t.config.WithLog {
return
Expand Down
44 changes: 32 additions & 12 deletions rollup/tracing/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,20 @@ func NewMuxTracer(structLogger *logger.StructLogger, subTracers ...tracers.Trace
}
return &tracers.Tracer{
Hooks: &tracing.Hooks{
OnTxStart: t.OnTxStart,
OnTxEnd: t.OnTxEnd,
OnEnter: t.OnEnter,
OnExit: t.OnExit,
OnOpcode: t.OnOpcode,
OnFault: t.OnFault,
OnGasChange: t.OnGasChange,
OnBalanceChange: t.OnBalanceChange,
OnNonceChange: t.OnNonceChange,
OnCodeChange: t.OnCodeChange,
OnStorageChange: t.OnStorageChange,
OnLog: t.OnLog,
OnTxStart: t.OnTxStart,
OnTxEnd: t.OnTxEnd,
OnEnter: t.OnEnter,
OnExit: t.OnExit,
OnOpcode: t.OnOpcode,
OnFault: t.OnFault,
OnGasChange: t.OnGasChange,
OnBalanceChange: t.OnBalanceChange,
OnNonceChange: t.OnNonceChange,
OnCodeChange: t.OnCodeChange,
OnStorageChange: t.OnStorageChange,
OnLog: t.OnLog,
OnSystemCallStartV2: t.OnSystemCallStart,
OnSystemCallEnd: t.OnSystemCallEnd,
},
Stop: t.Stop,
}
Expand Down Expand Up @@ -141,6 +143,24 @@ func (t *muxTracer) OnLog(log *types.Log) {
}
}

func (t *muxTracer) OnSystemCallStart(env *tracing.VMContext) {
for _, t := range t.subTracers {
if t.OnSystemCallStartV2 != nil {
t.OnSystemCallStartV2(env)
}
}
t.structLogger.OnSystemCallStart(env)
}

func (t *muxTracer) OnSystemCallEnd() {
for _, t := range t.subTracers {
if t.OnSystemCallEnd != nil {
t.OnSystemCallEnd()
}
}
t.structLogger.OnSystemCallEnd()
}

// Stop terminates execution of the tracer at the first opportune moment.
func (t *muxTracer) Stop(err error) {
for _, t := range t.subTracers {
Expand Down
28 changes: 28 additions & 0 deletions rollup/tracing/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,34 @@ func (env *TraceEnv) getTxResult(statedb *state.StateDB, index int, block *types
env.Codes[codeHash] = codeInfo
}
}

// For AltFeeTx, manually collect token contract bytecode
// since direct storage slot operations don't trigger EVM execution
if tx.Type() == types.AltFeeTxType && tx.FeeTokenID() != 0 {
tokenInfo, err := fees.GetTokenInfo(statedb, tx.FeeTokenID())
if err == nil && tokenInfo.TokenAddress != (common.Address{}) {

collectBytecode := func(addr common.Address) {
code := statedb.GetCode(addr)
keccakCodeHash := statedb.GetKeccakCodeHash(addr)
poseidonCodeHash := statedb.GetPoseidonCodeHash(addr)
codeSize := statedb.GetCodeSize(addr)

if poseidonCodeHash != (common.Hash{}) {
if _, exists := env.Codes[poseidonCodeHash]; !exists {
env.Codes[poseidonCodeHash] = logger.CodeInfo{
CodeSize: codeSize,
KeccakCodeHash: keccakCodeHash,
PoseidonCodeHash: poseidonCodeHash,
Code: code,
}
}
}
}
collectBytecode(tokenInfo.TokenAddress)
collectBytecode(rcfg.L2TokenRegistryAddress)
}
}
env.cMu.Unlock()

// merge required proof data
Expand Down
Loading