Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate CaptureArbitrumStorageGet/Set into the prestate tracer #352

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
4 changes: 2 additions & 2 deletions core/tracing/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addr should always be the arbosStorage address. We can add it here but not really necessary.
We shouldn't need mapped key because that's what "key" should mean. Storage is just key-value pairs and we don't care about the non-mapped key.


CaptureStylusHostioHook = func(name string, args, outs []byte, startInk, endInk uint64)
)
Expand Down
22 changes: 14 additions & 8 deletions eth/tracers/native/gen_account_json.go

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

8 changes: 4 additions & 4 deletions eth/tracers/native/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
Expand Down
50 changes: 42 additions & 8 deletions eth/tracers/native/prestate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prestate is just about finding all the places in storage that chaged.
We're not trying to add new things there. It already supports writes that happen during EVM by mimicing an SLOAD/SSTORE.
We just want to add the accesses that happened before EVM execution to the same place.
So we shouldn't need new entries. It should all be normal entries in the arbosstorage account.

}

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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand All @@ -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
}
10 changes: 10 additions & 0 deletions eth/tracers/native/tracer_arbitrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 ""
Expand Down
Loading