From 9570ab04f03141c07b4269c2bdf4c53fad24aa3f Mon Sep 17 00:00:00 2001 From: galaio Date: Wed, 4 Sep 2024 22:06:31 +0800 Subject: [PATCH] txdag: clean codes; --- core/state/statedb.go | 15 +++-- core/state_transition.go | 6 +- core/types/mvstates.go | 112 +++++++++--------------------------- core/types/mvstates_test.go | 99 ------------------------------- core/vm/interface.go | 4 +- miner/worker.go | 2 +- 6 files changed, 41 insertions(+), 197 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index 1316aa1b04..fbe6fb90c7 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -947,6 +947,7 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) { s.mvStates.RecordAccountWrite(addr, types.AccountSuicide) } } + s.stateObjectsDestructDirty = make(map[common.Address]*types.StateAccount) for addr := range s.journal.dirties { obj, exist := s.stateObjects[addr] if !exist { @@ -992,7 +993,9 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) { // the commit-phase will be a lot faster addressesToPrefetch = append(addressesToPrefetch, common.CopyBytes(addr[:])) // Copy needed for closure } - + if s.mvStates != nil { + s.mvStates.RecordWriteDone() + } if s.prefetcher != nil && len(addressesToPrefetch) > 0 { s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, addressesToPrefetch) } @@ -1709,6 +1712,7 @@ func (s *StateDB) BeginTxRecorder(isExcludeTx bool) { if s.mvStates == nil { return } + log.Debug("BeginTxRecorder", "tx", s.txIndex) if isExcludeTx { rwSet := types.NewRWSet(s.txIndex).WithExcludedTxFlag() if err := s.mvStates.FinaliseWithRWSet(rwSet); err != nil { @@ -1724,9 +1728,9 @@ func (s *StateDB) ResetMVStates(txCount int, feeReceivers []common.Address) *typ return s.mvStates } -func (s *StateDB) CheckFeeReceiversRWSet() error { +func (s *StateDB) CheckFeeReceiversRWSet() { if s.mvStates == nil { - return nil + return } if metrics.EnabledExpensive { defer func(start time.Time) { @@ -1740,7 +1744,7 @@ func (s *StateDB) CheckFeeReceiversRWSet() error { continue } s.mvStates.RecordCannotDelayGasFee() - return nil + return } for _, addr := range feeReceivers { @@ -1748,9 +1752,8 @@ func (s *StateDB) CheckFeeReceiversRWSet() error { continue } s.mvStates.RecordCannotDelayGasFee() - return nil + return } - return nil } func (s *StateDB) getStateObjectsDestruct(addr common.Address) (*types.StateAccount, bool) { diff --git a/core/state_transition.go b/core/state_transition.go index 650263c494..e0ace277f7 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -27,7 +27,6 @@ import ( cmath "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" ) @@ -535,9 +534,8 @@ func (st *StateTransition) innerTransitionDb() (*ExecutionResult, error) { } // check fee receiver rwSet here - if ferr := st.state.CheckFeeReceiversRWSet(); ferr != nil { - log.Error("CheckFeeReceiversRWSet err", "block", st.evm.Context.BlockNumber, "tx", st.evm.StateDB.TxIndex(), "err", ferr) - } + st.state.CheckFeeReceiversRWSet() + effectiveTip := msg.GasPrice if rules.IsLondon { effectiveTip = cmath.BigMin(msg.GasTipCap, new(big.Int).Sub(msg.GasFeeCap, st.evm.Context.BaseFee)) diff --git a/core/types/mvstates.go b/core/types/mvstates.go index ea709902d4..c96b6add85 100644 --- a/core/types/mvstates.go +++ b/core/types/mvstates.go @@ -8,7 +8,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" - "github.com/holiman/uint256" "golang.org/x/exp/slices" ) @@ -56,10 +55,6 @@ func NewRWSet(index int) *RWSet { } } -func (s *RWSet) Index() int { - return s.index -} - func (s *RWSet) RecordAccountRead(addr common.Address, state AccountState) { // only record the first read version sub, ok := s.accReadSet[addr] @@ -105,26 +100,6 @@ func (s *RWSet) RecordStorageWrite(addr common.Address, slot common.Hash) { s.slotWriteSet[addr][slot] = struct{}{} } -func (s *RWSet) queryAccReadItem(addr common.Address, state AccountState) bool { - sub, ok := s.accReadSet[addr] - if !ok { - return false - } - - _, ok = sub[state] - return ok -} - -func (s *RWSet) querySlotReadItem(addr common.Address, slot common.Hash) bool { - sub, ok := s.slotReadSet[addr] - if !ok { - return false - } - - _, ok = sub[slot] - return ok -} - func (s *RWSet) ReadSet() (map[common.Address]map[AccountState]struct{}, map[common.Address]map[common.Hash]struct{}) { return s.accReadSet, s.slotReadSet } @@ -275,11 +250,13 @@ type MVStates struct { txDepCache []TxDep // async rw event recorder + // these fields are only used in one routine asyncRWSet *RWSet rwEventCh chan []RWEventItem rwEventCache []RWEventItem rwEventCacheIndex int - recordeReadDone bool + recordingRead bool + recordingWrite bool // execution stat infos lock sync.RWMutex @@ -407,6 +384,7 @@ func (s *MVStates) finalisePreviousRWSet() { } if _, exist := s.asyncRWSet.accReadSet[addr][AccountSelf]; exist { s.cannotGasFeeDelay = true + break } } s.resolveDepsMapCacheByWrites(index, s.asyncRWSet) @@ -423,12 +401,21 @@ func (s *MVStates) RecordNewTx(index int) { }) } s.rwEventCacheIndex++ - s.recordeReadDone = false + s.recordingRead = true + s.recordingWrite = true s.BatchRecordHandle() } +func (s *MVStates) RecordReadDone() { + s.recordingRead = false +} + +func (s *MVStates) RecordWriteDone() { + s.recordingWrite = false +} + func (s *MVStates) RecordAccountRead(addr common.Address, state AccountState) { - if s.recordeReadDone { + if !s.recordingRead { return } if s.rwEventCacheIndex < len(s.rwEventCache) { @@ -447,7 +434,7 @@ func (s *MVStates) RecordAccountRead(addr common.Address, state AccountState) { } func (s *MVStates) RecordStorageRead(addr common.Address, slot common.Hash) { - if s.recordeReadDone { + if !s.recordingRead { return } if s.rwEventCacheIndex < len(s.rwEventCache) { @@ -465,11 +452,10 @@ func (s *MVStates) RecordStorageRead(addr common.Address, slot common.Hash) { s.rwEventCacheIndex++ } -func (s *MVStates) RecordReadDone() { - s.recordeReadDone = true -} - func (s *MVStates) RecordAccountWrite(addr common.Address, state AccountState) { + if !s.recordingWrite { + return + } if s.rwEventCacheIndex < len(s.rwEventCache) { s.rwEventCache[s.rwEventCacheIndex].Event = WriteAccRWEvent s.rwEventCache[s.rwEventCacheIndex].Addr = addr @@ -486,6 +472,9 @@ func (s *MVStates) RecordAccountWrite(addr common.Address, state AccountState) { } func (s *MVStates) RecordStorageWrite(addr common.Address, slot common.Hash) { + if !s.recordingWrite { + return + } if s.rwEventCacheIndex < len(s.rwEventCache) { s.rwEventCache[s.rwEventCacheIndex].Event = WriteSlotRWEvent s.rwEventCache[s.rwEventCacheIndex].Addr = addr @@ -502,6 +491,9 @@ func (s *MVStates) RecordStorageWrite(addr common.Address, slot common.Hash) { } func (s *MVStates) RecordCannotDelayGasFee() { + if !s.recordingWrite { + return + } if s.rwEventCacheIndex < len(s.rwEventCache) { s.rwEventCache[s.rwEventCacheIndex].Event = CannotGasFeeDelayRWEvent s.rwEventCacheIndex++ @@ -514,7 +506,7 @@ func (s *MVStates) RecordCannotDelayGasFee() { } func (s *MVStates) BatchRecordHandle() { - if len(s.rwEventCache) == 0 { + if s.rwEventCacheIndex == 0 { return } s.rwEventCh <- s.rwEventCache[:s.rwEventCacheIndex] @@ -543,9 +535,6 @@ func (s *MVStates) quickFinaliseWithRWSet(rwSet *RWSet) error { func (s *MVStates) FinaliseWithRWSet(rwSet *RWSet) error { s.lock.Lock() defer s.lock.Unlock() - if s.asyncRWSet == nil { - s.asyncRWSet = nil - } index := rwSet.index if s.nextFinaliseIndex > index { return fmt.Errorf("finalise in wrong order, next: %d, input: %d", s.nextFinaliseIndex, index) @@ -561,7 +550,6 @@ func (s *MVStates) FinaliseWithRWSet(rwSet *RWSet) error { "readCnt", len(s.rwSets[i].accReadSet)+len(s.rwSets[i].slotReadSet), "writeCnt", len(s.rwSets[i].accWriteSet)+len(s.rwSets[i].slotWriteSet)) } - s.rwSets[index] = rwSet return nil } @@ -813,15 +801,6 @@ func checkSlotDependency(writeSet map[common.Address]map[common.Hash]struct{}, r return false } -type TxDepMaker interface { - add(index uint64) - exist(index uint64) bool - deps() []uint64 - remove(index uint64) - len() int - reset() -} - type TxDepMap struct { tm map[uint64]struct{} cache []uint64 @@ -864,42 +843,3 @@ func (m *TxDepMap) remove(index uint64) { func (m *TxDepMap) len() int { return len(m.tm) } - -func (m *TxDepMap) reset() { - m.cache = nil - m.tm = make(map[uint64]struct{}) -} - -// isEqualRWVal compare state -func isEqualRWVal(accState *AccountState, src interface{}, compared interface{}) bool { - if accState != nil { - switch *accState { - case AccountBalance: - if src != nil && compared != nil { - return equalUint256(src.(*uint256.Int), compared.(*uint256.Int)) - } - return src == compared - case AccountNonce: - return src.(uint64) == compared.(uint64) - case AccountCodeHash: - if src != nil && compared != nil { - return slices.Equal(src.([]byte), compared.([]byte)) - } - return src == compared - } - return false - } - - if src != nil && compared != nil { - return src.(common.Hash) == compared.(common.Hash) - } - return src == compared -} - -func equalUint256(s, c *uint256.Int) bool { - if s != nil && c != nil { - return s.Eq(c) - } - - return s == c -} diff --git a/core/types/mvstates_test.go b/core/types/mvstates_test.go index f22ba40fe4..2f3eba3828 100644 --- a/core/types/mvstates_test.go +++ b/core/types/mvstates_test.go @@ -12,7 +12,6 @@ import ( "github.com/cometbft/cometbft/libs/rand" "github.com/golang/snappy" - "github.com/holiman/uint256" "github.com/stretchr/testify/require" ) @@ -187,104 +186,6 @@ func TestMVStates_SystemTxWithLargeDepsResolveTxDAG(t *testing.T) { t.Log(dag) } -func TestIsEqualRWVal(t *testing.T) { - tests := []struct { - key *AccountState - src interface{} - compared interface{} - isEqual bool - }{ - { - key: &AccountNonce, - src: uint64(0), - compared: uint64(0), - isEqual: true, - }, - { - key: &AccountNonce, - src: uint64(0), - compared: uint64(1), - isEqual: false, - }, - { - key: &AccountBalance, - src: new(uint256.Int).SetUint64(1), - compared: new(uint256.Int).SetUint64(1), - isEqual: true, - }, - { - key: &AccountBalance, - src: nil, - compared: new(uint256.Int).SetUint64(1), - isEqual: false, - }, - { - key: &AccountBalance, - src: (*uint256.Int)(nil), - compared: new(uint256.Int).SetUint64(1), - isEqual: false, - }, - { - key: &AccountBalance, - src: (*uint256.Int)(nil), - compared: (*uint256.Int)(nil), - isEqual: true, - }, - { - key: &AccountCodeHash, - src: []byte{1}, - compared: []byte{1}, - isEqual: true, - }, - { - key: &AccountCodeHash, - src: nil, - compared: []byte{1}, - isEqual: false, - }, - { - key: &AccountCodeHash, - src: ([]byte)(nil), - compared: []byte{1}, - isEqual: false, - }, - { - key: &AccountCodeHash, - src: ([]byte)(nil), - compared: ([]byte)(nil), - isEqual: true, - }, - { - key: &AccountSuicide, - src: struct{}{}, - compared: struct{}{}, - isEqual: false, - }, - { - key: &AccountSuicide, - src: nil, - compared: struct{}{}, - isEqual: false, - }, - { - key: nil, - src: mockHash, - compared: mockHash, - isEqual: true, - }, - { - key: nil, - src: nil, - compared: mockHash, - isEqual: false, - }, - } - - for i, item := range tests { - require.Equal(t, item.isEqual, isEqualRWVal(item.key, item.src, item.compared), i) - } -} - func TestTxRecorder_Basic(t *testing.T) { sets := []*RWSet{ mockRWSet(0, []interface{}{AccountSelf, AccountBalance, "0x00"}, diff --git a/core/vm/interface.go b/core/vm/interface.go index 4ad4ecc311..b6db1fd461 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -80,7 +80,9 @@ type StateDB interface { AddPreimage(common.Hash, []byte) TxIndex() int - CheckFeeReceiversRWSet() error + + // parallel DAG related + CheckFeeReceiversRWSet() } // CallContext provides a basic interface for the EVM calling conventions. The EVM diff --git a/miner/worker.go b/miner/worker.go index c40b7d4ec3..56824813b0 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1288,7 +1288,7 @@ func (w *worker) generateWork(genParams *generateParams) *newPayloadResult { start := time.Now() if w.chain.TxDAGEnabledWhenMine() { - work.state.ResetMVStates(0, nil) + work.state.ResetMVStates(0, []common.Address{work.coinbase, params.OptimismBaseFeeRecipient, params.OptimismL1FeeRecipient}) } for _, tx := range genParams.txs { from, _ := types.Sender(work.signer, tx)