mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 00:39:26 +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"
|
"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 {
|
type BALStateTransition struct {
|
||||||
accessList *BALReader
|
accessList *BALReader
|
||||||
db Database
|
db Database
|
||||||
|
|
@ -22,13 +25,18 @@ type BALStateTransition struct {
|
||||||
stateTrie Trie
|
stateTrie Trie
|
||||||
parentRoot common.Hash
|
parentRoot common.Hash
|
||||||
|
|
||||||
rootHash common.Hash
|
// the state root of the block
|
||||||
diffs map[common.Address]*bal.AccountMutations
|
rootHash common.Hash
|
||||||
prestates sync.Map //map[common.Address]*types.StateAccount
|
// the state modifications performed by the block
|
||||||
|
diffs map[common.Address]*bal.AccountMutations
|
||||||
poststates map[common.Address]*types.StateAccount
|
// a map of common.Address -> *types.StateAccount containing the block
|
||||||
tries sync.Map //map[common.Address]Trie
|
// 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{}
|
deletions map[common.Address]struct{}
|
||||||
|
|
||||||
originStorages map[common.Address]map[common.Hash]common.Hash
|
originStorages map[common.Address]map[common.Hash]common.Hash
|
||||||
|
|
@ -39,8 +47,6 @@ type BALStateTransition struct {
|
||||||
storageDeleted atomic.Int64
|
storageDeleted atomic.Int64
|
||||||
storageUpdated atomic.Int64
|
storageUpdated atomic.Int64
|
||||||
|
|
||||||
// TODO: maybe package these into their own 'CommitMetrics' struct instead of making them public fields
|
|
||||||
|
|
||||||
stateUpdate *stateUpdate
|
stateUpdate *stateUpdate
|
||||||
|
|
||||||
metrics BALStateTransitionMetrics
|
metrics BALStateTransitionMetrics
|
||||||
|
|
@ -85,7 +91,7 @@ func NewBALStateTransition(accessList *BALReader, db Database, parentRoot common
|
||||||
rootHash: common.Hash{},
|
rootHash: common.Hash{},
|
||||||
diffs: make(map[common.Address]*bal.AccountMutations),
|
diffs: make(map[common.Address]*bal.AccountMutations),
|
||||||
prestates: sync.Map{},
|
prestates: sync.Map{},
|
||||||
poststates: make(map[common.Address]*types.StateAccount),
|
postStates: make(map[common.Address]*types.StateAccount),
|
||||||
tries: sync.Map{},
|
tries: sync.Map{},
|
||||||
deletions: make(map[common.Address]struct{}),
|
deletions: make(map[common.Address]struct{}),
|
||||||
originStorages: make(map[common.Address]map[common.Hash]common.Hash),
|
originStorages: make(map[common.Address]map[common.Hash]common.Hash),
|
||||||
|
|
@ -128,6 +134,8 @@ func isAccountDeleted(prestate *types.StateAccount, mutations *bal.AccountMutati
|
||||||
return false
|
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) {
|
func (s *BALStateTransition) updateAccount(addr common.Address) (*types.StateAccount, []byte) {
|
||||||
a, _ := s.prestates.Load(addr)
|
a, _ := s.prestates.Load(addr)
|
||||||
acct := a.(*types.StateAccount)
|
acct := a.(*types.StateAccount)
|
||||||
|
|
@ -159,7 +167,7 @@ func (s *BALStateTransition) commitAccount(addr common.Address) (*accountUpdate,
|
||||||
)
|
)
|
||||||
op := &accountUpdate{
|
op := &accountUpdate{
|
||||||
address: addr,
|
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 {
|
if prestate, exist := s.prestates.Load(addr); exist {
|
||||||
prestate := prestate.(*types.StateAccount)
|
prestate := prestate.(*types.StateAccount)
|
||||||
|
|
@ -190,10 +198,11 @@ func (s *BALStateTransition) commitAccount(addr common.Address) (*accountUpdate,
|
||||||
}
|
}
|
||||||
tr, _ := s.tries.Load(addr)
|
tr, _ := s.tries.Load(addr)
|
||||||
root, nodes := tr.(Trie).Commit(false)
|
root, nodes := tr.(Trie).Commit(false)
|
||||||
s.poststates[addr].Root = root
|
s.postStates[addr].Root = root
|
||||||
return op, nodes, nil
|
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) {
|
func (s *BALStateTransition) CommitWithUpdate(block uint64, deleteEmptyObjects bool, noStorageWiping bool) (common.Hash, *stateUpdate, error) {
|
||||||
// 1) create a stateUpdate object
|
// 1) create a stateUpdate object
|
||||||
// Commit objects to the trie, measuring the elapsed time
|
// 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
|
return root, ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IntermediateRoot applies block state mutations and computes the updated state
|
||||||
|
// trie root.
|
||||||
func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
||||||
if s.rootHash != (common.Hash{}) {
|
if s.rootHash != (common.Hash{}) {
|
||||||
return s.rootHash
|
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()
|
start := time.Now()
|
||||||
lastIdx := len(s.accessList.block.Transactions()) + 1
|
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)
|
s.originStoragesWG.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer s.originStoragesWG.Done()
|
defer s.originStoragesWG.Done()
|
||||||
|
|
@ -371,11 +394,6 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
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() {
|
for _, addr := range s.accessList.ModifiedAccounts() {
|
||||||
diff := s.accessList.readAccountDiff(addr, lastIdx)
|
diff := s.accessList.readAccountDiff(addr, lastIdx)
|
||||||
s.diffs[addr] = diff
|
s.diffs[addr] = diff
|
||||||
|
|
@ -385,6 +403,7 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
address := addr
|
address := addr
|
||||||
go func() {
|
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)
|
acct := s.accessList.prestateReader.account(address)
|
||||||
diff := s.diffs[address]
|
diff := s.diffs[address]
|
||||||
if acct == nil {
|
if acct == nil {
|
||||||
|
|
@ -428,21 +447,6 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
||||||
hashStart := time.Now()
|
hashStart := time.Now()
|
||||||
tr.Hash()
|
tr.Hash()
|
||||||
s.metrics.StateHash = time.Since(hashStart)
|
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()
|
wg.Done()
|
||||||
|
|
@ -450,7 +454,7 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Add(1)
|
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() {
|
go func() {
|
||||||
prefetchStart := time.Now()
|
prefetchStart := time.Now()
|
||||||
if err := s.stateTrie.PrefetchAccount(s.accessList.ModifiedAccounts()); err != nil {
|
if err := s.stateTrie.PrefetchAccount(s.accessList.ModifiedAccounts()); err != nil {
|
||||||
|
|
@ -463,8 +467,7 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
s.metrics.AccountUpdate = time.Since(start)
|
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()
|
stateUpdateStart := time.Now()
|
||||||
for mutatedAddr, _ := range s.diffs {
|
for mutatedAddr, _ := range s.diffs {
|
||||||
p, _ := s.prestates.Load(mutatedAddr)
|
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 {
|
if err := s.stateTrie.UpdateAccount(mutatedAddr, acct, len(code)); err != nil {
|
||||||
panic("FUCK4")
|
panic("FUCK4")
|
||||||
}
|
}
|
||||||
s.poststates[mutatedAddr] = acct
|
s.postStates[mutatedAddr] = acct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -498,21 +501,6 @@ func (s *BALStateTransition) IntermediateRoot(_ bool) common.Hash {
|
||||||
stateTrieHashStart := time.Now()
|
stateTrieHashStart := time.Now()
|
||||||
s.rootHash = s.stateTrie.Hash()
|
s.rootHash = s.stateTrie.Hash()
|
||||||
s.metrics.StateHash = time.Since(stateTrieHashStart)
|
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
|
return s.rootHash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue