mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
optionally enable block witness recording/dumping via 'debug_setWitnessRecording'. only collect witnesses in statedb if explicitly enabled
This commit is contained in:
parent
64e53367d8
commit
2d0ee010f2
5 changed files with 69 additions and 16 deletions
|
|
@ -258,6 +258,8 @@ type BlockChain struct {
|
||||||
processor Processor // Block transaction processor interface
|
processor Processor // Block transaction processor interface
|
||||||
forker *ForkChoice
|
forker *ForkChoice
|
||||||
vmConfig vm.Config
|
vmConfig vm.Config
|
||||||
|
|
||||||
|
witnessRecordingPath atomic.Pointer[string]
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBlockChain returns a fully initialised block chain using information
|
// NewBlockChain returns a fully initialised block chain using information
|
||||||
|
|
@ -1779,7 +1781,15 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
|
parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
|
||||||
}
|
}
|
||||||
statedb, err := state.New(parent.Root, bc.stateCache, bc.snaps)
|
|
||||||
|
var statedb *state.StateDB
|
||||||
|
var err error
|
||||||
|
recordBlockwitness := bc.witnessRecordingPath.Load() != nil
|
||||||
|
if recordBlockwitness {
|
||||||
|
statedb, err = state.NewWithWitnessRecording(parent.Root, bc.stateCache, bc.snaps)
|
||||||
|
} else {
|
||||||
|
statedb, err = state.New(parent.Root, bc.stateCache, bc.snaps)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return it.index, err
|
return it.index, err
|
||||||
}
|
}
|
||||||
|
|
@ -1852,8 +1862,16 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
||||||
} else {
|
} else {
|
||||||
status, err = bc.writeBlockAndSetHead(block, receipts, logs, statedb, false)
|
status, err = bc.writeBlockAndSetHead(block, receipts, logs, statedb, false)
|
||||||
}
|
}
|
||||||
statedb.GetWitness().SetBlock(block)
|
|
||||||
log.Info(fmt.Sprintf("block %d summary:\n%s", block.NumberU64(), statedb.GetWitness().Summary()))
|
if witnessRecordingPath := bc.witnessRecordingPath.Load(); witnessRecordingPath != nil {
|
||||||
|
witness := statedb.GetWitness()
|
||||||
|
witness.SetBlock(block)
|
||||||
|
if err := state.DumpBlockWitnessToFile(witness, *witnessRecordingPath); err != nil {
|
||||||
|
log.Error("could not dump block witness to file", "err", err)
|
||||||
|
} else {
|
||||||
|
log.Info(fmt.Sprintf("block %d summary:\n%s", block.NumberU64(), statedb.GetWitness().Summary()))
|
||||||
|
}
|
||||||
|
}
|
||||||
//state.DumpBlockWithWitnessToFile(statedb.GetWitness(), block)
|
//state.DumpBlockWithWitnessToFile(statedb.GetWitness(), block)
|
||||||
|
|
||||||
followupInterrupt.Store(true)
|
followupInterrupt.Store(true)
|
||||||
|
|
@ -2594,3 +2612,11 @@ func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) {
|
||||||
func (bc *BlockChain) GetTrieFlushInterval() time.Duration {
|
func (bc *BlockChain) GetTrieFlushInterval() time.Duration {
|
||||||
return time.Duration(bc.flushInterval.Load())
|
return time.Duration(bc.flushInterval.Load())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bc *BlockChain) SetWitnessRecording(path string, enabled bool) {
|
||||||
|
if enabled {
|
||||||
|
bc.witnessRecordingPath.Store(&path)
|
||||||
|
} else {
|
||||||
|
bc.witnessRecordingPath.Store(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Witness struct {
|
type Witness struct {
|
||||||
|
|
@ -260,16 +261,15 @@ func NewWitness() *Witness {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DumpBlockWithWitnessToFile(w *Witness, b *types.Block) {
|
func DumpBlockWitnessToFile(w *Witness, path string) error {
|
||||||
enc := w.EncodeRLP()
|
enc := w.EncodeRLP()
|
||||||
path, _ := os.Getwd() //"/datadrive/"
|
|
||||||
err := os.MkdirAll(fmt.Sprintf("%s/block-dump", path), 0755)
|
blockHash := w.block.Hash()
|
||||||
|
outputFName := fmt.Sprintf("%d-%x.rlp", w.block.NumberU64(), blockHash[0:8])
|
||||||
|
path = filepath.Join(path, outputFName)
|
||||||
|
err := os.WriteFile(path, enc, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("shite2")
|
return err
|
||||||
}
|
|
||||||
outputFName := fmt.Sprintf("%d-%x.rlp", b.NumberU64(), b.Hash())
|
|
||||||
err = os.WriteFile(path+"/block-dump/"+outputFName, enc, 0644)
|
|
||||||
if err != nil {
|
|
||||||
panic("shite 3")
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,17 @@ type StateDB struct {
|
||||||
// Testing hooks
|
// Testing hooks
|
||||||
onCommit func(states *triestate.Set) // Hook invoked when commit is performed
|
onCommit func(states *triestate.Set) // Hook invoked when commit is performed
|
||||||
|
|
||||||
witness *Witness
|
recordWitness bool
|
||||||
|
witness *Witness
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWithWitnessRecording(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) {
|
||||||
|
sdb, err := New(root, db, snaps)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sdb.recordWitness = true
|
||||||
|
return sdb, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new state from a given trie.
|
// New creates a new state from a given trie.
|
||||||
|
|
@ -1202,6 +1212,8 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
|
||||||
storageTrieNodesDeleted int
|
storageTrieNodesDeleted int
|
||||||
nodes = trienode.NewMergedNodeSet()
|
nodes = trienode.NewMergedNodeSet()
|
||||||
codeWriter = s.db.DiskDB().NewBatch()
|
codeWriter = s.db.DiskDB().NewBatch()
|
||||||
|
root common.Hash
|
||||||
|
set *trienode.NodeSet
|
||||||
)
|
)
|
||||||
// Handle all state deletions first
|
// Handle all state deletions first
|
||||||
incomplete, err := s.handleDestruction(nodes)
|
incomplete, err := s.handleDestruction(nodes)
|
||||||
|
|
@ -1247,9 +1259,14 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
|
||||||
if metrics.EnabledExpensive {
|
if metrics.EnabledExpensive {
|
||||||
start = time.Now()
|
start = time.Now()
|
||||||
}
|
}
|
||||||
//root, set, err := s.trie.Commit(true)
|
|
||||||
root, set, accessList, err := s.trie.CommitAndObtainAccessList(true)
|
if s.recordWitness {
|
||||||
s.witness.addAccessList(common.Hash{}, accessList)
|
var accessList map[string][]byte
|
||||||
|
root, set, accessList, err = s.trie.CommitAndObtainAccessList(true)
|
||||||
|
s.witness.addAccessList(common.Hash{}, accessList)
|
||||||
|
} else {
|
||||||
|
root, set, err = s.trie.Commit(true)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -443,3 +443,8 @@ func (api *DebugAPI) GetTrieFlushInterval() (string, error) {
|
||||||
}
|
}
|
||||||
return api.eth.blockchain.GetTrieFlushInterval().String(), nil
|
return api.eth.blockchain.GetTrieFlushInterval().String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *DebugAPI) SetWitnessRecording(path string, enabled bool) error {
|
||||||
|
api.eth.blockchain.SetWitnessRecording(path, enabled)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -501,6 +501,11 @@ web3._extend({
|
||||||
call: 'debug_getTrieFlushInterval',
|
call: 'debug_getTrieFlushInterval',
|
||||||
params: 0
|
params: 0
|
||||||
}),
|
}),
|
||||||
|
new web3._extend.Method({
|
||||||
|
name: 'setWitnessRecording',
|
||||||
|
call: 'debug_setWitnessRecording',
|
||||||
|
params: 2
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
properties: []
|
properties: []
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue