diff --git a/core/state/statedb.go b/core/state/statedb.go index 74f2e9518a..930af4b2ab 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -42,7 +42,6 @@ import ( "github.com/ethereum/go-ethereum/trie/triestate" "github.com/ethereum/go-ethereum/trie/utils" "github.com/holiman/uint256" - "golang.org/x/sync/errgroup" ) // TriesInMemory represents the number of layers that are kept in RAM. @@ -167,6 +166,9 @@ type StateDB struct { StorageUpdated atomic.Int64 AccountDeleted int StorageDeleted atomic.Int64 + + // singlethreaded avoids creation of additional threads when set to true for compatibility with cannon. + singlethreaded bool } // New creates a new state from a given trie. @@ -196,6 +198,10 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) return sdb, nil } +func (s *StateDB) MakeSinglethreaded() { + s.singlethreaded = true +} + // SetLogger sets the logger for account update hooks. func (s *StateDB) SetLogger(l *tracing.Hooks) { s.logger = l @@ -852,7 +858,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { // so there's no need to explicitly wait for the prefetchers to finish. var ( start = time.Now() - workers errgroup.Group + workers = newWorkerGroup(s.singlethreaded) ) if s.db.TrieDB().IsVerkle() { // Whilst MPT storage tries are independent, Verkle has one single trie @@ -1227,7 +1233,7 @@ func (s *StateDB) commit(deleteEmptyObjects bool) (*stateUpdate, error) { var ( start = time.Now() root common.Hash - workers errgroup.Group + workers = newWorkerGroup(s.singlethreaded) ) // Schedule the account trie first since that will be the biggest, so give // it the most time to crunch. diff --git a/core/state/workers.go b/core/state/workers.go new file mode 100644 index 0000000000..72b93cd7ad --- /dev/null +++ b/core/state/workers.go @@ -0,0 +1,37 @@ +package state + +import ( + "errors" + + "golang.org/x/sync/errgroup" +) + +type workerGroup interface { + Go(func() error) + SetLimit(int) + Wait() error +} + +func newWorkerGroup(singlethreaded bool) workerGroup { + if singlethreaded { + return &inlineWorkerGroup{} + } else { + var grp errgroup.Group + return &grp + } +} + +type inlineWorkerGroup struct { + err error +} + +func (i *inlineWorkerGroup) Go(action func() error) { + i.err = errors.Join(i.err, action()) +} + +func (i *inlineWorkerGroup) SetLimit(_ int) { +} + +func (i *inlineWorkerGroup) Wait() error { + return i.err +}