mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
Revert "fix bug: should use Lock when mutating the flag" (#1140)
This commit is contained in:
parent
b15e2dc162
commit
6801260e9a
16 changed files with 74 additions and 83 deletions
6
cmd/evm/testdata/3/readme.md
vendored
6
cmd/evm/testdata/3/readme.md
vendored
|
|
@ -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`.
|
||||
|
|
|
|||
6
cmd/evm/testdata/4/readme.md
vendored
6
cmd/evm/testdata/4/readme.md
vendored
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source: bor
|
||||
Version: 1.2.1
|
||||
Version: 1.2.0-beta
|
||||
Section: develop
|
||||
Priority: standard
|
||||
Maintainer: Polygon <release-team@polygon.technology>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source: bor
|
||||
Version: 1.2.1
|
||||
Version: 1.2.0-beta
|
||||
Section: develop
|
||||
Priority: standard
|
||||
Maintainer: Polygon <release-team@polygon.technology>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source: bor-profile
|
||||
Version: 1.2.1
|
||||
Version: 1.2.0-beta
|
||||
Section: develop
|
||||
Priority: standard
|
||||
Maintainer: Polygon <release-team@polygon.technology>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source: bor-profile
|
||||
Version: 1.2.1
|
||||
Version: 1.2.0-beta
|
||||
Section: develop
|
||||
Priority: standard
|
||||
Maintainer: Polygon <release-team@polygon.technology>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source: bor-profile
|
||||
Version: 1.2.1
|
||||
Version: 1.2.0-beta
|
||||
Section: develop
|
||||
Priority: standard
|
||||
Maintainer: Polygon <release-team@polygon.technology>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source: bor-profile
|
||||
Version: 1.2.1
|
||||
Version: 1.2.0-beta
|
||||
Section: develop
|
||||
Priority: standard
|
||||
Maintainer: Polygon <release-team@polygon.technology>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue