Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/state: copy the snap when copying the state #22340

Merged
merged 2 commits into from
Feb 18, 2021
Merged
Changes from 1 commit
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
25 changes: 25 additions & 0 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,31 @@ func (s *StateDB) Copy() *StateDB {
if s.prefetcher != nil {
state.prefetcher = s.prefetcher.copy()
}
if s.snaps != nil {
// In order for the miner to be able to use and make additions
// to the snapshot tree, we need to copy that aswell.
// Otherwise, any block mined by ourselves will cause gaps in the tree,
// and force the miner to operate trie-backed only
state.snaps = s.snaps
state.snap = s.snap
// TODO: Should we copy or make new (empty) ones here?
// If we copy, we need to ensure concurrency safety.
// If we don't copy, we run the risk of consensus breaking.
// In theory, as the state is copied, it's still 'fresh', and these
// should be empty.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The miner copies the state after running the transactions, but before claiming the block reward. It does this so it ca pile more txs on top. In that case, the state is fresh only if no tx populated it (i.e. post byzantium)

//
// It might be good to check the size first, and if any are non-zero,
// simply avoid copying over the snap
state.snapDestructs = make(map[common.Hash]struct{})
state.snapAccounts = make(map[common.Hash][]byte)
state.snapStorage = make(map[common.Hash]map[common.Hash][]byte)
if len(s.snapAccounts)+len(s.snapDestructs)+len(s.snapStorage) != 0 {
panic("Oy vey!")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expect this to blow up on pre-byzantium with intermediate root calls?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So... deep copy then?

}

}

state.snaps = s.snaps
return state
}

Expand Down