From 6801260e9a574279b14f996cf7565423703933ad Mon Sep 17 00:00:00 2001 From: Pratik Patil Date: Mon, 22 Jan 2024 19:00:20 +0530 Subject: [PATCH] Revert "fix bug: should use Lock when mutating the flag" (#1140) --- cmd/evm/testdata/3/readme.md | 6 ++- cmd/evm/testdata/4/readme.md | 6 ++- core/blockchain.go | 30 ++++++++----- core/blockstm/mvhashmap.go | 37 ++++++++++------ core/parallel_state_processor.go | 4 +- core/state/pruner/pruner.go | 44 ++----------------- core/vm/interpreter.go | 4 ++ eth/backend.go | 4 +- miner/worker_test.go | 2 +- packaging/templates/package_scripts/control | 2 +- .../templates/package_scripts/control.arm64 | 2 +- .../package_scripts/control.profile.amd64 | 2 +- .../package_scripts/control.profile.arm64 | 2 +- .../package_scripts/control.validator | 2 +- .../package_scripts/control.validator.arm64 | 2 +- params/version.go | 8 ++-- 16 files changed, 74 insertions(+), 83 deletions(-) diff --git a/cmd/evm/testdata/3/readme.md b/cmd/evm/testdata/3/readme.md index 7a52c9833e..016887f865 100644 --- a/cmd/evm/testdata/3/readme.md +++ b/cmd/evm/testdata/3/readme.md @@ -1,2 +1,6 @@ +<<<<<<< HEAD These files examplify a transition where a transaction (executed on block 5) requests -the blockhash for block `1`. +======= +These files exemplify a transition where a transaction (executed on block 5) requests +>>>>>>> bed84606583893fdb698cc1b5058cc47b4dbd837 +the blockhash for block `1`. diff --git a/cmd/evm/testdata/4/readme.md b/cmd/evm/testdata/4/readme.md index 56846dfdd2..9d1c946a86 100644 --- a/cmd/evm/testdata/4/readme.md +++ b/cmd/evm/testdata/4/readme.md @@ -1,3 +1,7 @@ +<<<<<<< HEAD +These files examplify a transition where a transaction (executed on block 5) requests +======= These files exemplify a transition where a transaction (executed on block 5) requests -the blockhash for block `4`, but where the hash for that block is missing. +>>>>>>> bed84606583893fdb698cc1b5058cc47b4dbd837 +the blockhash for block `4`, but where the hash for that block is missing. It's expected that executing these should cause `exit` with errorcode `4`. diff --git a/core/blockchain.go b/core/blockchain.go index b63ab6378c..36d5635065 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -236,14 +236,13 @@ type BlockChain struct { stopping atomic.Bool // false if chain is running, true when stopped procInterrupt atomic.Bool // interrupt signaler for block processing - engine consensus.Engine - validator Validator // Block and state validator interface - prefetcher Prefetcher - processor Processor // Block transaction processor interface - parallelProcessor Processor // Parallel block transaction processor interface - parallelSpeculativeProcesses int // Number of parallel speculative processes - forker *ForkChoice - vmConfig vm.Config + engine consensus.Engine + validator Validator // Block and state validator interface + prefetcher Prefetcher + processor Processor // Block transaction processor interface + parallelProcessor Processor // Parallel block transaction processor interface + forker *ForkChoice + vmConfig vm.Config // Bor related changes borReceiptsCache *lru.Cache[common.Hash, *types.Receipt] // Cache for the most recent bor receipt receipts per block @@ -409,8 +408,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis // The first thing the node will do is reconstruct the verification data for // the head block (ethash cache or clique voting snapshot). Might as well do // it in advance. - // BOR - commented out intentionally - // bc.engine.VerifyHeader(bc, bc.CurrentHeader()) + bc.engine.VerifyHeader(bc, bc.CurrentHeader()) // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain for hash := range BadHashes { @@ -483,7 +481,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis } // NewParallelBlockChain , similar to NewBlockChain, creates a new blockchain object, but with a parallel state processor -func NewParallelBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis, overrides *ChainOverrides, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(header *types.Header) bool, txLookupLimit *uint64, checker ethereum.ChainValidator, numprocs int) (*BlockChain, error) { +func NewParallelBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis, overrides *ChainOverrides, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(header *types.Header) bool, txLookupLimit *uint64, checker ethereum.ChainValidator) (*BlockChain, error) { bc, err := NewBlockChain(db, cacheConfig, genesis, overrides, engine, vmConfig, shouldPreserve, txLookupLimit, checker) if err != nil { @@ -502,7 +500,6 @@ func NewParallelBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis } bc.parallelProcessor = NewParallelStateProcessor(chainConfig, bc, engine) - bc.parallelSpeculativeProcesses = numprocs return bc, nil } @@ -2142,6 +2139,15 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1) } + statedb, err := state.New(parent.Root, bc.stateCache, bc.snaps) + if err != nil { + return it.index, err + } + + // Enable prefetching to pull in trie node paths while processing transactions + statedb.StartPrefetcher("chain") + activeState = statedb + // If we have a followup block, run that against the current state to pre-cache // transactions and probabilistically some of the account/storage trie nodes. var followupInterrupt atomic.Bool diff --git a/core/blockstm/mvhashmap.go b/core/blockstm/mvhashmap.go index 003de91e70..59085138cf 100644 --- a/core/blockstm/mvhashmap.go +++ b/core/blockstm/mvhashmap.go @@ -121,23 +121,34 @@ func (mv *MVHashMap) Write(k Key, v Version, data interface{}) { return }) - cells.rw.Lock() - if ci, ok := cells.tm.Get(v.TxnIndex); !ok { - cells.tm.Put(v.TxnIndex, &WriteCell{ - flag: FlagDone, - incarnation: v.Incarnation, - data: data, - }) - } else { + cells.rw.RLock() + ci, ok := cells.tm.Get(v.TxnIndex) + cells.rw.RUnlock() + + if ok { if ci.(*WriteCell).incarnation > v.Incarnation { panic(fmt.Errorf("existing transaction value does not have lower incarnation: %v, %v", k, v.TxnIndex)) } + ci.(*WriteCell).flag = FlagDone ci.(*WriteCell).incarnation = v.Incarnation ci.(*WriteCell).data = data + } else { + cells.rw.Lock() + if ci, ok = cells.tm.Get(v.TxnIndex); !ok { + cells.tm.Put(v.TxnIndex, &WriteCell{ + flag: FlagDone, + incarnation: v.Incarnation, + data: data, + }) + } else { + ci.(*WriteCell).flag = FlagDone + ci.(*WriteCell).incarnation = v.Incarnation + ci.(*WriteCell).data = data + } + cells.rw.Unlock() } - cells.rw.Unlock() } func (mv *MVHashMap) ReadStorage(k Key, fallBack func() any) any { @@ -155,13 +166,13 @@ func (mv *MVHashMap) MarkEstimate(k Key, txIdx int) { panic(fmt.Errorf("path must already exist")) }) - cells.rw.Lock() + cells.rw.RLock() if ci, ok := cells.tm.Get(txIdx); !ok { panic(fmt.Sprintf("should not happen - cell should be present for path. TxIdx: %v, path, %x, cells keys: %v", txIdx, k, cells.tm.Keys())) } else { ci.(*WriteCell).flag = FlagEstimate } - cells.rw.Unlock() + cells.rw.RUnlock() } func (mv *MVHashMap) Delete(k Key, txIdx int) { @@ -222,8 +233,8 @@ func (mv *MVHashMap) Read(k Key, txIdx int) (res MVReadResult) { } cells.rw.RLock() - fk, fv := cells.tm.Floor(txIdx - 1) + cells.rw.RUnlock() if fk != nil && fv != nil { c := fv.(*WriteCell) @@ -242,8 +253,6 @@ func (mv *MVHashMap) Read(k Key, txIdx int) (res MVReadResult) { } } - cells.rw.RUnlock() - return } diff --git a/core/parallel_state_processor.go b/core/parallel_state_processor.go index 2dfff35349..c4077de4d8 100644 --- a/core/parallel_state_processor.go +++ b/core/parallel_state_processor.go @@ -364,7 +364,7 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat backupStateDB := statedb.Copy() profile := false - result, err := blockstm.ExecuteParallel(tasks, profile, metadata, p.bc.parallelSpeculativeProcesses, interruptCtx) + result, err := blockstm.ExecuteParallel(tasks, profile, metadata, cfg.ParallelSpeculativeProcesses, interruptCtx) if err == nil && profile && result.Deps != nil { _, weight := result.Deps.LongestPath(*result.Stats) @@ -398,7 +398,7 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat t.totalUsedGas = usedGas } - _, err = blockstm.ExecuteParallel(tasks, false, metadata, p.bc.parallelSpeculativeProcesses, interruptCtx) + _, err = blockstm.ExecuteParallel(tasks, false, metadata, cfg.ParallelSpeculativeProcesses, interruptCtx) break } diff --git a/core/state/pruner/pruner.go b/core/state/pruner/pruner.go index ea021c3be2..157d2e181d 100644 --- a/core/state/pruner/pruner.go +++ b/core/state/pruner/pruner.go @@ -57,7 +57,6 @@ const ( // Config includes all the configurations for pruning. type Config struct { Datadir string // The directory of the state database - Cachedir string // The directory of state clean cache BloomSize uint64 // The Megabytes of memory allocated to bloom-filter } @@ -262,7 +261,7 @@ func (p *Pruner) Prune(root common.Hash) error { } if stateBloomRoot != (common.Hash{}) { - return RecoverPruning(p.config.Datadir, p.db, p.config.Cachedir) + return RecoverPruning(p.config.Datadir, p.db) } // If the target state root is not specified, use the HEAD-127 as the // target. The reason for picking it is: @@ -287,8 +286,8 @@ func (p *Pruner) Prune(root common.Hash) error { // is the presence of root can indicate the presence of the // entire trie. if !rawdb.HasLegacyTrieNode(p.db, root) { - // The special case is for clique based networks(goerli and - // some other private networks), it's possible that two + // The special case is for clique based networks(goerli + // and some other private networks), it's possible that two // consecutive blocks will have same root. In this case snapshot // difflayer won't be created. So HEAD-127 may not paired with // head-127 layer. Instead the paired layer is higher than the @@ -325,12 +324,6 @@ func (p *Pruner) Prune(root common.Hash) error { log.Info("Selecting user-specified state as the pruning target", "root", root) } } - // Before start the pruning, delete the clean trie cache first. - // It's necessary otherwise in the next restart we will hit the - // deleted state root in the "clean cache" so that the incomplete - // state is picked for usage. - deleteCleanTrieCache(p.config.Cachedir) - // All the state roots of the middle layer should be forcibly pruned, // otherwise the dangling state will be left. middleRoots := make(map[common.Hash]struct{}) @@ -375,7 +368,7 @@ func (p *Pruner) Prune(root common.Hash) error { // pruning can be resumed. What's more if the bloom filter is constructed, the // pruning **has to be resumed**. Otherwise a lot of dangling nodes may be left // in the disk. -func RecoverPruning(datadir string, db ethdb.Database, trieCachePath string) error { +func RecoverPruning(datadir string, db ethdb.Database) error { stateBloomPath, stateBloomRoot, err := findBloomFilter(datadir) if err != nil { return err @@ -416,12 +409,6 @@ func RecoverPruning(datadir string, db ethdb.Database, trieCachePath string) err log.Info("Loaded state bloom filter", "path", stateBloomPath) - // Before start the pruning, delete the clean trie cache first. - // It's necessary otherwise in the next restart we will hit the - // deleted state root in the "clean cache" so that the incomplete - // state is picked for usage. - deleteCleanTrieCache(trieCachePath) - // All the state roots of the middle layers should be forcibly pruned, // otherwise the dangling state will be left. var ( @@ -464,7 +451,6 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error { if err != nil { return err } - accIter, err := t.NodeIterator(nil) if err != nil { return err @@ -491,7 +477,6 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error { if err != nil { return err } - storageIter, err := storageTrie.NodeIterator(nil) if err != nil { return err @@ -551,24 +536,3 @@ func findBloomFilter(datadir string) (string, common.Hash, error) { return stateBloomPath, stateBloomRoot, nil } - -const warningLog = ` - -WARNING! - -The clean trie cache is not found. Please delete it by yourself after the -pruning. Remember don't start the Geth without deleting the clean trie cache -otherwise the entire database may be damaged! - -Check the command description "geth snapshot prune-state --help" for more details. -` - -func deleteCleanTrieCache(path string) { - if !common.FileExist(path) { - log.Warn(warningLog) - return - } - - os.RemoveAll(path) - log.Info("Deleted trie clean cache", "path", path) -} diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index e91d80b811..c8907bc9b3 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -52,6 +52,10 @@ type Config struct { NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls) EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages ExtraEips []int // Additional EIPS that are to be enabled + + // parallel EVM configs + ParallelEnable bool + ParallelSpeculativeProcesses int } // ScopeContext contains the things that are per-call, such as stack and memory, diff --git a/eth/backend.go b/eth/backend.go index 1afb2c47b4..5c440aa64b 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -143,7 +143,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if err != nil { return nil, err } - if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb, ""); err != nil { + if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb); err != nil { log.Error("Failed to recover state", "error", err) } @@ -236,7 +236,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { // check if Parallel EVM is enabled // if enabled, use parallel state processor if config.ParallelEVM.Enable { - eth.blockchain, err = core.NewParallelBlockChain(chainDb, cacheConfig, config.Genesis, &overrides, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, checker, config.ParallelEVM.SpeculativeProcesses) + eth.blockchain, err = core.NewParallelBlockChain(chainDb, cacheConfig, config.Genesis, &overrides, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, checker) } else { eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, config.Genesis, &overrides, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, checker) } diff --git a/miner/worker_test.go b/miner/worker_test.go index 88f7924b00..58a5ff2948 100644 --- a/miner/worker_test.go +++ b/miner/worker_test.go @@ -949,7 +949,7 @@ func BenchmarkBorMiningBlockSTMMetadata(b *testing.B) { db2 := rawdb.NewMemoryDatabase() back.genesis.MustCommit(db2) - chain, _ := core.NewParallelBlockChain(db2, nil, back.genesis, nil, engine, vm.Config{}, nil, nil, nil, 8) + chain, _ := core.NewParallelBlockChain(db2, nil, back.genesis, nil, engine, vm.Config{ParallelEnable: true, ParallelSpeculativeProcesses: 8}, nil, nil, nil) defer chain.Stop() // Ignore empty commit here for less noise. diff --git a/packaging/templates/package_scripts/control b/packaging/templates/package_scripts/control index 5b249281c7..e4f0463fc2 100644 --- a/packaging/templates/package_scripts/control +++ b/packaging/templates/package_scripts/control @@ -1,5 +1,5 @@ Source: bor -Version: 1.2.1 +Version: 1.2.0-beta Section: develop Priority: standard Maintainer: Polygon diff --git a/packaging/templates/package_scripts/control.arm64 b/packaging/templates/package_scripts/control.arm64 index d6ea25f3b8..04a59510f7 100644 --- a/packaging/templates/package_scripts/control.arm64 +++ b/packaging/templates/package_scripts/control.arm64 @@ -1,5 +1,5 @@ Source: bor -Version: 1.2.1 +Version: 1.2.0-beta Section: develop Priority: standard Maintainer: Polygon diff --git a/packaging/templates/package_scripts/control.profile.amd64 b/packaging/templates/package_scripts/control.profile.amd64 index 5272652792..f83b21148d 100644 --- a/packaging/templates/package_scripts/control.profile.amd64 +++ b/packaging/templates/package_scripts/control.profile.amd64 @@ -1,5 +1,5 @@ Source: bor-profile -Version: 1.2.1 +Version: 1.2.0-beta Section: develop Priority: standard Maintainer: Polygon diff --git a/packaging/templates/package_scripts/control.profile.arm64 b/packaging/templates/package_scripts/control.profile.arm64 index d229ab68dc..e39ecda6d1 100644 --- a/packaging/templates/package_scripts/control.profile.arm64 +++ b/packaging/templates/package_scripts/control.profile.arm64 @@ -1,5 +1,5 @@ Source: bor-profile -Version: 1.2.1 +Version: 1.2.0-beta Section: develop Priority: standard Maintainer: Polygon diff --git a/packaging/templates/package_scripts/control.validator b/packaging/templates/package_scripts/control.validator index 41c1e7f3c3..f201053311 100644 --- a/packaging/templates/package_scripts/control.validator +++ b/packaging/templates/package_scripts/control.validator @@ -1,5 +1,5 @@ Source: bor-profile -Version: 1.2.1 +Version: 1.2.0-beta Section: develop Priority: standard Maintainer: Polygon diff --git a/packaging/templates/package_scripts/control.validator.arm64 b/packaging/templates/package_scripts/control.validator.arm64 index 7d94bb7cbe..fa5360da07 100644 --- a/packaging/templates/package_scripts/control.validator.arm64 +++ b/packaging/templates/package_scripts/control.validator.arm64 @@ -1,5 +1,5 @@ Source: bor-profile -Version: 1.2.1 +Version: 1.2.0-beta Section: develop Priority: standard Maintainer: Polygon diff --git a/params/version.go b/params/version.go index 39e283fb0d..d942ddf483 100644 --- a/params/version.go +++ b/params/version.go @@ -21,10 +21,10 @@ import ( ) const ( - VersionMajor = 1 // Major version component of the current release - VersionMinor = 2 // Minor version component of the current release - VersionPatch = 1 // Patch version component of the current release - VersionMeta = "" // Version metadata to append to the version string + VersionMajor = 1 // Major version component of the current release + VersionMinor = 2 // Minor version component of the current release + VersionPatch = 0 // Patch version component of the current release + VersionMeta = "beta" // Version metadata to append to the version string ) var GitCommit string