Revert "fix bug: should use Lock when mutating the flag" (#1140)

This commit is contained in:
Pratik Patil 2024-01-22 19:00:20 +05:30 committed by GitHub
parent b15e2dc162
commit 6801260e9a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 74 additions and 83 deletions

View file

@ -1,2 +1,6 @@
<<<<<<< HEAD
These files examplify a transition where a transaction (executed on block 5) requests 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
>>>>>>> bed84606583893fdb698cc1b5058cc47b4dbd837
the blockhash for block `1`. the blockhash for block `1`.

View file

@ -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 These files exemplify a transition where a transaction (executed on block 5) requests
>>>>>>> bed84606583893fdb698cc1b5058cc47b4dbd837
the blockhash for block `4`, but where the hash for that block is missing. 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`. It's expected that executing these should cause `exit` with errorcode `4`.

View file

@ -241,7 +241,6 @@ type BlockChain struct {
prefetcher Prefetcher prefetcher Prefetcher
processor Processor // Block transaction processor interface processor Processor // Block transaction processor interface
parallelProcessor Processor // Parallel block transaction processor interface parallelProcessor Processor // Parallel block transaction processor interface
parallelSpeculativeProcesses int // Number of parallel speculative processes
forker *ForkChoice forker *ForkChoice
vmConfig vm.Config vmConfig vm.Config
@ -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 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 // the head block (ethash cache or clique voting snapshot). Might as well do
// it in advance. // 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 // 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 { 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 // 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) bc, err := NewBlockChain(db, cacheConfig, genesis, overrides, engine, vmConfig, shouldPreserve, txLookupLimit, checker)
if err != nil { if err != nil {
@ -502,7 +500,6 @@ func NewParallelBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis
} }
bc.parallelProcessor = NewParallelStateProcessor(chainConfig, bc, engine) bc.parallelProcessor = NewParallelStateProcessor(chainConfig, bc, engine)
bc.parallelSpeculativeProcesses = numprocs
return bc, nil 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) 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 // 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. // transactions and probabilistically some of the account/storage trie nodes.
var followupInterrupt atomic.Bool var followupInterrupt atomic.Bool

View file

@ -121,24 +121,35 @@ func (mv *MVHashMap) Write(k Key, v Version, data interface{}) {
return return
}) })
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() cells.rw.Lock()
if ci, ok := cells.tm.Get(v.TxnIndex); !ok { if ci, ok = cells.tm.Get(v.TxnIndex); !ok {
cells.tm.Put(v.TxnIndex, &WriteCell{ cells.tm.Put(v.TxnIndex, &WriteCell{
flag: FlagDone, flag: FlagDone,
incarnation: v.Incarnation, incarnation: v.Incarnation,
data: data, data: data,
}) })
} else { } else {
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).flag = FlagDone
ci.(*WriteCell).incarnation = v.Incarnation ci.(*WriteCell).incarnation = v.Incarnation
ci.(*WriteCell).data = data ci.(*WriteCell).data = data
} }
cells.rw.Unlock() cells.rw.Unlock()
} }
}
func (mv *MVHashMap) ReadStorage(k Key, fallBack func() any) any { func (mv *MVHashMap) ReadStorage(k Key, fallBack func() any) any {
data, ok := mv.s.Load(string(k[:])) data, ok := mv.s.Load(string(k[:]))
@ -155,13 +166,13 @@ func (mv *MVHashMap) MarkEstimate(k Key, txIdx int) {
panic(fmt.Errorf("path must already exist")) panic(fmt.Errorf("path must already exist"))
}) })
cells.rw.Lock() cells.rw.RLock()
if ci, ok := cells.tm.Get(txIdx); !ok { 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())) 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 { } else {
ci.(*WriteCell).flag = FlagEstimate ci.(*WriteCell).flag = FlagEstimate
} }
cells.rw.Unlock() cells.rw.RUnlock()
} }
func (mv *MVHashMap) Delete(k Key, txIdx int) { 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() cells.rw.RLock()
fk, fv := cells.tm.Floor(txIdx - 1) fk, fv := cells.tm.Floor(txIdx - 1)
cells.rw.RUnlock()
if fk != nil && fv != nil { if fk != nil && fv != nil {
c := fv.(*WriteCell) c := fv.(*WriteCell)
@ -242,8 +253,6 @@ func (mv *MVHashMap) Read(k Key, txIdx int) (res MVReadResult) {
} }
} }
cells.rw.RUnlock()
return return
} }

View file

@ -364,7 +364,7 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat
backupStateDB := statedb.Copy() backupStateDB := statedb.Copy()
profile := false 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 { if err == nil && profile && result.Deps != nil {
_, weight := result.Deps.LongestPath(*result.Stats) _, weight := result.Deps.LongestPath(*result.Stats)
@ -398,7 +398,7 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat
t.totalUsedGas = usedGas t.totalUsedGas = usedGas
} }
_, err = blockstm.ExecuteParallel(tasks, false, metadata, p.bc.parallelSpeculativeProcesses, interruptCtx) _, err = blockstm.ExecuteParallel(tasks, false, metadata, cfg.ParallelSpeculativeProcesses, interruptCtx)
break break
} }

View file

@ -57,7 +57,6 @@ const (
// Config includes all the configurations for pruning. // Config includes all the configurations for pruning.
type Config struct { type Config struct {
Datadir string // The directory of the state database 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 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{}) { 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 // If the target state root is not specified, use the HEAD-127 as the
// target. The reason for picking it is: // 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 // is the presence of root can indicate the presence of the
// entire trie. // entire trie.
if !rawdb.HasLegacyTrieNode(p.db, root) { if !rawdb.HasLegacyTrieNode(p.db, root) {
// The special case is for clique based networks(goerli and // The special case is for clique based networks(goerli
// some other private networks), it's possible that two // and some other private networks), it's possible that two
// consecutive blocks will have same root. In this case snapshot // consecutive blocks will have same root. In this case snapshot
// difflayer won't be created. So HEAD-127 may not paired with // difflayer won't be created. So HEAD-127 may not paired with
// head-127 layer. Instead the paired layer is higher than the // 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) 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, // All the state roots of the middle layer should be forcibly pruned,
// otherwise the dangling state will be left. // otherwise the dangling state will be left.
middleRoots := make(map[common.Hash]struct{}) 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 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 // pruning **has to be resumed**. Otherwise a lot of dangling nodes may be left
// in the disk. // 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) stateBloomPath, stateBloomRoot, err := findBloomFilter(datadir)
if err != nil { if err != nil {
return err return err
@ -416,12 +409,6 @@ func RecoverPruning(datadir string, db ethdb.Database, trieCachePath string) err
log.Info("Loaded state bloom filter", "path", stateBloomPath) 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, // All the state roots of the middle layers should be forcibly pruned,
// otherwise the dangling state will be left. // otherwise the dangling state will be left.
var ( var (
@ -464,7 +451,6 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
if err != nil { if err != nil {
return err return err
} }
accIter, err := t.NodeIterator(nil) accIter, err := t.NodeIterator(nil)
if err != nil { if err != nil {
return err return err
@ -491,7 +477,6 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
if err != nil { if err != nil {
return err return err
} }
storageIter, err := storageTrie.NodeIterator(nil) storageIter, err := storageTrie.NodeIterator(nil)
if err != nil { if err != nil {
return err return err
@ -551,24 +536,3 @@ func findBloomFilter(datadir string) (string, common.Hash, error) {
return stateBloomPath, stateBloomRoot, nil 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)
}

View file

@ -52,6 +52,10 @@ type Config struct {
NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls) NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls)
EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages
ExtraEips []int // Additional EIPS that are to be enabled 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, // ScopeContext contains the things that are per-call, such as stack and memory,

View file

@ -143,7 +143,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
if err != nil { if err != nil {
return nil, err 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) 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 // check if Parallel EVM is enabled
// if enabled, use parallel state processor // if enabled, use parallel state processor
if config.ParallelEVM.Enable { 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 { } else {
eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, config.Genesis, &overrides, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, checker) eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, config.Genesis, &overrides, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, checker)
} }

View file

@ -949,7 +949,7 @@ func BenchmarkBorMiningBlockSTMMetadata(b *testing.B) {
db2 := rawdb.NewMemoryDatabase() db2 := rawdb.NewMemoryDatabase()
back.genesis.MustCommit(db2) 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() defer chain.Stop()
// Ignore empty commit here for less noise. // Ignore empty commit here for less noise.

View file

@ -1,5 +1,5 @@
Source: bor Source: bor
Version: 1.2.1 Version: 1.2.0-beta
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor Source: bor
Version: 1.2.1 Version: 1.2.0-beta
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor-profile Source: bor-profile
Version: 1.2.1 Version: 1.2.0-beta
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor-profile Source: bor-profile
Version: 1.2.1 Version: 1.2.0-beta
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor-profile Source: bor-profile
Version: 1.2.1 Version: 1.2.0-beta
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor-profile Source: bor-profile
Version: 1.2.1 Version: 1.2.0-beta
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -23,8 +23,8 @@ import (
const ( const (
VersionMajor = 1 // Major version component of the current release VersionMajor = 1 // Major version component of the current release
VersionMinor = 2 // Minor version component of the current release VersionMinor = 2 // Minor version component of the current release
VersionPatch = 1 // Patch version component of the current release VersionPatch = 0 // Patch version component of the current release
VersionMeta = "" // Version metadata to append to the version string VersionMeta = "beta" // Version metadata to append to the version string
) )
var GitCommit string var GitCommit string