diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 8235f08f85..f75526b057 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -148,8 +148,8 @@ type ( LogHook = func(log *types.Log) CaptureArbitrumTransferHook = func(from, to *common.Address, value *big.Int, before bool, purpose string) - CaptureArbitrumStorageGetHook = func(key common.Hash, depth int, before bool) - CaptureArbitrumStorageSetHook = func(key, value common.Hash, depth int, before bool) + CaptureArbitrumStorageGetHook = func(addr common.Address, key, mappedKey common.Hash, depth int, before bool) + CaptureArbitrumStorageSetHook = func(addr common.Address, key, mappedKey, value common.Hash, depth int, before bool) CaptureStylusHostioHook = func(name string, args, outs []byte, startInk, endInk uint64) ) diff --git a/eth/tracers/native/gen_account_json.go b/eth/tracers/native/gen_account_json.go index 4c39cbc38c..f4cd22850e 100644 --- a/eth/tracers/native/gen_account_json.go +++ b/eth/tracers/native/gen_account_json.go @@ -15,26 +15,29 @@ var _ = (*accountMarshaling)(nil) // MarshalJSON marshals as JSON. func (a account) MarshalJSON() ([]byte, error) { type account struct { - Balance *hexutil.Big `json:"balance,omitempty"` - Code hexutil.Bytes `json:"code,omitempty"` - Nonce uint64 `json:"nonce,omitempty"` - Storage map[common.Hash]common.Hash `json:"storage,omitempty"` + Balance *hexutil.Big `json:"balance,omitempty"` + Code hexutil.Bytes `json:"code,omitempty"` + Nonce uint64 `json:"nonce,omitempty"` + Storage map[common.Hash]common.Hash `json:"storage,omitempty"` + ArbitrumStorage map[common.Hash]common.Hash `json:"arbitrumStorage,omitempty"` } var enc account enc.Balance = (*hexutil.Big)(a.Balance) enc.Code = a.Code enc.Nonce = a.Nonce enc.Storage = a.Storage + enc.ArbitrumStorage = a.ArbitrumStorage return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. func (a *account) UnmarshalJSON(input []byte) error { type account struct { - Balance *hexutil.Big `json:"balance,omitempty"` - Code *hexutil.Bytes `json:"code,omitempty"` - Nonce *uint64 `json:"nonce,omitempty"` - Storage map[common.Hash]common.Hash `json:"storage,omitempty"` + Balance *hexutil.Big `json:"balance,omitempty"` + Code *hexutil.Bytes `json:"code,omitempty"` + Nonce *uint64 `json:"nonce,omitempty"` + Storage map[common.Hash]common.Hash `json:"storage,omitempty"` + ArbitrumStorage map[common.Hash]common.Hash `json:"arbitrumStorage,omitempty"` } var dec account if err := json.Unmarshal(input, &dec); err != nil { @@ -52,5 +55,8 @@ func (a *account) UnmarshalJSON(input []byte) error { if dec.Storage != nil { a.Storage = dec.Storage } + if dec.ArbitrumStorage != nil { + a.ArbitrumStorage = dec.ArbitrumStorage + } return nil } diff --git a/eth/tracers/native/mux.go b/eth/tracers/native/mux.go index 2a3a7dcdd0..c3563a201b 100644 --- a/eth/tracers/native/mux.go +++ b/eth/tracers/native/mux.go @@ -177,18 +177,18 @@ func (t *muxTracer) OnLog(log *types.Log) { } } -func (t *muxTracer) CaptureArbitrumStorageGet(key common.Hash, depth int, before bool) { +func (t *muxTracer) CaptureArbitrumStorageGet(addr common.Address, key, mappedKey common.Hash, depth int, before bool) { for _, t := range t.tracers { if t.CaptureArbitrumStorageGet != nil { - t.CaptureArbitrumStorageGet(key, depth, before) + t.CaptureArbitrumStorageGet(addr, key, mappedKey, depth, before) } } } -func (t *muxTracer) CaptureArbitrumStorageSet(key, value common.Hash, depth int, before bool) { +func (t *muxTracer) CaptureArbitrumStorageSet(addr common.Address, key, mappedKey, value common.Hash, depth int, before bool) { for _, t := range t.tracers { if t.CaptureArbitrumStorageSet != nil { - t.CaptureArbitrumStorageSet(key, value, depth, before) + t.CaptureArbitrumStorageSet(addr, key, mappedKey, value, depth, before) } } } diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index b353c06960..8c7a1199fb 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -47,10 +47,13 @@ type account struct { Nonce uint64 `json:"nonce,omitempty"` Storage map[common.Hash]common.Hash `json:"storage,omitempty"` empty bool + + ArbitrumStorage map[common.Hash]common.Hash `json:"arbitrumStorage,omitempty"` + arbStorageKeyMap map[common.Hash]common.Hash } func (a *account) exists() bool { - return a.Nonce > 0 || len(a.Code) > 0 || len(a.Storage) > 0 || (a.Balance != nil && a.Balance.Sign() != 0) + return a.Nonce > 0 || len(a.Code) > 0 || len(a.Storage) > 0 || (a.Balance != nil && a.Balance.Sign() != 0) || len(a.ArbitrumStorage) > 0 } type accountMarshaling struct { @@ -90,9 +93,11 @@ func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Trac } return &tracers.Tracer{ Hooks: &tracing.Hooks{ - OnTxStart: t.OnTxStart, - OnTxEnd: t.OnTxEnd, - OnOpcode: t.OnOpcode, + OnTxStart: t.OnTxStart, + OnTxEnd: t.OnTxEnd, + OnOpcode: t.OnOpcode, + CaptureArbitrumStorageGet: t.CaptureArbitrumStorageGet, + CaptureArbitrumStorageSet: t.CaptureArbitrumStorageSet, }, GetResult: t.GetResult, Stop: t.Stop, @@ -209,6 +214,7 @@ func (t *prestateTracer) processDiffState() { } modified := false postAccount := &account{Storage: make(map[common.Hash]common.Hash)} + postAccount.ArbitrumStorage = make(map[common.Hash]common.Hash) newBalance := t.env.StateDB.GetBalance(addr).ToBig() newNonce := t.env.StateDB.GetNonce(addr) newCode := t.env.StateDB.GetCode(addr) @@ -244,6 +250,24 @@ func (t *prestateTracer) processDiffState() { } } + for key, val := range state.ArbitrumStorage { + // don't include the empty slot + if val == (common.Hash{}) { + delete(t.pre[addr].ArbitrumStorage, key) + } + + newVal := t.env.StateDB.GetState(types.ArbosStateAddress, state.arbStorageKeyMap[key]) + if val == newVal { + // Omit unchanged slots + delete(t.pre[addr].ArbitrumStorage, key) + } else { + modified = true + if newVal != (common.Hash{}) { + postAccount.ArbitrumStorage[key] = newVal + } + } + } + if modified { t.post[addr] = postAccount } else { @@ -261,10 +285,12 @@ func (t *prestateTracer) lookupAccount(addr common.Address) { } acc := &account{ - Balance: t.env.StateDB.GetBalance(addr).ToBig(), - Nonce: t.env.StateDB.GetNonce(addr), - Code: t.env.StateDB.GetCode(addr), - Storage: make(map[common.Hash]common.Hash), + Balance: t.env.StateDB.GetBalance(addr).ToBig(), + Nonce: t.env.StateDB.GetNonce(addr), + Code: t.env.StateDB.GetCode(addr), + Storage: make(map[common.Hash]common.Hash), + ArbitrumStorage: make(map[common.Hash]common.Hash), + arbStorageKeyMap: make(map[common.Hash]common.Hash), } if !acc.exists() { acc.empty = true @@ -281,3 +307,11 @@ func (t *prestateTracer) lookupStorage(addr common.Address, key common.Hash) { } t.pre[addr].Storage[key] = t.env.StateDB.GetState(addr, key) } + +func (t *prestateTracer) lookupArbitrumStorage(addr common.Address, key, mappedKey common.Hash) { + if _, ok := t.pre[addr].ArbitrumStorage[key]; ok { + return + } + t.pre[addr].ArbitrumStorage[key] = t.env.StateDB.GetState(types.ArbosStateAddress, mappedKey) + t.pre[addr].arbStorageKeyMap[key] = mappedKey +} diff --git a/eth/tracers/native/tracer_arbitrum.go b/eth/tracers/native/tracer_arbitrum.go index 5134b5f099..6014cd37bc 100644 --- a/eth/tracers/native/tracer_arbitrum.go +++ b/eth/tracers/native/tracer_arbitrum.go @@ -74,6 +74,16 @@ func (t *flatCallTracer) CaptureArbitrumTransfer(from, to *common.Address, value } } +func (t *prestateTracer) CaptureArbitrumStorageGet(addr common.Address, key, mappedKey common.Hash, depth int, before bool) { + t.lookupAccount(addr) + t.lookupArbitrumStorage(addr, key, mappedKey) +} + +func (t *prestateTracer) CaptureArbitrumStorageSet(addr common.Address, key, mappedKey, value common.Hash, depth int, before bool) { + t.lookupAccount(addr) + t.lookupArbitrumStorage(addr, key, mappedKey) +} + func bigToHex(n *big.Int) string { if n == nil { return ""