optionally enable block witness recording/dumping via 'debug_setWitnessRecording'. only collect witnesses in statedb if explicitly enabled

This commit is contained in:
Jared Wasinger 2023-12-19 18:51:23 +08:00
parent 64e53367d8
commit 2d0ee010f2
5 changed files with 69 additions and 16 deletions

View file

@ -258,6 +258,8 @@ type BlockChain struct {
processor Processor // Block transaction processor interface
forker *ForkChoice
vmConfig vm.Config
witnessRecordingPath atomic.Pointer[string]
}
// 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 {
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 {
return it.index, err
}
@ -1852,8 +1862,16 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
} else {
status, err = bc.writeBlockAndSetHead(block, receipts, logs, statedb, false)
}
statedb.GetWitness().SetBlock(block)
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)
followupInterrupt.Store(true)
@ -2594,3 +2612,11 @@ func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) {
func (bc *BlockChain) GetTrieFlushInterval() time.Duration {
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)
}
}

View file

@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/rlp"
"os"
"path/filepath"
)
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()
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 {
panic("shite2")
}
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 err
}
return nil
}

View file

@ -139,9 +139,19 @@ type StateDB struct {
// Testing hooks
onCommit func(states *triestate.Set) // Hook invoked when commit is performed
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.
func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) {
tr, err := db.OpenTrie(root)
@ -1202,6 +1212,8 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
storageTrieNodesDeleted int
nodes = trienode.NewMergedNodeSet()
codeWriter = s.db.DiskDB().NewBatch()
root common.Hash
set *trienode.NodeSet
)
// Handle all state deletions first
incomplete, err := s.handleDestruction(nodes)
@ -1247,9 +1259,14 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
if metrics.EnabledExpensive {
start = time.Now()
}
//root, set, err := s.trie.Commit(true)
root, set, accessList, err := s.trie.CommitAndObtainAccessList(true)
if s.recordWitness {
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 {
return common.Hash{}, err
}

View file

@ -443,3 +443,8 @@ func (api *DebugAPI) GetTrieFlushInterval() (string, error) {
}
return api.eth.blockchain.GetTrieFlushInterval().String(), nil
}
func (api *DebugAPI) SetWitnessRecording(path string, enabled bool) error {
api.eth.blockchain.SetWitnessRecording(path, enabled)
return nil
}

View file

@ -501,6 +501,11 @@ web3._extend({
call: 'debug_getTrieFlushInterval',
params: 0
}),
new web3._extend.Method({
name: 'setWitnessRecording',
call: 'debug_setWitnessRecording',
params: 2
}),
],
properties: []
});