mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-12 15:03:45 +00:00
feat(trace): add per_tx_storage_trace (#372)
* 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>
This commit is contained in:
parent
38a6a1e964
commit
3cf5ba882d
3 changed files with 37 additions and 3 deletions
|
|
@ -17,6 +17,7 @@ type BlockTrace struct {
|
||||||
Header *Header `json:"header"`
|
Header *Header `json:"header"`
|
||||||
Transactions []*TransactionData `json:"transactions"`
|
Transactions []*TransactionData `json:"transactions"`
|
||||||
StorageTrace *StorageTrace `json:"storageTrace"`
|
StorageTrace *StorageTrace `json:"storageTrace"`
|
||||||
|
TxStorageTraces []*StorageTrace `json:"txStorageTraces,omitempty"`
|
||||||
ExecutionResults []*ExecutionResult `json:"executionResults"`
|
ExecutionResults []*ExecutionResult `json:"executionResults"`
|
||||||
MPTWitness *json.RawMessage `json:"mptwitness,omitempty"`
|
MPTWitness *json.RawMessage `json:"mptwitness,omitempty"`
|
||||||
WithdrawTrieRoot common.Hash `json:"withdraw_trie_root,omitempty"`
|
WithdrawTrieRoot common.Hash `json:"withdraw_trie_root,omitempty"`
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ type traceEnv struct {
|
||||||
// this lock is used to protect StorageTrace's read and write mutual exclusion.
|
// this lock is used to protect StorageTrace's read and write mutual exclusion.
|
||||||
sMu sync.Mutex
|
sMu sync.Mutex
|
||||||
*types.StorageTrace
|
*types.StorageTrace
|
||||||
|
txStorageTraces []*types.StorageTrace
|
||||||
// zktrie tracer is used for zktrie storage to build additional deletion proof
|
// zktrie tracer is used for zktrie storage to build additional deletion proof
|
||||||
zkTrieTracer map[string]state.ZktrieProofTracer
|
zkTrieTracer map[string]state.ZktrieProofTracer
|
||||||
executionResults []*types.ExecutionResult
|
executionResults []*types.ExecutionResult
|
||||||
|
|
@ -125,6 +126,7 @@ func (api *API) createTraceEnv(ctx context.Context, config *TraceConfig, block *
|
||||||
},
|
},
|
||||||
zkTrieTracer: make(map[string]state.ZktrieProofTracer),
|
zkTrieTracer: make(map[string]state.ZktrieProofTracer),
|
||||||
executionResults: make([]*types.ExecutionResult, block.Transactions().Len()),
|
executionResults: make([]*types.ExecutionResult, block.Transactions().Len()),
|
||||||
|
txStorageTraces: make([]*types.StorageTrace, block.Transactions().Len()),
|
||||||
}
|
}
|
||||||
|
|
||||||
key := coinbase.String()
|
key := coinbase.String()
|
||||||
|
|
@ -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
|
// If execution failed in between, abort
|
||||||
select {
|
select {
|
||||||
case err := <-errCh:
|
case err := <-errCh:
|
||||||
|
|
@ -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
|
// merge required proof data
|
||||||
proofAccounts := tracer.UpdatedAccounts()
|
proofAccounts := tracer.UpdatedAccounts()
|
||||||
proofAccounts[vmenv.FeeRecipient()] = struct{}{}
|
proofAccounts[vmenv.FeeRecipient()] = struct{}{}
|
||||||
|
|
@ -306,7 +326,10 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
|
||||||
addrStr := addr.String()
|
addrStr := addr.String()
|
||||||
|
|
||||||
env.pMu.Lock()
|
env.pMu.Lock()
|
||||||
_, existed := env.Proofs[addrStr]
|
checkedProof, existed := env.Proofs[addrStr]
|
||||||
|
if existed {
|
||||||
|
txStorageTrace.Proofs[addrStr] = checkedProof
|
||||||
|
}
|
||||||
env.pMu.Unlock()
|
env.pMu.Unlock()
|
||||||
if existed {
|
if existed {
|
||||||
continue
|
continue
|
||||||
|
|
@ -322,6 +345,7 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
|
||||||
}
|
}
|
||||||
env.pMu.Lock()
|
env.pMu.Lock()
|
||||||
env.Proofs[addrStr] = wrappedProof
|
env.Proofs[addrStr] = wrappedProof
|
||||||
|
txStorageTrace.Proofs[addrStr] = wrappedProof
|
||||||
env.pMu.Unlock()
|
env.pMu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,6 +357,10 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
|
||||||
rcfg.ScalarSlot: {},
|
rcfg.ScalarSlot: {},
|
||||||
})
|
})
|
||||||
for addr, keys := range proofStorages {
|
for addr, keys := range proofStorages {
|
||||||
|
if _, existed := txStorageTrace.StorageProofs[addr.String()]; !existed {
|
||||||
|
txStorageTrace.StorageProofs[addr.String()] = make(map[string][]hexutil.Bytes)
|
||||||
|
}
|
||||||
|
|
||||||
env.sMu.Lock()
|
env.sMu.Lock()
|
||||||
trie, err := state.GetStorageTrieForProof(addr)
|
trie, err := state.GetStorageTrieForProof(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -349,6 +377,7 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
|
||||||
keyStr := key.String()
|
keyStr := key.String()
|
||||||
isDelete := bytes.Equal(values.Bytes(), common.Hash{}.Bytes())
|
isDelete := bytes.Equal(values.Bytes(), common.Hash{}.Bytes())
|
||||||
|
|
||||||
|
txm := txStorageTrace.StorageProofs[addrStr]
|
||||||
env.sMu.Lock()
|
env.sMu.Lock()
|
||||||
m, existed := env.StorageProofs[addrStr]
|
m, existed := env.StorageProofs[addrStr]
|
||||||
if !existed {
|
if !existed {
|
||||||
|
|
@ -357,7 +386,8 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
|
||||||
if zktrieTracer.Available() {
|
if zktrieTracer.Available() {
|
||||||
env.zkTrieTracer[addrStr] = state.NewProofTracer(trie)
|
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
|
// still need to touch tracer for deletion
|
||||||
if isDelete && zktrieTracer.Available() {
|
if isDelete && zktrieTracer.Available() {
|
||||||
env.zkTrieTracer[addrStr].MarkDeletion(key)
|
env.zkTrieTracer[addrStr].MarkDeletion(key)
|
||||||
|
|
@ -383,6 +413,7 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
|
||||||
wrappedProof[i] = bt
|
wrappedProof[i] = bt
|
||||||
}
|
}
|
||||||
env.sMu.Lock()
|
env.sMu.Lock()
|
||||||
|
txm[keyStr] = wrappedProof
|
||||||
m[keyStr] = wrappedProof
|
m[keyStr] = wrappedProof
|
||||||
if zktrieTracer.Available() {
|
if zktrieTracer.Available() {
|
||||||
if isDelete {
|
if isDelete {
|
||||||
|
|
@ -405,6 +436,7 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc
|
||||||
ReturnValue: fmt.Sprintf("%x", returnVal),
|
ReturnValue: fmt.Sprintf("%x", returnVal),
|
||||||
StructLogs: vm.FormatLogs(tracer.StructLogs()),
|
StructLogs: vm.FormatLogs(tracer.StructLogs()),
|
||||||
}
|
}
|
||||||
|
env.txStorageTraces[index] = txStorageTrace
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -461,6 +493,7 @@ func (api *API) fillBlockTrace(env *traceEnv, block *types.Block) (*types.BlockT
|
||||||
Header: block.Header(),
|
Header: block.Header(),
|
||||||
StorageTrace: env.StorageTrace,
|
StorageTrace: env.StorageTrace,
|
||||||
ExecutionResults: env.executionResults,
|
ExecutionResults: env.executionResults,
|
||||||
|
TxStorageTraces: env.txStorageTraces,
|
||||||
Transactions: txs,
|
Transactions: txs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import (
|
||||||
const (
|
const (
|
||||||
VersionMajor = 4 // Major version component of the current release
|
VersionMajor = 4 // Major version component of the current release
|
||||||
VersionMinor = 2 // Minor 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
|
VersionMeta = "sepolia" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue