Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,7 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) {
// IntermediateRoot computes the current root hash of the state trie.
// It is called in between transactions to get the root hash that
// goes into transaction receipts.
func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool, opts ...stateconf.StateDBIntermediateRootOption) common.Hash {
// Finalise all the dirty storage states and write them into the tries
s.Finalise(deleteEmptyObjects)

Expand All @@ -883,6 +883,15 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
s.prefetcher = nil
}()
}

if stateconf.ShouldDestructStateDB(opts...) {
for addr := range s.stateObjectsDestruct {
if obj := s.stateObjects[addr]; obj != nil {
s.trie.DeleteAccount(addr) // prefix delete in firewood
}
}
}

// Although naively it makes sense to retrieve the account trie and then do
// the contract storage and account updates sequentially, that short circuits
// the account prefetcher. Instead, let's process all the storage updates
Expand Down Expand Up @@ -1163,7 +1172,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool, opts ...statecon
return common.Hash{}, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr)
}
// Finalize any pending changes and merge everything into the tries
s.IntermediateRoot(deleteEmptyObjects)
s.IntermediateRoot(deleteEmptyObjects, stateconf.ExtractIntermediateRootOpts(opts...)...)

// Commit objects to the trie, measuring the elapsed time
var (
Expand Down
36 changes: 34 additions & 2 deletions libevm/stateconf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ import (
type StateDBCommitOption = options.Option[stateDBCommitConfig]

type stateDBCommitConfig struct {
snapshotOpts []SnapshotUpdateOption
triedbOpts []TrieDBUpdateOption
snapshotOpts []SnapshotUpdateOption
triedbOpts []TrieDBUpdateOption
intermediateRootOpts []StateDBIntermediateRootOption
}

// WithSnapshotUpdateOpts returns a StateDBCommitOption carrying a list of
Expand Down Expand Up @@ -60,6 +61,21 @@ func ExtractTrieDBUpdateOpts(opts ...StateDBCommitOption) []TrieDBUpdateOption {
return options.As(opts...).triedbOpts
}

// WithIntermediateRootOpts returns a StateDBCommitOption carrying a list of
// StateDBIntermediateRootOptions. If multiple such options are used, only the last will be
// applied as they overwrite each other.
func WithIntermediateRootOpts(opts ...StateDBIntermediateRootOption) StateDBCommitOption {
return options.Func[stateDBCommitConfig](func(c *stateDBCommitConfig) {
c.intermediateRootOpts = opts
})
}

// ExtractIntermediateRootOpts returns the list of StateDBIntermediateRootOptions carried by
// the provided slice of StateDBCommitOption.
func ExtractIntermediateRootOpts(opts ...StateDBCommitOption) []StateDBIntermediateRootOption {
return options.As(opts...).intermediateRootOpts
}

// A SnapshotUpdateOption configures the behaviour of
// state.SnapshotTree.Update() implementations. This will be removed along with
// state.SnapshotTree.
Expand Down Expand Up @@ -114,6 +130,22 @@ func ExtractTrieDBUpdatePayload(opts ...TrieDBUpdateOption) (common.Hash, common
return *conf.parentBlockHash, *conf.currentBlockHash, true
}

type StateDBIntermediateRootOption = options.Option[stateDBIntermediateRootConfig]

type stateDBIntermediateRootConfig struct {
shouldDestruct bool
}

func WithStateDBDestruct() StateDBIntermediateRootOption {
return options.Func[stateDBIntermediateRootConfig](func(c *stateDBIntermediateRootConfig) {
c.shouldDestruct = true
})
}

func ShouldDestructStateDB(opts ...StateDBIntermediateRootOption) bool {
return options.As(opts...).shouldDestruct
}

// A StateDBStateOption configures the behaviour of state.StateDB methods for
// getting and setting state: GetState(), GetCommittedState(), and SetState().
type StateDBStateOption = options.Option[stateDBStateConfig]
Expand Down
Loading