mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
cleanup bal state transition
This commit is contained in:
parent
abd8612b1d
commit
74ca164123
1 changed files with 38 additions and 50 deletions
|
|
@ -15,6 +15,9 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// BALStateTransition is responsible for performing the state root update
|
||||
// and commit for EIP 7928 access-list-containing blocks. An instance of
|
||||
// this object is only used for a single block.
|
||||
type BALStateTransition struct {
|
||||
accessList *BALReader
|
||||
db Database
|
||||
|
|
@ -22,13 +25,18 @@ type BALStateTransition struct {
|
|||
stateTrie Trie
|
||||
parentRoot common.Hash
|
||||
|
||||
rootHash common.Hash
|
||||
diffs map[common.Address]*bal.AccountMutations
|
||||
prestates sync.Map //map[common.Address]*types.StateAccount
|
||||
|
||||
poststates map[common.Address]*types.StateAccount
|
||||
tries sync.Map //map[common.Address]Trie
|
||||
// the state root of the block
|
||||
rootHash common.Hash
|
||||
// the state modifications performed by the block
|
||||
diffs map[common.Address]*bal.AccountMutations
|
||||
// a map of common.Address -> *types.StateAccount containing the block
|
||||
// prestate of all accounts that will be modified
|
||||
prestates sync.Map
|
||||
|
||||
postStates map[common.Address]*types.StateAccount
|
||||
// a map of common.Address -> Trie containing the account tries for all
|
||||
// accounts with mutated storage
|
||||
tries sync.Map //map[common.Address]Trie
|
||||
deletions map[common.Address]struct{}
|
||||
|
||||
originStorages map[common.Address]map[common.Hash]common.Hash
|
||||
|
|
@ -39,8 +47,6 @@ type BALStateTransition struct {
|
|||
storageDeleted atomic.Int64
|
||||
storageUpdated atomic.Int64
|
||||
|
||||
// TODO: maybe package these into their own 'CommitMetrics' struct instead of making them public fields
|
||||
|
||||
stateUpdate *stateUpdate
|
||||
|
||||
metrics BALStateTransitionMetrics
|
||||
|
|
@ -85,7 +91,7 @@ func NewBALStateTransition(accessList *BALReader, db Database, parentRoot common
|
|||
rootHash: common.Hash{},
|
||||
diffs: make(map[common.Address]*bal.AccountMutations),
|
||||
prestates: sync.Map{},
|
||||
poststates: make(map[common.Address]*types.StateAccount),
|
||||
postStates: make(map[common.Address]*types.StateAccount),
|
||||
tries: sync.Map{},
|
||||
deletions: make(map[common.Address]struct{}),
|
||||
originStorages: make(map[common.Address]map[common.Hash]common.Hash),
|
||||
|
|
@ -128,6 +134,8 @@ func isAccountDeleted(prestate *types.StateAccount, mutations *bal.AccountMutati
|
|||
return false
|
||||
}
|
||||
|
||||
// updateAccount applies the block state mutations to a given account returning
|
||||
// the updated state account and new code (if the account code changed)
|
||||
func (s *BALStateTransition) updateAccount(addr common.Address) (*types.StateAccount, []byte) {
|
||||
a, _ := s.prestates.Load(addr)
|
||||
acct := a.(*types.StateAccount)
|
||||
|
|
@ -159,7 +167,7 @@ func (s *BALStateTransition) commitAccount(addr common.Address) (*accountUpdate,
|
|||
)
|
||||
op := &accountUpdate{
|
||||
address: addr,
|
||||
data: types.SlimAccountRLP(*s.poststates[addr]), // TODO: cache the updated state acocunt somewhere
|
||||
data: types.SlimAccountRLP(*s.postStates[addr]), // TODO: cache the updated state acocunt somewhere
|
||||
}
|
||||
if prestate, exist := s.prestates.Load(addr); exist {
|
||||
prestate := prestate.(*types.StateAccount)
|
||||
|
|
@ -190,10 +198,11 @@ func (s *BALStateTransition) commitAccount(addr common.Address) (*accountUpdate,
|
|||
}
|
||||
tr, _ := s.tries.Load(addr)
|
||||
root, nodes := tr.(Trie).Commit(false)
|
||||
s.poststates[addr].Root = root
|
||||
s.postStates[addr].Root = root
|
||||
return op, nodes, nil
|
||||
}
|
||||
|
||||
// CommitWithUpdate flushes mutated trie nodes and state accounts to disk.
|
||||
func (s *BALStateTransition) CommitWithUpdate(block uint64, deleteEmptyObjects bool, noStorageWiping bool) (common.Hash, *stateUpdate, error) {
|
||||
// 1) create a stateUpdate object
|
||||
// Commit objects to the trie, measuring the elapsed time
|
||||
|
|
@ -342,14 +351,28 @@ func (s *BALStateTransition) CommitWithUpdate(block uint64, deleteEmptyObjects b
|
|||
return root, ret, nil
|
||||
}
|
||||
|
||||
// IntermediateRoot applies block state mutations and computes the updated state
|
||||
// trie root.
|
||||
func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
||||
if s.rootHash != (common.Hash{}) {
|
||||
return s.rootHash
|
||||
}
|
||||
|
||||
// State root calculation proceeds as follows:
|
||||
|
||||
// 1 (a): load the prestate state accounts for addresses which were modified in the block
|
||||
// 1 (b): load the origin storage values for all slots which were modified during the block (this is needed for computing the stateUpdate)
|
||||
// 1 (c): update each mutated account, producing the post-block state object by applying the state mutations to the prestate (retrieved in 1a).
|
||||
// 1 (d): prefetch the intermediate trie nodes of the mutated state set from the account trie.
|
||||
//
|
||||
// 2: compute the post-state root of the account trie
|
||||
//
|
||||
// Steps 1/2 are performed sequentially, with steps 1a-d performed in parallel
|
||||
|
||||
start := time.Now()
|
||||
lastIdx := len(s.accessList.block.Transactions()) + 1
|
||||
|
||||
//1 (b): load the origin storage values for all slots which were modified during the block
|
||||
s.originStoragesWG.Add(1)
|
||||
go func() {
|
||||
defer s.originStoragesWG.Done()
|
||||
|
|
@ -371,11 +394,6 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
|||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// 1. resolve the entire state object for the updated addrs, in parallel prefetch them in the account trie
|
||||
// 1. in parallel:
|
||||
// * load the prestate of mutated state objects from the snapshot, update their tries.
|
||||
// * prefetch all mutated account in the account trie
|
||||
|
||||
for _, addr := range s.accessList.ModifiedAccounts() {
|
||||
diff := s.accessList.readAccountDiff(addr, lastIdx)
|
||||
s.diffs[addr] = diff
|
||||
|
|
@ -385,6 +403,7 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
|||
wg.Add(1)
|
||||
address := addr
|
||||
go func() {
|
||||
// 1 (c): update each mutated account, producing the post-block state object by applying the state mutations to the prestate (retrieved in 1a).
|
||||
acct := s.accessList.prestateReader.account(address)
|
||||
diff := s.diffs[address]
|
||||
if acct == nil {
|
||||
|
|
@ -428,21 +447,6 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
|||
hashStart := time.Now()
|
||||
tr.Hash()
|
||||
s.metrics.StateHash = time.Since(hashStart)
|
||||
/*
|
||||
var objTrieData string
|
||||
it, err := tr.NodeIterator([]byte{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for it.Next(true) {
|
||||
if it.Leaf() {
|
||||
objTrieData += fmt.Sprintf("%x: %x\n", it.Path(), it.LeafBlob())
|
||||
} else {
|
||||
objTrieData += fmt.Sprintf("%x: %x\n", it.Path(), it.Hash())
|
||||
}
|
||||
}
|
||||
fmt.Printf("acct hash %x. hash=%x, updated storage: %v, deleted storage: %v trie:\n%s\n", crypto.Keccak256Hash(address[:]), tr.Hash(), updateKeys, deleteKeys, objTrieData)
|
||||
*/
|
||||
}
|
||||
|
||||
wg.Done()
|
||||
|
|
@ -450,7 +454,7 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
|||
}
|
||||
|
||||
wg.Add(1)
|
||||
// prefetch all modified accounts in the main account trie.
|
||||
// 1 (d): prefetch the intermediate trie nodes of the mutated state set from the account trie.
|
||||
go func() {
|
||||
prefetchStart := time.Now()
|
||||
if err := s.stateTrie.PrefetchAccount(s.accessList.ModifiedAccounts()); err != nil {
|
||||
|
|
@ -463,8 +467,7 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
|||
wg.Wait()
|
||||
s.metrics.AccountUpdate = time.Since(start)
|
||||
|
||||
// stage 2: update the main account trie
|
||||
|
||||
// 2: compute the post-state root of the account trie
|
||||
stateUpdateStart := time.Now()
|
||||
for mutatedAddr, _ := range s.diffs {
|
||||
p, _ := s.prestates.Load(mutatedAddr)
|
||||
|
|
@ -489,7 +492,7 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
|||
if err := s.stateTrie.UpdateAccount(mutatedAddr, acct, len(code)); err != nil {
|
||||
panic("FUCK4")
|
||||
}
|
||||
s.poststates[mutatedAddr] = acct
|
||||
s.postStates[mutatedAddr] = acct
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -498,21 +501,6 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
|||
stateTrieHashStart := time.Now()
|
||||
s.rootHash = s.stateTrie.Hash()
|
||||
s.metrics.StateHash = time.Since(stateTrieHashStart)
|
||||
|
||||
/*
|
||||
it, err := s.stateTrie.NodeIterator([]byte{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("state trie")
|
||||
for it.Next(true) {
|
||||
if it.Leaf() {
|
||||
fmt.Printf("%x: %x\n", it.Path(), it.LeafBlob())
|
||||
} else {
|
||||
fmt.Printf("%x: %x\n", it.Path(), it.Hash())
|
||||
}
|
||||
}
|
||||
*/
|
||||
return s.rootHash
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue