Skip to content

Commit

Permalink
feat(trace): add per_tx_storage_trace (#372)
Browse files Browse the repository at this point in the history
* add proof for predeployed storages

* reverse inneeded code

* update for mainbranch merging

* add pertx storage trace

* dummy tx proof

* add txstorage trace

* add coinbase storage as trace

* Update version.go

* address comments

---------

Co-authored-by: Ho Vei <noelwei@gmail.com>
  • Loading branch information
HAOYUatHZ and noel2004 committed Jul 4, 2023
1 parent 38a6a1e commit 3cf5ba8
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
1 change: 1 addition & 0 deletions core/types/l2trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type BlockTrace struct {
Header *Header `json:"header"`
Transactions []*TransactionData `json:"transactions"`
StorageTrace *StorageTrace `json:"storageTrace"`
TxStorageTraces []*StorageTrace `json:"txStorageTraces,omitempty"`
ExecutionResults []*ExecutionResult `json:"executionResults"`
MPTWitness *json.RawMessage `json:"mptwitness,omitempty"`
WithdrawTrieRoot common.Hash `json:"withdraw_trie_root,omitempty"`
Expand Down
37 changes: 35 additions & 2 deletions eth/tracers/api_blocktrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type traceEnv struct {
// this lock is used to protect StorageTrace's read and write mutual exclusion.
sMu sync.Mutex
*types.StorageTrace
txStorageTraces []*types.StorageTrace
// zktrie tracer is used for zktrie storage to build additional deletion proof
zkTrieTracer map[string]state.ZktrieProofTracer
executionResults []*types.ExecutionResult
Expand Down Expand Up @@ -125,6 +126,7 @@ func (api *API) createTraceEnv(ctx context.Context, config *TraceConfig, block *
},
zkTrieTracer: make(map[string]state.ZktrieProofTracer),
executionResults: make([]*types.ExecutionResult, block.Transactions().Len()),
txStorageTraces: make([]*types.StorageTrace, block.Transactions().Len()),
}

key := coinbase.String()
Expand Down Expand Up @@ -211,6 +213,13 @@ func (api *API) getBlockTrace(block *types.Block, env *traceEnv) (*types.BlockTr
}
}

// build dummy per-tx deletion proof
for _, txStorageTrace := range env.txStorageTraces {
if txStorageTrace != nil {
txStorageTrace.DeletionProofs = env.DeletionProofs
}
}

// If execution failed in between, abort
select {
case err := <-errCh:
Expand Down Expand Up @@ -298,6 +307,17 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
})
}

txStorageTrace := &types.StorageTrace{
Proofs: make(map[string][]hexutil.Bytes),
StorageProofs: make(map[string]map[string][]hexutil.Bytes),
}
// still we have no state root for per tx, only set the head and tail
if index == 0 {
txStorageTrace.RootBefore = state.GetRootHash()
} else if index == len(block.Transactions())-1 {
txStorageTrace.RootAfter = block.Root()
}

// merge required proof data
proofAccounts := tracer.UpdatedAccounts()
proofAccounts[vmenv.FeeRecipient()] = struct{}{}
Expand All @@ -306,7 +326,10 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
addrStr := addr.String()

env.pMu.Lock()
_, existed := env.Proofs[addrStr]
checkedProof, existed := env.Proofs[addrStr]
if existed {
txStorageTrace.Proofs[addrStr] = checkedProof
}
env.pMu.Unlock()
if existed {
continue
Expand All @@ -322,6 +345,7 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
}
env.pMu.Lock()
env.Proofs[addrStr] = wrappedProof
txStorageTrace.Proofs[addrStr] = wrappedProof
env.pMu.Unlock()
}

Expand All @@ -333,6 +357,10 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
rcfg.ScalarSlot: {},
})
for addr, keys := range proofStorages {
if _, existed := txStorageTrace.StorageProofs[addr.String()]; !existed {
txStorageTrace.StorageProofs[addr.String()] = make(map[string][]hexutil.Bytes)
}

env.sMu.Lock()
trie, err := state.GetStorageTrieForProof(addr)
if err != nil {
Expand All @@ -349,6 +377,7 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
keyStr := key.String()
isDelete := bytes.Equal(values.Bytes(), common.Hash{}.Bytes())

txm := txStorageTrace.StorageProofs[addrStr]
env.sMu.Lock()
m, existed := env.StorageProofs[addrStr]
if !existed {
Expand All @@ -357,7 +386,8 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
if zktrieTracer.Available() {
env.zkTrieTracer[addrStr] = state.NewProofTracer(trie)
}
} else if _, existed := m[keyStr]; existed {
} else if proof, existed := m[keyStr]; existed {
txm[keyStr] = proof
// still need to touch tracer for deletion
if isDelete && zktrieTracer.Available() {
env.zkTrieTracer[addrStr].MarkDeletion(key)
Expand All @@ -383,6 +413,7 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
wrappedProof[i] = bt
}
env.sMu.Lock()
txm[keyStr] = wrappedProof
m[keyStr] = wrappedProof
if zktrieTracer.Available() {
if isDelete {
Expand All @@ -405,6 +436,7 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
ReturnValue: fmt.Sprintf("%x", returnVal),
StructLogs: vm.FormatLogs(tracer.StructLogs()),
}
env.txStorageTraces[index] = txStorageTrace

return nil
}
Expand Down Expand Up @@ -461,6 +493,7 @@ func (api *API) fillBlockTrace(env *traceEnv, block *types.Block) (*types.BlockT
Header: block.Header(),
StorageTrace: env.StorageTrace,
ExecutionResults: env.executionResults,
TxStorageTraces: env.txStorageTraces,
Transactions: txs,
}

Expand Down
2 changes: 1 addition & 1 deletion params/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
const (
VersionMajor = 4 // Major version component of the current release
VersionMinor = 2 // Minor version component of the current release
VersionPatch = 5 // Patch version component of the current release
VersionPatch = 6 // Patch version component of the current release
VersionMeta = "sepolia" // Version metadata to append to the version string
)

Expand Down

0 comments on commit 3cf5ba8

Please sign in to comment.