mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 22:56:43 +00:00
Merge branch 'develop' into shivam/upstream-geth-1.13.5
This commit is contained in:
commit
4008d5efe8
90 changed files with 348 additions and 650 deletions
|
|
@ -1677,7 +1677,7 @@ var bindTests = []struct {
|
||||||
}
|
}
|
||||||
sim.Commit()
|
sim.Commit()
|
||||||
|
|
||||||
// This test the existence of the free retreiver call for view and pure functions
|
// This test the existence of the free retriever call for view and pure functions
|
||||||
if num, err := pav.PureFunc(nil); err != nil {
|
if num, err := pav.PureFunc(nil); err != nil {
|
||||||
t.Fatalf("Failed to call anonymous field retriever: %v", err)
|
t.Fatalf("Failed to call anonymous field retriever: %v", err)
|
||||||
} else if num.Cmp(big.NewInt(42)) != 0 {
|
} else if num.Cmp(big.NewInt(42)) != 0 {
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ func (w *watcher) loop() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Filsystem watcher error", "err", err)
|
log.Info("Filesystem watcher error", "err", err)
|
||||||
case <-debounce.C:
|
case <-debounce.C:
|
||||||
w.ac.scanAccounts()
|
w.ac.scanAccounts()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ func (hub *Hub) refreshWallets() {
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Card connected, start tracking in amongs the wallets
|
// Card connected, start tracking in amongst the wallets
|
||||||
hub.wallets[reader] = wallet
|
hub.wallets[reader] = wallet
|
||||||
events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletArrived})
|
events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletArrived})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
"bor": {
|
"bor": {
|
||||||
"jaipurBlock": 23850000,
|
"jaipurBlock": 23850000,
|
||||||
"delhiBlock": 38189056,
|
"delhiBlock": 38189056,
|
||||||
"parallelUniverseBlock": 0,
|
|
||||||
"indoreBlock": 44934656,
|
"indoreBlock": 44934656,
|
||||||
"stateSyncConfirmationDelay": {
|
"stateSyncConfirmationDelay": {
|
||||||
"44934656": 128
|
"44934656": 128
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
"bor": {
|
"bor": {
|
||||||
"jaipurBlock": 22770000,
|
"jaipurBlock": 22770000,
|
||||||
"delhiBlock": 29638656,
|
"delhiBlock": 29638656,
|
||||||
"parallelUniverseBlock": 0,
|
|
||||||
"indoreBlock": 37075456,
|
"indoreBlock": 37075456,
|
||||||
"stateSyncConfirmationDelay": {
|
"stateSyncConfirmationDelay": {
|
||||||
"37075456": 128
|
"37075456": 128
|
||||||
|
|
|
||||||
6
cmd/evm/testdata/3/readme.md
vendored
6
cmd/evm/testdata/3/readme.md
vendored
|
|
@ -1,6 +1,2 @@
|
||||||
<<<<<<< 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
|
||||||
=======
|
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,7 +1,3 @@
|
||||||
<<<<<<< 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`.
|
||||||
|
|
|
||||||
|
|
@ -353,7 +353,7 @@ func (c *Bor) verifyHeader(chain consensus.ChainHeaderReader, header *types.Head
|
||||||
isSprintEnd := IsSprintStart(number+1, c.config.CalculateSprint(number))
|
isSprintEnd := IsSprintStart(number+1, c.config.CalculateSprint(number))
|
||||||
|
|
||||||
// Ensure that the extra-data contains a signer list on checkpoint, but none otherwise
|
// Ensure that the extra-data contains a signer list on checkpoint, but none otherwise
|
||||||
signersBytes := len(header.GetValidatorBytes(c.config))
|
signersBytes := len(header.GetValidatorBytes(c.chainConfig))
|
||||||
|
|
||||||
if !isSprintEnd && signersBytes != 0 {
|
if !isSprintEnd && signersBytes != 0 {
|
||||||
return errExtraValidators
|
return errExtraValidators
|
||||||
|
|
@ -472,7 +472,7 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainHeaderReader, header *t
|
||||||
|
|
||||||
sort.Sort(valset.ValidatorsByAddress(newValidators))
|
sort.Sort(valset.ValidatorsByAddress(newValidators))
|
||||||
|
|
||||||
headerVals, err := valset.ParseValidators(header.GetValidatorBytes(c.config))
|
headerVals, err := valset.ParseValidators(header.GetValidatorBytes(c.chainConfig))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -490,7 +490,7 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainHeaderReader, header *t
|
||||||
|
|
||||||
// verify the validator list in the last sprint block
|
// verify the validator list in the last sprint block
|
||||||
if IsSprintStart(number, c.config.CalculateSprint(number)) {
|
if IsSprintStart(number, c.config.CalculateSprint(number)) {
|
||||||
parentValidatorBytes := parent.GetValidatorBytes(c.config)
|
parentValidatorBytes := parent.GetValidatorBytes(c.chainConfig)
|
||||||
validatorsBytes := make([]byte, len(snap.ValidatorSet.Validators)*validatorHeaderBytesLength)
|
validatorsBytes := make([]byte, len(snap.ValidatorSet.Validators)*validatorHeaderBytesLength)
|
||||||
|
|
||||||
currentValidators := snap.ValidatorSet.Copy().Validators
|
currentValidators := snap.ValidatorSet.Copy().Validators
|
||||||
|
|
@ -521,7 +521,7 @@ func (c *Bor) snapshot(chain consensus.ChainHeaderReader, number uint64, hash co
|
||||||
val := valset.NewValidator(signer, 1000)
|
val := valset.NewValidator(signer, 1000)
|
||||||
validatorset := valset.NewValidatorSet([]*valset.Validator{val})
|
validatorset := valset.NewValidatorSet([]*valset.Validator{val})
|
||||||
|
|
||||||
snapshot := newSnapshot(c.config, c.signatures, number, hash, validatorset.Validators)
|
snapshot := newSnapshot(c.chainConfig, c.signatures, number, hash, validatorset.Validators)
|
||||||
|
|
||||||
return snapshot, nil
|
return snapshot, nil
|
||||||
}
|
}
|
||||||
|
|
@ -541,7 +541,7 @@ func (c *Bor) snapshot(chain consensus.ChainHeaderReader, number uint64, hash co
|
||||||
|
|
||||||
// If an on-disk checkpoint snapshot can be found, use that
|
// If an on-disk checkpoint snapshot can be found, use that
|
||||||
if number%checkpointInterval == 0 {
|
if number%checkpointInterval == 0 {
|
||||||
if s, err := loadSnapshot(c.config, c.signatures, c.db, hash); err == nil {
|
if s, err := loadSnapshot(c.chainConfig, c.config, c.signatures, c.db, hash); err == nil {
|
||||||
log.Trace("Loaded snapshot from disk", "number", number, "hash", hash)
|
log.Trace("Loaded snapshot from disk", "number", number, "hash", hash)
|
||||||
|
|
||||||
snap = s
|
snap = s
|
||||||
|
|
@ -570,7 +570,7 @@ func (c *Bor) snapshot(chain consensus.ChainHeaderReader, number uint64, hash co
|
||||||
}
|
}
|
||||||
|
|
||||||
// new snap shot
|
// new snap shot
|
||||||
snap = newSnapshot(c.config, c.signatures, number, hash, validators)
|
snap = newSnapshot(c.chainConfig, c.signatures, number, hash, validators)
|
||||||
if err := snap.store(c.db); err != nil {
|
if err := snap.store(c.db); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -742,7 +742,7 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) e
|
||||||
// sort validator by address
|
// sort validator by address
|
||||||
sort.Sort(valset.ValidatorsByAddress(newValidators))
|
sort.Sort(valset.ValidatorsByAddress(newValidators))
|
||||||
|
|
||||||
if c.config.IsParallelUniverse(header.Number) {
|
if c.chainConfig.IsCancun(header.Number) {
|
||||||
var tempValidatorBytes []byte
|
var tempValidatorBytes []byte
|
||||||
|
|
||||||
for _, validator := range newValidators {
|
for _, validator := range newValidators {
|
||||||
|
|
@ -766,7 +766,7 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) e
|
||||||
header.Extra = append(header.Extra, validator.HeaderBytes()...)
|
header.Extra = append(header.Extra, validator.HeaderBytes()...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if c.config.IsParallelUniverse(header.Number) {
|
} else if c.chainConfig.IsCancun(header.Number) {
|
||||||
blockExtraData := &types.BlockExtraData{
|
blockExtraData := &types.BlockExtraData{
|
||||||
ValidatorBytes: nil,
|
ValidatorBytes: nil,
|
||||||
TxDependency: nil,
|
TxDependency: nil,
|
||||||
|
|
@ -883,10 +883,6 @@ func (c *Bor) changeContractCodeIfNeeded(headerNumber uint64, state *state.State
|
||||||
for addr, account := range allocs {
|
for addr, account := range allocs {
|
||||||
log.Info("change contract code", "address", addr)
|
log.Info("change contract code", "address", addr)
|
||||||
state.SetCode(addr, account.Code)
|
state.SetCode(addr, account.Code)
|
||||||
|
|
||||||
if state.GetBalance(addr).Cmp(big.NewInt(0)) == 0 {
|
|
||||||
state.SetBalance(addr, account.Balance)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,6 @@ func TestGenesisContractChange(t *testing.T) {
|
||||||
"balance": "0x1000",
|
"balance": "0x1000",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"6": map[string]interface{}{
|
|
||||||
addr0.Hex(): map[string]interface{}{
|
|
||||||
"code": hexutil.Bytes{0x1, 0x4},
|
|
||||||
"balance": "0x2000",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -93,35 +87,24 @@ func TestGenesisContractChange(t *testing.T) {
|
||||||
|
|
||||||
root := genesis.Root()
|
root := genesis.Root()
|
||||||
|
|
||||||
// code does not change, balance remains 0
|
// code does not change
|
||||||
root, statedb = addBlock(root, 1)
|
root, statedb = addBlock(root, 1)
|
||||||
require.Equal(t, statedb.GetCode(addr0), []byte{0x1, 0x1})
|
require.Equal(t, statedb.GetCode(addr0), []byte{0x1, 0x1})
|
||||||
require.Equal(t, statedb.GetBalance(addr0), big.NewInt(0))
|
|
||||||
|
|
||||||
// code changes 1st time, balance remains 0
|
// code changes 1st time
|
||||||
root, statedb = addBlock(root, 2)
|
root, statedb = addBlock(root, 2)
|
||||||
require.Equal(t, statedb.GetCode(addr0), []byte{0x1, 0x2})
|
require.Equal(t, statedb.GetCode(addr0), []byte{0x1, 0x2})
|
||||||
require.Equal(t, statedb.GetBalance(addr0), big.NewInt(0))
|
|
||||||
|
|
||||||
// code same as 1st change, balance remains 0
|
// code same as 1st change
|
||||||
root, statedb = addBlock(root, 3)
|
root, statedb = addBlock(root, 3)
|
||||||
require.Equal(t, statedb.GetCode(addr0), []byte{0x1, 0x2})
|
require.Equal(t, statedb.GetCode(addr0), []byte{0x1, 0x2})
|
||||||
|
|
||||||
|
// code changes 2nd time
|
||||||
|
_, statedb = addBlock(root, 4)
|
||||||
|
require.Equal(t, statedb.GetCode(addr0), []byte{0x1, 0x3})
|
||||||
|
|
||||||
|
// make sure balance change DOES NOT take effect
|
||||||
require.Equal(t, statedb.GetBalance(addr0), big.NewInt(0))
|
require.Equal(t, statedb.GetBalance(addr0), big.NewInt(0))
|
||||||
|
|
||||||
// code changes 2nd time, balance updates to 4096
|
|
||||||
root, statedb = addBlock(root, 4)
|
|
||||||
require.Equal(t, statedb.GetCode(addr0), []byte{0x1, 0x3})
|
|
||||||
require.Equal(t, statedb.GetBalance(addr0), big.NewInt(4096))
|
|
||||||
|
|
||||||
// code same as 2nd change, balance remains 4096
|
|
||||||
root, statedb = addBlock(root, 5)
|
|
||||||
require.Equal(t, statedb.GetCode(addr0), []byte{0x1, 0x3})
|
|
||||||
require.Equal(t, statedb.GetBalance(addr0), big.NewInt(4096))
|
|
||||||
|
|
||||||
// code changes 3rd time, balance remains 4096
|
|
||||||
_, statedb = addBlock(root, 6)
|
|
||||||
require.Equal(t, statedb.GetCode(addr0), []byte{0x1, 0x4})
|
|
||||||
require.Equal(t, statedb.GetBalance(addr0), big.NewInt(4096))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEncodeSigHeaderJaipur(t *testing.T) {
|
func TestEncodeSigHeaderJaipur(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"path"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -420,7 +421,7 @@ func makeURL(urlString, rawPath, rawQuery string) (*url.URL, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
u.Path = rawPath
|
u.Path = path.Join(u.Path, rawPath)
|
||||||
u.RawQuery = rawQuery
|
u.RawQuery = rawQuery
|
||||||
|
|
||||||
return u, err
|
return u, err
|
||||||
|
|
|
||||||
|
|
@ -256,8 +256,8 @@ func TestFetchShutdown(t *testing.T) {
|
||||||
|
|
||||||
// Expect this to fail due to timeout
|
// Expect this to fail due to timeout
|
||||||
_, err = client.FetchCheckpoint(ctx, -1)
|
_, err = client.FetchCheckpoint(ctx, -1)
|
||||||
require.Equal(t, "context deadline exceeded", err.Error(), "expect the function error to be a context deadline exeeded error")
|
require.Equal(t, "context deadline exceeded", err.Error(), "expect the function error to be a context deadline exceeded error")
|
||||||
require.Equal(t, "context deadline exceeded", ctx.Err().Error(), "expect the ctx error to be a context deadline exeeded error")
|
require.Equal(t, "context deadline exceeded", ctx.Err().Error(), "expect the ctx error to be a context deadline exceeded error")
|
||||||
|
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
|
|
@ -346,7 +346,7 @@ func TestContext(t *testing.T) {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
// Expect this to never occur, throw explicit error
|
// Expect this to never occur, throw explicit error
|
||||||
errCh <- errors.New("unexpectecd call to `ctx.Done()`")
|
errCh <- errors.New("unexpected call to `ctx.Done()`")
|
||||||
case <-time.After(2 * time.Second):
|
case <-time.After(2 * time.Second):
|
||||||
// Case for safely exiting the tests
|
// Case for safely exiting the tests
|
||||||
errCh <- nil
|
errCh <- nil
|
||||||
|
|
@ -399,7 +399,7 @@ func TestSpanURL(t *testing.T) {
|
||||||
const expected = "http://bor0/bor/span/1"
|
const expected = "http://bor0/bor/span/1"
|
||||||
|
|
||||||
if url.String() != expected {
|
if url.String() != expected {
|
||||||
t.Fatalf("expected URL %q, got %q", url.String(), expected)
|
t.Fatalf("expected URL %q, got %q", expected, url.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -414,6 +414,6 @@ func TestStateSyncURL(t *testing.T) {
|
||||||
const expected = "http://bor0/clerk/event-record/list?from-id=10&to-time=100&limit=50"
|
const expected = "http://bor0/clerk/event-record/list?from-id=10&to-time=100&limit=50"
|
||||||
|
|
||||||
if url.String() != expected {
|
if url.String() != expected {
|
||||||
t.Fatalf("expected URL %q, got %q", url.String(), expected)
|
t.Fatalf("expected URL %q, got %q", expected, url.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,9 @@ import (
|
||||||
|
|
||||||
// Snapshot is the state of the authorization voting at a given point in time.
|
// Snapshot is the state of the authorization voting at a given point in time.
|
||||||
type Snapshot struct {
|
type Snapshot struct {
|
||||||
config *params.BorConfig // Consensus engine parameters to fine tune behavior
|
chainConfig *params.ChainConfig
|
||||||
sigcache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover
|
|
||||||
|
sigcache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover
|
||||||
|
|
||||||
Number uint64 `json:"number"` // Block number where the snapshot was created
|
Number uint64 `json:"number"` // Block number where the snapshot was created
|
||||||
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
|
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
|
||||||
|
|
@ -28,14 +29,14 @@ type Snapshot struct {
|
||||||
// method does not initialize the set of recent signers, so only ever use if for
|
// method does not initialize the set of recent signers, so only ever use if for
|
||||||
// the genesis block.
|
// the genesis block.
|
||||||
func newSnapshot(
|
func newSnapshot(
|
||||||
config *params.BorConfig,
|
chainConfig *params.ChainConfig,
|
||||||
sigcache *lru.ARCCache,
|
sigcache *lru.ARCCache,
|
||||||
number uint64,
|
number uint64,
|
||||||
hash common.Hash,
|
hash common.Hash,
|
||||||
validators []*valset.Validator,
|
validators []*valset.Validator,
|
||||||
) *Snapshot {
|
) *Snapshot {
|
||||||
snap := &Snapshot{
|
snap := &Snapshot{
|
||||||
config: config,
|
chainConfig: chainConfig,
|
||||||
sigcache: sigcache,
|
sigcache: sigcache,
|
||||||
Number: number,
|
Number: number,
|
||||||
Hash: hash,
|
Hash: hash,
|
||||||
|
|
@ -47,7 +48,7 @@ func newSnapshot(
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadSnapshot loads an existing snapshot from the database.
|
// loadSnapshot loads an existing snapshot from the database.
|
||||||
func loadSnapshot(config *params.BorConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*Snapshot, error) {
|
func loadSnapshot(chainConfig *params.ChainConfig, config *params.BorConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*Snapshot, error) {
|
||||||
blob, err := db.Get(append([]byte("bor-"), hash[:]...))
|
blob, err := db.Get(append([]byte("bor-"), hash[:]...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -61,7 +62,7 @@ func loadSnapshot(config *params.BorConfig, sigcache *lru.ARCCache, db ethdb.Dat
|
||||||
|
|
||||||
snap.ValidatorSet.UpdateValidatorMap()
|
snap.ValidatorSet.UpdateValidatorMap()
|
||||||
|
|
||||||
snap.config = config
|
snap.chainConfig = chainConfig
|
||||||
snap.sigcache = sigcache
|
snap.sigcache = sigcache
|
||||||
|
|
||||||
// update total voting power
|
// update total voting power
|
||||||
|
|
@ -85,7 +86,7 @@ func (s *Snapshot) store(db ethdb.Database) error {
|
||||||
// copy creates a deep copy of the snapshot, though not the individual votes.
|
// copy creates a deep copy of the snapshot, though not the individual votes.
|
||||||
func (s *Snapshot) copy() *Snapshot {
|
func (s *Snapshot) copy() *Snapshot {
|
||||||
cpy := &Snapshot{
|
cpy := &Snapshot{
|
||||||
config: s.config,
|
chainConfig: s.chainConfig,
|
||||||
sigcache: s.sigcache,
|
sigcache: s.sigcache,
|
||||||
Number: s.Number,
|
Number: s.Number,
|
||||||
Hash: s.Hash,
|
Hash: s.Hash,
|
||||||
|
|
@ -122,12 +123,12 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
|
||||||
number := header.Number.Uint64()
|
number := header.Number.Uint64()
|
||||||
|
|
||||||
// Delete the oldest signer from the recent list to allow it signing again
|
// Delete the oldest signer from the recent list to allow it signing again
|
||||||
if number >= s.config.CalculateSprint(number) {
|
if number >= s.chainConfig.Bor.CalculateSprint(number) {
|
||||||
delete(snap.Recents, number-s.config.CalculateSprint(number))
|
delete(snap.Recents, number-s.chainConfig.Bor.CalculateSprint(number))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve the authorization key and check against signers
|
// Resolve the authorization key and check against signers
|
||||||
signer, err := ecrecover(header, s.sigcache, s.config)
|
signer, err := ecrecover(header, s.sigcache, s.chainConfig.Bor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -145,12 +146,12 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
|
||||||
snap.Recents[number] = signer
|
snap.Recents[number] = signer
|
||||||
|
|
||||||
// change validator set and change proposer
|
// change validator set and change proposer
|
||||||
if number > 0 && (number+1)%s.config.CalculateSprint(number) == 0 {
|
if number > 0 && (number+1)%s.chainConfig.Bor.CalculateSprint(number) == 0 {
|
||||||
if err := validateHeaderExtraField(header.Extra); err != nil {
|
if err := validateHeaderExtraField(header.Extra); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
validatorBytes := header.GetValidatorBytes(s.config)
|
validatorBytes := header.GetValidatorBytes(s.chainConfig)
|
||||||
|
|
||||||
// get validators from headers and use that for new validator set
|
// get validators from headers and use that for new validator set
|
||||||
newVals, _ := valset.ParseValidators(validatorBytes)
|
newVals, _ := valset.ParseValidators(validatorBytes)
|
||||||
|
|
|
||||||
|
|
@ -451,7 +451,8 @@ 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.
|
||||||
bc.engine.VerifyHeader(bc, bc.CurrentHeader())
|
// BOR - commented out intentionally
|
||||||
|
// 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 {
|
||||||
|
|
@ -2111,7 +2112,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
||||||
// The chain importer is starting and stopping trie prefetchers. If a bad
|
// The chain importer is starting and stopping trie prefetchers. If a bad
|
||||||
// block or other error is hit however, an early return may not properly
|
// block or other error is hit however, an early return may not properly
|
||||||
// terminate the background threads. This defer ensures that we clean up
|
// terminate the background threads. This defer ensures that we clean up
|
||||||
// and dangling prefetcher, without defering each and holding on live refs.
|
// and dangling prefetcher, without deferring each and holding on live refs.
|
||||||
if activeState != nil {
|
if activeState != nil {
|
||||||
activeState.StopPrefetcher()
|
activeState.StopPrefetcher()
|
||||||
}
|
}
|
||||||
|
|
@ -2198,15 +2199,6 @@ 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
|
||||||
|
|
@ -2763,6 +2755,12 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
||||||
|
|
||||||
log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain))
|
log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain))
|
||||||
}
|
}
|
||||||
|
// Reset the tx lookup cache in case to clear stale txlookups.
|
||||||
|
// This is done before writing any new chain data to avoid the
|
||||||
|
// weird scenario that canonical chain is changed while the
|
||||||
|
// stale lookups are still cached.
|
||||||
|
bc.txLookupCache.Purge()
|
||||||
|
|
||||||
// Insert the new chain(except the head block(reverse order)),
|
// Insert the new chain(except the head block(reverse order)),
|
||||||
// taking care of the proper incremental order.
|
// taking care of the proper incremental order.
|
||||||
for i := len(newChain) - 1; i >= 1; i-- {
|
for i := len(newChain) - 1; i >= 1; i-- {
|
||||||
|
|
@ -2777,11 +2775,13 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
||||||
|
|
||||||
// Delete useless indexes right now which includes the non-canonical
|
// Delete useless indexes right now which includes the non-canonical
|
||||||
// transaction indexes, canonical chain indexes which above the head.
|
// transaction indexes, canonical chain indexes which above the head.
|
||||||
indexesBatch := bc.db.NewBatch()
|
var (
|
||||||
for _, tx := range types.HashDifference(deletedTxs, addedTxs) {
|
indexesBatch = bc.db.NewBatch()
|
||||||
|
diffs = types.HashDifference(deletedTxs, addedTxs)
|
||||||
|
)
|
||||||
|
for _, tx := range diffs {
|
||||||
rawdb.DeleteTxLookupEntry(indexesBatch, tx)
|
rawdb.DeleteTxLookupEntry(indexesBatch, tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete all hash markers that are not part of the new canonical chain.
|
// Delete all hash markers that are not part of the new canonical chain.
|
||||||
// Because the reorg function does not handle new chain head, all hash
|
// Because the reorg function does not handle new chain head, all hash
|
||||||
// markers greater than or equal to new chain head should be deleted.
|
// markers greater than or equal to new chain head should be deleted.
|
||||||
|
|
|
||||||
|
|
@ -121,34 +121,23 @@ func (mv *MVHashMap) Write(k Key, v Version, data interface{}) {
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
|
|
||||||
cells.rw.RLock()
|
cells.rw.Lock()
|
||||||
ci, ok := cells.tm.Get(v.TxnIndex)
|
if ci, ok := cells.tm.Get(v.TxnIndex); !ok {
|
||||||
cells.rw.RUnlock()
|
cells.tm.Put(v.TxnIndex, &WriteCell{
|
||||||
|
flag: FlagDone,
|
||||||
if ok {
|
incarnation: v.Incarnation,
|
||||||
|
data: data,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
if ci.(*WriteCell).incarnation > v.Incarnation {
|
if ci.(*WriteCell).incarnation > v.Incarnation {
|
||||||
panic(fmt.Errorf("existing transaction value does not have lower incarnation: %v, %v",
|
panic(fmt.Errorf("existing transaction value does not have lower incarnation: %v, %v",
|
||||||
k, v.TxnIndex))
|
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
|
||||||
} 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 {
|
func (mv *MVHashMap) ReadStorage(k Key, fallBack func() any) any {
|
||||||
|
|
@ -166,13 +155,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.RLock()
|
cells.rw.Lock()
|
||||||
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.RUnlock()
|
cells.rw.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mv *MVHashMap) Delete(k Key, txIdx int) {
|
func (mv *MVHashMap) Delete(k Key, txIdx int) {
|
||||||
|
|
@ -233,8 +222,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)
|
||||||
|
|
@ -253,6 +242,8 @@ func (mv *MVHashMap) Read(k Key, txIdx int) (res MVReadResult) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cells.rw.RUnlock()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -288,6 +288,11 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat
|
||||||
|
|
||||||
deps := GetDeps(blockTxDependency)
|
deps := GetDeps(blockTxDependency)
|
||||||
|
|
||||||
|
if !VerifyDeps(deps) || len(blockTxDependency) != len(block.Transactions()) {
|
||||||
|
blockTxDependency = nil
|
||||||
|
deps = make(map[int][]int)
|
||||||
|
}
|
||||||
|
|
||||||
if blockTxDependency != nil {
|
if blockTxDependency != nil {
|
||||||
metadata = true
|
metadata = true
|
||||||
}
|
}
|
||||||
|
|
@ -308,57 +313,30 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat
|
||||||
shouldDelayFeeCal = false
|
shouldDelayFeeCal = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(blockTxDependency) != len(block.Transactions()) {
|
task := &ExecutionTask{
|
||||||
task := &ExecutionTask{
|
msg: *msg,
|
||||||
msg: *msg,
|
config: p.config,
|
||||||
config: p.config,
|
gasLimit: block.GasLimit(),
|
||||||
gasLimit: block.GasLimit(),
|
blockNumber: blockNumber,
|
||||||
blockNumber: blockNumber,
|
blockHash: blockHash,
|
||||||
blockHash: blockHash,
|
tx: tx,
|
||||||
tx: tx,
|
index: i,
|
||||||
index: i,
|
cleanStateDB: cleansdb,
|
||||||
cleanStateDB: cleansdb,
|
finalStateDB: statedb,
|
||||||
finalStateDB: statedb,
|
blockChain: p.bc,
|
||||||
blockChain: p.bc,
|
header: header,
|
||||||
header: header,
|
evmConfig: cfg,
|
||||||
evmConfig: cfg,
|
shouldDelayFeeCal: &shouldDelayFeeCal,
|
||||||
shouldDelayFeeCal: &shouldDelayFeeCal,
|
sender: msg.From,
|
||||||
sender: msg.From,
|
totalUsedGas: usedGas,
|
||||||
totalUsedGas: usedGas,
|
receipts: &receipts,
|
||||||
receipts: &receipts,
|
allLogs: &allLogs,
|
||||||
allLogs: &allLogs,
|
dependencies: deps[i],
|
||||||
dependencies: deps[i],
|
coinbase: coinbase,
|
||||||
coinbase: coinbase,
|
blockContext: blockContext,
|
||||||
blockContext: blockContext,
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks = append(tasks, task)
|
|
||||||
} else {
|
|
||||||
task := &ExecutionTask{
|
|
||||||
msg: *msg,
|
|
||||||
config: p.config,
|
|
||||||
gasLimit: block.GasLimit(),
|
|
||||||
blockNumber: blockNumber,
|
|
||||||
blockHash: blockHash,
|
|
||||||
tx: tx,
|
|
||||||
index: i,
|
|
||||||
cleanStateDB: cleansdb,
|
|
||||||
finalStateDB: statedb,
|
|
||||||
blockChain: p.bc,
|
|
||||||
header: header,
|
|
||||||
evmConfig: cfg,
|
|
||||||
shouldDelayFeeCal: &shouldDelayFeeCal,
|
|
||||||
sender: msg.From,
|
|
||||||
totalUsedGas: usedGas,
|
|
||||||
receipts: &receipts,
|
|
||||||
allLogs: &allLogs,
|
|
||||||
dependencies: nil,
|
|
||||||
coinbase: coinbase,
|
|
||||||
blockContext: blockContext,
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks = append(tasks, task)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks = append(tasks, task)
|
||||||
}
|
}
|
||||||
|
|
||||||
backupStateDB := statedb.Copy()
|
backupStateDB := statedb.Copy()
|
||||||
|
|
@ -427,3 +405,21 @@ func GetDeps(txDependency [][]uint64) map[int][]int {
|
||||||
|
|
||||||
return deps
|
return deps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns true if dependencies are correct
|
||||||
|
func VerifyDeps(deps map[int][]int) bool {
|
||||||
|
// number of transactions in the block
|
||||||
|
n := len(deps)
|
||||||
|
|
||||||
|
// Handle out-of-range and circular dependency problem
|
||||||
|
for i := 0; i <= n-1; i++ {
|
||||||
|
val := deps[i]
|
||||||
|
for _, depTx := range val {
|
||||||
|
if depTx >= n || depTx >= i {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
|
||||||
30
core/parallel_state_processor_test.go
Normal file
30
core/parallel_state_processor_test.go
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMetadata(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
correctTxDependency := [][]uint64{{}, {0}, {}, {1}, {3}, {}, {0, 2}, {5}, {}, {8}}
|
||||||
|
wrongTxDependency := [][]uint64{{0}}
|
||||||
|
wrongTxDependencyCircular := [][]uint64{{}, {2}, {1}}
|
||||||
|
wrongTxDependencyOutOfRange := [][]uint64{{}, {}, {3}}
|
||||||
|
|
||||||
|
var temp map[int][]int
|
||||||
|
|
||||||
|
temp = GetDeps(correctTxDependency)
|
||||||
|
assert.Equal(t, true, VerifyDeps(temp))
|
||||||
|
|
||||||
|
temp = GetDeps(wrongTxDependency)
|
||||||
|
assert.Equal(t, false, VerifyDeps(temp))
|
||||||
|
|
||||||
|
temp = GetDeps(wrongTxDependencyCircular)
|
||||||
|
assert.Equal(t, false, VerifyDeps(temp))
|
||||||
|
|
||||||
|
temp = GetDeps(wrongTxDependencyOutOfRange)
|
||||||
|
assert.Equal(t, false, VerifyDeps(temp))
|
||||||
|
}
|
||||||
|
|
@ -76,7 +76,7 @@ func ReadRawBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types.
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadBorReceipt retrieves all the bor block receipts belonging to a block, including
|
// ReadBorReceipt retrieves all the bor block receipts belonging to a block, including
|
||||||
// its correspoinding metadata fields. If it is unable to populate these metadata
|
// its corresponding metadata fields. If it is unable to populate these metadata
|
||||||
// fields then nil is returned.
|
// fields then nil is returned.
|
||||||
func ReadBorReceipt(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) *types.Receipt {
|
func ReadBorReceipt(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) *types.Receipt {
|
||||||
if config != nil && config.Bor != nil && config.Bor.Sprint != nil && !config.Bor.IsSprintStart(number) {
|
if config != nil && config.Bor != nil && config.Bor.Sprint != nil && !config.Bor.IsSprintStart(number) {
|
||||||
|
|
|
||||||
|
|
@ -917,7 +917,7 @@ func getChunk(size int, b int) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO (?)
|
// TODO (?)
|
||||||
// - test that if we remove several head-files, aswell as data last data-file,
|
// - test that if we remove several head-files, as well as data last data-file,
|
||||||
// the index is truncated accordingly
|
// the index is truncated accordingly
|
||||||
// Right now, the freezer would fail on these conditions:
|
// Right now, the freezer would fail on these conditions:
|
||||||
// 1. have data files d0, d1, d2, d3
|
// 1. have data files d0, d1, d2, d3
|
||||||
|
|
|
||||||
|
|
@ -103,12 +103,10 @@ func NewPruner(db ethdb.Database, config Config) (*Pruner, error) {
|
||||||
log.Warn("Sanitizing bloomfilter size", "provided(MB)", config.BloomSize, "updated(MB)", 256)
|
log.Warn("Sanitizing bloomfilter size", "provided(MB)", config.BloomSize, "updated(MB)", 256)
|
||||||
config.BloomSize = 256
|
config.BloomSize = 256
|
||||||
}
|
}
|
||||||
|
|
||||||
stateBloom, err := newStateBloomWithSize(config.BloomSize)
|
stateBloom, err := newStateBloomWithSize(config.BloomSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Pruner{
|
return &Pruner{
|
||||||
config: config,
|
config: config,
|
||||||
chainHeader: headBlock.Header(),
|
chainHeader: headBlock.Header(),
|
||||||
|
|
@ -123,7 +121,7 @@ func prune(snaptree *snapshot.Tree, root common.Hash, maindb ethdb.Database, sta
|
||||||
// the trie nodes(and codes) belong to the active state will be filtered
|
// the trie nodes(and codes) belong to the active state will be filtered
|
||||||
// out. A very small part of stale tries will also be filtered because of
|
// out. A very small part of stale tries will also be filtered because of
|
||||||
// the false-positive rate of bloom filter. But the assumption is held here
|
// the false-positive rate of bloom filter. But the assumption is held here
|
||||||
// that the false-positive is low enough(~0.05%). The probablity of the
|
// that the false-positive is low enough(~0.05%). The probability of the
|
||||||
// dangling node is the state root is super low. So the dangling nodes in
|
// dangling node is the state root is super low. So the dangling nodes in
|
||||||
// theory will never ever be visited again.
|
// theory will never ever be visited again.
|
||||||
var (
|
var (
|
||||||
|
|
@ -134,7 +132,6 @@ func prune(snaptree *snapshot.Tree, root common.Hash, maindb ethdb.Database, sta
|
||||||
batch = maindb.NewBatch()
|
batch = maindb.NewBatch()
|
||||||
iter = maindb.NewIterator(nil, nil)
|
iter = maindb.NewIterator(nil, nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
for iter.Next() {
|
for iter.Next() {
|
||||||
key := iter.Key()
|
key := iter.Key()
|
||||||
|
|
||||||
|
|
@ -148,7 +145,6 @@ func prune(snaptree *snapshot.Tree, root common.Hash, maindb ethdb.Database, sta
|
||||||
if isCode {
|
if isCode {
|
||||||
checkKey = codeKey
|
checkKey = codeKey
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, exist := middleStateRoots[common.BytesToHash(checkKey)]; exist {
|
if _, exist := middleStateRoots[common.BytesToHash(checkKey)]; exist {
|
||||||
log.Debug("Forcibly delete the middle state roots", "hash", common.BytesToHash(checkKey))
|
log.Debug("Forcibly delete the middle state roots", "hash", common.BytesToHash(checkKey))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -157,26 +153,21 @@ func prune(snaptree *snapshot.Tree, root common.Hash, maindb ethdb.Database, sta
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
size += common.StorageSize(len(key) + len(iter.Value()))
|
size += common.StorageSize(len(key) + len(iter.Value()))
|
||||||
batch.Delete(key)
|
batch.Delete(key)
|
||||||
|
|
||||||
var eta time.Duration // Realistically will never remain uninited
|
var eta time.Duration // Realistically will never remain uninited
|
||||||
|
|
||||||
if done := binary.BigEndian.Uint64(key[:8]); done > 0 {
|
if done := binary.BigEndian.Uint64(key[:8]); done > 0 {
|
||||||
var (
|
var (
|
||||||
left = math.MaxUint64 - binary.BigEndian.Uint64(key[:8])
|
left = math.MaxUint64 - binary.BigEndian.Uint64(key[:8])
|
||||||
speed = done/uint64(time.Since(pstart)/time.Millisecond+1) + 1 // +1s to avoid division by zero
|
speed = done/uint64(time.Since(pstart)/time.Millisecond+1) + 1 // +1s to avoid division by zero
|
||||||
)
|
)
|
||||||
|
|
||||||
eta = time.Duration(left/speed) * time.Millisecond
|
eta = time.Duration(left/speed) * time.Millisecond
|
||||||
}
|
}
|
||||||
|
|
||||||
if time.Since(logged) > 8*time.Second {
|
if time.Since(logged) > 8*time.Second {
|
||||||
log.Info("Pruning state data", "nodes", count, "skipped", skipped, "size", size,
|
log.Info("Pruning state data", "nodes", count, "skipped", skipped, "size", size,
|
||||||
"elapsed", common.PrettyDuration(time.Since(pstart)), "eta", common.PrettyDuration(eta))
|
"elapsed", common.PrettyDuration(time.Since(pstart)), "eta", common.PrettyDuration(eta))
|
||||||
|
|
||||||
logged = time.Now()
|
logged = time.Now()
|
||||||
}
|
}
|
||||||
// Recreate the iterator after every batch commit in order
|
// Recreate the iterator after every batch commit in order
|
||||||
|
|
@ -190,12 +181,10 @@ func prune(snaptree *snapshot.Tree, root common.Hash, maindb ethdb.Database, sta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if batch.ValueSize() > 0 {
|
if batch.ValueSize() > 0 {
|
||||||
batch.Write()
|
batch.Write()
|
||||||
batch.Reset()
|
batch.Reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
iter.Release()
|
iter.Release()
|
||||||
log.Info("Pruned state data", "nodes", count, "size", size, "elapsed", common.PrettyDuration(time.Since(pstart)))
|
log.Info("Pruned state data", "nodes", count, "size", size, "elapsed", common.PrettyDuration(time.Since(pstart)))
|
||||||
|
|
||||||
|
|
@ -222,19 +211,15 @@ func prune(snaptree *snapshot.Tree, root common.Hash, maindb ethdb.Database, sta
|
||||||
// Note for small pruning, the compaction is skipped.
|
// Note for small pruning, the compaction is skipped.
|
||||||
if count >= rangeCompactionThreshold {
|
if count >= rangeCompactionThreshold {
|
||||||
cstart := time.Now()
|
cstart := time.Now()
|
||||||
|
|
||||||
for b := 0x00; b <= 0xf0; b += 0x10 {
|
for b := 0x00; b <= 0xf0; b += 0x10 {
|
||||||
var (
|
var (
|
||||||
start = []byte{byte(b)}
|
start = []byte{byte(b)}
|
||||||
end = []byte{byte(b + 0x10)}
|
end = []byte{byte(b + 0x10)}
|
||||||
)
|
)
|
||||||
|
|
||||||
if b == 0xf0 {
|
if b == 0xf0 {
|
||||||
end = nil
|
end = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Compacting database", "range", fmt.Sprintf("%#x-%#x", start, end), "elapsed", common.PrettyDuration(time.Since(cstart)))
|
log.Info("Compacting database", "range", fmt.Sprintf("%#x-%#x", start, end), "elapsed", common.PrettyDuration(time.Since(cstart)))
|
||||||
|
|
||||||
if err := maindb.Compact(start, end); err != nil {
|
if err := maindb.Compact(start, end); err != nil {
|
||||||
log.Error("Database compaction failed", "error", err)
|
log.Error("Database compaction failed", "error", err)
|
||||||
return err
|
return err
|
||||||
|
|
@ -242,16 +227,13 @@ func prune(snaptree *snapshot.Tree, root common.Hash, maindb ethdb.Database, sta
|
||||||
}
|
}
|
||||||
log.Info("Database compaction finished", "elapsed", common.PrettyDuration(time.Since(cstart)))
|
log.Info("Database compaction finished", "elapsed", common.PrettyDuration(time.Since(cstart)))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("State pruning successful", "pruned", size, "elapsed", common.PrettyDuration(time.Since(start)))
|
log.Info("State pruning successful", "pruned", size, "elapsed", common.PrettyDuration(time.Since(start)))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prune deletes all historical state nodes except the nodes belong to the
|
// Prune deletes all historical state nodes except the nodes belong to the
|
||||||
// specified state version. If user doesn't specify the state version, use
|
// specified state version. If user doesn't specify the state version, use
|
||||||
// the bottom-most snapshot diff layer as the target.
|
// the bottom-most snapshot diff layer as the target.
|
||||||
// nolint:nestif
|
|
||||||
func (p *Pruner) Prune(root common.Hash) error {
|
func (p *Pruner) Prune(root common.Hash) error {
|
||||||
// If the state bloom filter is already committed previously,
|
// If the state bloom filter is already committed previously,
|
||||||
// reuse it for pruning instead of generating a new one. It's
|
// reuse it for pruning instead of generating a new one. It's
|
||||||
|
|
@ -261,7 +243,6 @@ func (p *Pruner) Prune(root common.Hash) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if stateBloomRoot != (common.Hash{}) {
|
if stateBloomRoot != (common.Hash{}) {
|
||||||
return RecoverPruning(p.config.Datadir, p.db)
|
return RecoverPruning(p.config.Datadir, p.db)
|
||||||
}
|
}
|
||||||
|
|
@ -300,23 +281,18 @@ func (p *Pruner) Prune(root common.Hash) error {
|
||||||
// state available, but we don't want to use the topmost state
|
// state available, but we don't want to use the topmost state
|
||||||
// as the pruning target.
|
// as the pruning target.
|
||||||
var found bool
|
var found bool
|
||||||
|
|
||||||
for i := len(layers) - 2; i >= 2; i-- {
|
for i := len(layers) - 2; i >= 2; i-- {
|
||||||
if rawdb.HasLegacyTrieNode(p.db, layers[i].Root()) {
|
if rawdb.HasLegacyTrieNode(p.db, layers[i].Root()) {
|
||||||
root = layers[i].Root()
|
root = layers[i].Root()
|
||||||
found = true
|
found = true
|
||||||
|
|
||||||
log.Info("Selecting middle-layer as the pruning target", "root", root, "depth", i)
|
log.Info("Selecting middle-layer as the pruning target", "root", root, "depth", i)
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
if len(layers) > 0 {
|
if len(layers) > 0 {
|
||||||
return errors.New("no snapshot paired state")
|
return errors.New("no snapshot paired state")
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("associated state[%x] is not present", root)
|
return fmt.Errorf("associated state[%x] is not present", root)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -329,18 +305,15 @@ func (p *Pruner) Prune(root common.Hash) error {
|
||||||
// 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{})
|
||||||
|
|
||||||
for _, layer := range layers {
|
for _, layer := range layers {
|
||||||
if layer.Root() == root {
|
if layer.Root() == root {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
middleRoots[layer.Root()] = struct{}{}
|
middleRoots[layer.Root()] = struct{}{}
|
||||||
}
|
}
|
||||||
// Traverse the target state, re-construct the whole state trie and
|
// Traverse the target state, re-construct the whole state trie and
|
||||||
// commit to the given bloom filter.
|
// commit to the given bloom filter.
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
if err := snapshot.GenerateTrie(p.snaptree, root, p.db, p.stateBloom); err != nil {
|
if err := snapshot.GenerateTrie(p.snaptree, root, p.db, p.stateBloom); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -349,17 +322,13 @@ func (p *Pruner) Prune(root common.Hash) error {
|
||||||
if err := extractGenesis(p.db, p.stateBloom); err != nil {
|
if err := extractGenesis(p.db, p.stateBloom); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
filterName := bloomFilterName(p.config.Datadir, root)
|
filterName := bloomFilterName(p.config.Datadir, root)
|
||||||
|
|
||||||
log.Info("Writing state bloom to disk", "name", filterName)
|
log.Info("Writing state bloom to disk", "name", filterName)
|
||||||
|
|
||||||
if err := p.stateBloom.Commit(filterName, filterName+stateBloomFileTempSuffix); err != nil {
|
if err := p.stateBloom.Commit(filterName, filterName+stateBloomFileTempSuffix); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("State bloom filter committed", "name", filterName)
|
log.Info("State bloom filter committed", "name", filterName)
|
||||||
|
|
||||||
return prune(p.snaptree, root, p.db, p.stateBloom, filterName, middleRoots, start)
|
return prune(p.snaptree, root, p.db, p.stateBloom, filterName, middleRoots, start)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -375,11 +344,9 @@ func RecoverPruning(datadir string, db ethdb.Database) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if stateBloomPath == "" {
|
if stateBloomPath == "" {
|
||||||
return nil // nothing to recover
|
return nil // nothing to recover
|
||||||
}
|
}
|
||||||
|
|
||||||
headBlock := rawdb.ReadHeadBlock(db)
|
headBlock := rawdb.ReadHeadBlock(db)
|
||||||
if headBlock == nil {
|
if headBlock == nil {
|
||||||
return errors.New("failed to load head block")
|
return errors.New("failed to load head block")
|
||||||
|
|
@ -404,12 +371,10 @@ func RecoverPruning(datadir string, db ethdb.Database) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err // The relevant snapshot(s) might not exist
|
return err // The relevant snapshot(s) might not exist
|
||||||
}
|
}
|
||||||
|
|
||||||
stateBloom, err := NewStateBloomFromDisk(stateBloomPath)
|
stateBloom, err := NewStateBloomFromDisk(stateBloomPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Loaded state bloom filter", "path", stateBloomPath)
|
log.Info("Loaded state bloom filter", "path", stateBloomPath)
|
||||||
|
|
||||||
// All the state roots of the middle layers should be forcibly pruned,
|
// All the state roots of the middle layers should be forcibly pruned,
|
||||||
|
|
@ -419,21 +384,17 @@ func RecoverPruning(datadir string, db ethdb.Database) error {
|
||||||
layers = snaptree.Snapshots(headBlock.Root(), 128, true)
|
layers = snaptree.Snapshots(headBlock.Root(), 128, true)
|
||||||
middleRoots = make(map[common.Hash]struct{})
|
middleRoots = make(map[common.Hash]struct{})
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, layer := range layers {
|
for _, layer := range layers {
|
||||||
if layer.Root() == stateBloomRoot {
|
if layer.Root() == stateBloomRoot {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
middleRoots[layer.Root()] = struct{}{}
|
middleRoots[layer.Root()] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
log.Error("Pruning target state is not existent")
|
log.Error("Pruning target state is not existent")
|
||||||
return errors.New("non-existent target state")
|
return errors.New("non-existent target state")
|
||||||
}
|
}
|
||||||
|
|
||||||
return prune(snaptree, stateBloomRoot, db, stateBloom, stateBloomPath, middleRoots, time.Now())
|
return prune(snaptree, stateBloomRoot, db, stateBloom, stateBloomPath, middleRoots, time.Now())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -444,7 +405,6 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
|
||||||
if genesisHash == (common.Hash{}) {
|
if genesisHash == (common.Hash{}) {
|
||||||
return errors.New("missing genesis hash")
|
return errors.New("missing genesis hash")
|
||||||
}
|
}
|
||||||
|
|
||||||
genesis := rawdb.ReadBlock(db, genesisHash, 0)
|
genesis := rawdb.ReadBlock(db, genesisHash, 0)
|
||||||
if genesis == nil {
|
if genesis == nil {
|
||||||
return errors.New("missing genesis block")
|
return errors.New("missing genesis block")
|
||||||
|
|
@ -471,7 +431,6 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
|
||||||
if err := rlp.DecodeBytes(accIter.LeafBlob(), &acc); err != nil {
|
if err := rlp.DecodeBytes(accIter.LeafBlob(), &acc); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if acc.Root != types.EmptyRootHash {
|
if acc.Root != types.EmptyRootHash {
|
||||||
id := trie.StorageTrieID(genesis.Root(), common.BytesToHash(accIter.LeafKey()), acc.Root)
|
id := trie.StorageTrieID(genesis.Root(), common.BytesToHash(accIter.LeafKey()), acc.Root)
|
||||||
storageTrie, err := trie.NewStateTrie(id, trie.NewDatabase(db, trie.HashDefaults))
|
storageTrie, err := trie.NewStateTrie(id, trie.NewDatabase(db, trie.HashDefaults))
|
||||||
|
|
@ -488,18 +447,15 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
|
||||||
stateBloom.Put(hash.Bytes(), nil)
|
stateBloom.Put(hash.Bytes(), nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if storageIter.Error() != nil {
|
if storageIter.Error() != nil {
|
||||||
return storageIter.Error()
|
return storageIter.Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
|
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||||
stateBloom.Put(acc.CodeHash, nil)
|
stateBloom.Put(acc.CodeHash, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return accIter.Error()
|
return accIter.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -512,7 +468,6 @@ func isBloomFilter(filename string) (bool, common.Hash) {
|
||||||
if strings.HasPrefix(filename, stateBloomFilePrefix) && strings.HasSuffix(filename, stateBloomFileSuffix) {
|
if strings.HasPrefix(filename, stateBloomFilePrefix) && strings.HasSuffix(filename, stateBloomFileSuffix) {
|
||||||
return true, common.HexToHash(filename[len(stateBloomFilePrefix)+1 : len(filename)-len(stateBloomFileSuffix)-1])
|
return true, common.HexToHash(filename[len(stateBloomFilePrefix)+1 : len(filename)-len(stateBloomFileSuffix)-1])
|
||||||
}
|
}
|
||||||
|
|
||||||
return false, common.Hash{}
|
return false, common.Hash{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -521,7 +476,6 @@ func findBloomFilter(datadir string) (string, common.Hash, error) {
|
||||||
stateBloomPath string
|
stateBloomPath string
|
||||||
stateBloomRoot common.Hash
|
stateBloomRoot common.Hash
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := filepath.Walk(datadir, func(path string, info os.FileInfo, err error) error {
|
if err := filepath.Walk(datadir, func(path string, info os.FileInfo, err error) error {
|
||||||
if info != nil && !info.IsDir() {
|
if info != nil && !info.IsDir() {
|
||||||
ok, root := isBloomFilter(path)
|
ok, root := isBloomFilter(path)
|
||||||
|
|
@ -534,6 +488,5 @@ func findBloomFilter(datadir string) (string, common.Hash, error) {
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return "", common.Hash{}, err
|
return "", common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return stateBloomPath, stateBloomRoot, nil
|
return stateBloomPath, stateBloomRoot, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ var (
|
||||||
aggregatorMemoryLimit = uint64(4 * 1024 * 1024)
|
aggregatorMemoryLimit = uint64(4 * 1024 * 1024)
|
||||||
|
|
||||||
// aggregatorItemLimit is an approximate number of items that will end up
|
// aggregatorItemLimit is an approximate number of items that will end up
|
||||||
// in the agregator layer before it's flushed out to disk. A plain account
|
// in the aggregator layer before it's flushed out to disk. A plain account
|
||||||
// weighs around 14B (+hash), a storage slot 32B (+hash), a deleted slot
|
// weighs around 14B (+hash), a storage slot 32B (+hash), a deleted slot
|
||||||
// 0B (+hash). Slots are mostly set/unset in lockstep, so that average at
|
// 0B (+hash). Slots are mostly set/unset in lockstep, so that average at
|
||||||
// 16B (+hash). All in all, the average entry seems to be 15+32=47B. Use a
|
// 16B (+hash). All in all, the average entry seems to be 15+32=47B. Use a
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ func TestDiskMerge(t *testing.T) {
|
||||||
// Retrieve all the data through the disk layer and validate it
|
// Retrieve all the data through the disk layer and validate it
|
||||||
base = snaps.Snapshot(diffRoot)
|
base = snaps.Snapshot(diffRoot)
|
||||||
if _, ok := base.(*diskLayer); !ok {
|
if _, ok := base.(*diskLayer); !ok {
|
||||||
t.Fatalf("update not flattend into the disk layer")
|
t.Fatalf("update not flattened into the disk layer")
|
||||||
}
|
}
|
||||||
|
|
||||||
// assertAccount ensures that an account matches the given blob.
|
// assertAccount ensures that an account matches the given blob.
|
||||||
|
|
@ -374,7 +374,7 @@ func TestDiskPartialMerge(t *testing.T) {
|
||||||
// Retrieve all the data through the disk layer and validate it
|
// Retrieve all the data through the disk layer and validate it
|
||||||
base = snaps.Snapshot(diffRoot)
|
base = snaps.Snapshot(diffRoot)
|
||||||
if _, ok := base.(*diskLayer); !ok {
|
if _, ok := base.(*diskLayer); !ok {
|
||||||
t.Fatalf("test %d: update not flattend into the disk layer", i)
|
t.Fatalf("test %d: update not flattened into the disk layer", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertAccount(accNoModNoCache, accNoModNoCache[:])
|
assertAccount(accNoModNoCache, accNoModNoCache[:])
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,7 @@ func testIterativeStateSync(t *testing.T, count int, commit bool, bypath bool, s
|
||||||
id := trie.StorageTrieID(srcRoot, common.BytesToHash(node.syncPath[0]), acc.Root)
|
id := trie.StorageTrieID(srcRoot, common.BytesToHash(node.syncPath[0]), acc.Root)
|
||||||
stTrie, err := trie.New(id, ndb)
|
stTrie, err := trie.New(id, ndb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to retriev storage trie for path %x: %v", node.syncPath[1], err)
|
t.Fatalf("failed to retrieve storage trie for path %x: %v", node.syncPath[1], err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, _, err := stTrie.GetNode(node.syncPath[1])
|
data, _, err := stTrie.GetNode(node.syncPath[1])
|
||||||
|
|
|
||||||
|
|
@ -456,7 +456,7 @@ func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error {
|
||||||
tx := new(types.Transaction)
|
tx := new(types.Transaction)
|
||||||
if err := rlp.DecodeBytes(blob, tx); err != nil {
|
if err := rlp.DecodeBytes(blob, tx); err != nil {
|
||||||
// This path is impossible unless the disk data representation changes
|
// This path is impossible unless the disk data representation changes
|
||||||
// across restarts. For that ever unprobable case, recover gracefully
|
// across restarts. For that ever improbable case, recover gracefully
|
||||||
// by ignoring this data entry.
|
// by ignoring this data entry.
|
||||||
log.Error("Failed to decode blob pool entry", "id", id, "err", err)
|
log.Error("Failed to decode blob pool entry", "id", id, "err", err)
|
||||||
return err
|
return err
|
||||||
|
|
@ -471,7 +471,7 @@ func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error {
|
||||||
sender, err := p.signer.Sender(tx)
|
sender, err := p.signer.Sender(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// This path is impossible unless the signature validity changes across
|
// This path is impossible unless the signature validity changes across
|
||||||
// restarts. For that ever unprobable case, recover gracefully by ignoring
|
// restarts. For that ever improbable case, recover gracefully by ignoring
|
||||||
// this data entry.
|
// this data entry.
|
||||||
log.Error("Failed to recover blob tx sender", "id", id, "hash", tx.Hash(), "err", err)
|
log.Error("Failed to recover blob tx sender", "id", id, "hash", tx.Hash(), "err", err)
|
||||||
return err
|
return err
|
||||||
|
|
@ -711,7 +711,7 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
|
||||||
// offload removes a tracked blob transaction from the pool and moves it into the
|
// offload removes a tracked blob transaction from the pool and moves it into the
|
||||||
// limbo for tracking until finality.
|
// limbo for tracking until finality.
|
||||||
//
|
//
|
||||||
// The method may log errors for various unexpcted scenarios but will not return
|
// The method may log errors for various unexpected scenarios but will not return
|
||||||
// any of it since there's no clear error case. Some errors may be due to coding
|
// any of it since there's no clear error case. Some errors may be due to coding
|
||||||
// issues, others caused by signers mining MEV stuff or swapping transactions. In
|
// issues, others caused by signers mining MEV stuff or swapping transactions. In
|
||||||
// all cases, the pool needs to continue operating.
|
// all cases, the pool needs to continue operating.
|
||||||
|
|
@ -738,7 +738,7 @@ func (p *BlobPool) offload(addr common.Address, nonce uint64, id uint64, inclusi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset implements txpool.SubPool, allowing the blob pool's internal state to be
|
// Reset implements txpool.SubPool, allowing the blob pool's internal state to be
|
||||||
// kept in sync with the main transacion pool's internal state.
|
// kept in sync with the main transaction pool's internal state.
|
||||||
func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
|
func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
|
||||||
waitStart := time.Now()
|
waitStart := time.Now()
|
||||||
p.lock.Lock()
|
p.lock.Lock()
|
||||||
|
|
@ -972,7 +972,7 @@ func (p *BlobPool) reinject(addr common.Address, txhash common.Hash) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGasTip implements txpool.SubPool, allowing the blob pool's gas requirements
|
// SetGasTip implements txpool.SubPool, allowing the blob pool's gas requirements
|
||||||
// to be kept in sync with the main transacion pool's gas requirements.
|
// to be kept in sync with the main transaction pool's gas requirements.
|
||||||
func (p *BlobPool) SetGasTip(tip *big.Int) {
|
func (p *BlobPool) SetGasTip(tip *big.Int) {
|
||||||
p.lock.Lock()
|
p.lock.Lock()
|
||||||
defer p.lock.Unlock()
|
defer p.lock.Unlock()
|
||||||
|
|
|
||||||
|
|
@ -598,9 +598,9 @@ func TestOpenDrops(t *testing.T) {
|
||||||
verifyPoolInternals(t, pool)
|
verifyPoolInternals(t, pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that transactions loaded from disk are indexed corrently.
|
// Tests that transactions loaded from disk are indexed correctly.
|
||||||
//
|
//
|
||||||
// - 1. Transactions must be groupped by sender, sorted by nonce
|
// - 1. Transactions must be grouped by sender, sorted by nonce
|
||||||
// - 2. Eviction thresholds are calculated correctly for the sequences
|
// - 2. Eviction thresholds are calculated correctly for the sequences
|
||||||
// - 3. Balance usage of an account is totals across all transactions
|
// - 3. Balance usage of an account is totals across all transactions
|
||||||
func TestOpenIndex(t *testing.T) {
|
func TestOpenIndex(t *testing.T) {
|
||||||
|
|
@ -1213,7 +1213,7 @@ func TestAdd(t *testing.T) {
|
||||||
keys[acc], _ = crypto.GenerateKey()
|
keys[acc], _ = crypto.GenerateKey()
|
||||||
addrs[acc] = crypto.PubkeyToAddress(keys[acc].PublicKey)
|
addrs[acc] = crypto.PubkeyToAddress(keys[acc].PublicKey)
|
||||||
|
|
||||||
// Seed the state database with this acocunt
|
// Seed the state database with this account
|
||||||
statedb.AddBalance(addrs[acc], new(big.Int).SetUint64(seed.balance))
|
statedb.AddBalance(addrs[acc], new(big.Int).SetUint64(seed.balance))
|
||||||
statedb.SetNonce(addrs[acc], seed.nonce)
|
statedb.SetNonce(addrs[acc], seed.nonce)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ func newLimbo(datadir string) (*limbo, error) {
|
||||||
index: make(map[common.Hash]uint64),
|
index: make(map[common.Hash]uint64),
|
||||||
groups: make(map[uint64]map[uint64]common.Hash),
|
groups: make(map[uint64]map[uint64]common.Hash),
|
||||||
}
|
}
|
||||||
// Index all limboed blobs on disk and delete anything inprocessable
|
// Index all limboed blobs on disk and delete anything unprocessable
|
||||||
var fails []uint64
|
var fails []uint64
|
||||||
index := func(id uint64, size uint32, data []byte) {
|
index := func(id uint64, size uint32, data []byte) {
|
||||||
if l.parseBlob(id, data) != nil {
|
if l.parseBlob(id, data) != nil {
|
||||||
|
|
@ -89,7 +89,7 @@ func (l *limbo) parseBlob(id uint64, data []byte) error {
|
||||||
item := new(limboBlob)
|
item := new(limboBlob)
|
||||||
if err := rlp.DecodeBytes(data, item); err != nil {
|
if err := rlp.DecodeBytes(data, item); err != nil {
|
||||||
// This path is impossible unless the disk data representation changes
|
// This path is impossible unless the disk data representation changes
|
||||||
// across restarts. For that ever unprobable case, recover gracefully
|
// across restarts. For that ever improbable case, recover gracefully
|
||||||
// by ignoring this data entry.
|
// by ignoring this data entry.
|
||||||
log.Error("Failed to decode blob limbo entry", "id", id, "err", err)
|
log.Error("Failed to decode blob limbo entry", "id", id, "err", err)
|
||||||
return err
|
return err
|
||||||
|
|
@ -172,7 +172,7 @@ func (l *limbo) pull(tx common.Hash) (*types.Transaction, error) {
|
||||||
// update changes the block number under which a blob transaction is tracked. This
|
// update changes the block number under which a blob transaction is tracked. This
|
||||||
// method should be used when a reorg changes a transaction's inclusion block.
|
// method should be used when a reorg changes a transaction's inclusion block.
|
||||||
//
|
//
|
||||||
// The method may log errors for various unexpcted scenarios but will not return
|
// The method may log errors for various unexpected scenarios but will not return
|
||||||
// any of it since there's no clear error case. Some errors may be due to coding
|
// any of it since there's no clear error case. Some errors may be due to coding
|
||||||
// issues, others caused by signers mining MEV stuff or swapping transactions. In
|
// issues, others caused by signers mining MEV stuff or swapping transactions. In
|
||||||
// all cases, the pool needs to continue operating.
|
// all cases, the pool needs to continue operating.
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ var (
|
||||||
pooltipGauge = metrics.NewRegisteredGauge("blobpool/pooltip", nil)
|
pooltipGauge = metrics.NewRegisteredGauge("blobpool/pooltip", nil)
|
||||||
|
|
||||||
// addwait/time, resetwait/time and getwait/time track the rough health of
|
// addwait/time, resetwait/time and getwait/time track the rough health of
|
||||||
// the pool and wether or not it's capable of keeping up with the load from
|
// the pool and whether or not it's capable of keeping up with the load from
|
||||||
// the network.
|
// the network.
|
||||||
addwaitHist = metrics.NewRegisteredHistogram("blobpool/addwait", nil, metrics.NewExpDecaySample(1028, 0.015))
|
addwaitHist = metrics.NewRegisteredHistogram("blobpool/addwait", nil, metrics.NewExpDecaySample(1028, 0.015))
|
||||||
addtimeHist = metrics.NewRegisteredHistogram("blobpool/addtime", nil, metrics.NewExpDecaySample(1028, 0.015))
|
addtimeHist = metrics.NewRegisteredHistogram("blobpool/addtime", nil, metrics.NewExpDecaySample(1028, 0.015))
|
||||||
|
|
|
||||||
|
|
@ -155,8 +155,7 @@ var DefaultConfig = Config{
|
||||||
AccountQueue: 64,
|
AccountQueue: 64,
|
||||||
GlobalQueue: 1024,
|
GlobalQueue: 1024,
|
||||||
|
|
||||||
Lifetime: 3 * time.Hour,
|
Lifetime: 3 * time.Hour,
|
||||||
AllowUnprotectedTxs: false,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanitize checks the provided user configurations and changes anything that's
|
// sanitize checks the provided user configurations and changes anything that's
|
||||||
|
|
@ -602,8 +601,7 @@ func (pool *LegacyPool) local() map[common.Address]types.Transactions {
|
||||||
// and does not require the pool mutex to be held.
|
// and does not require the pool mutex to be held.
|
||||||
func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) error {
|
func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) error {
|
||||||
opts := &txpool.ValidationOptions{
|
opts := &txpool.ValidationOptions{
|
||||||
Config: pool.chainconfig,
|
Config: pool.chainconfig,
|
||||||
AllowUnprotectedTxs: pool.config.AllowUnprotectedTxs,
|
|
||||||
Accept: 0 |
|
Accept: 0 |
|
||||||
1<<types.LegacyTxType |
|
1<<types.LegacyTxType |
|
||||||
1<<types.AccessListTxType |
|
1<<types.AccessListTxType |
|
||||||
|
|
@ -673,11 +671,6 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e
|
||||||
knownTxMeter.Mark(1)
|
knownTxMeter.Mark(1)
|
||||||
return false, txpool.ErrAlreadyKnown
|
return false, txpool.ErrAlreadyKnown
|
||||||
}
|
}
|
||||||
|
|
||||||
if pool.config.AllowUnprotectedTxs {
|
|
||||||
pool.signer = types.NewFakeSigner(tx.ChainId())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the local flag. If it's from local source or it's from the network but
|
// Make the local flag. If it's from local source or it's from the network but
|
||||||
// the sender is marked as local previously, treat it as the local transaction.
|
// the sender is marked as local previously, treat it as the local transaction.
|
||||||
isLocal := local || pool.locals.containsTx(tx)
|
isLocal := local || pool.locals.containsTx(tx)
|
||||||
|
|
@ -991,11 +984,6 @@ func (pool *LegacyPool) Add(txs []*types.Transaction, local, sync bool) []error
|
||||||
knownTxMeter.Mark(1)
|
knownTxMeter.Mark(1)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if pool.config.AllowUnprotectedTxs {
|
|
||||||
pool.signer = types.NewFakeSigner(tx.ChainId())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exclude transactions with basic errors, e.g invalid signatures and
|
// Exclude transactions with basic errors, e.g invalid signatures and
|
||||||
// insufficient intrinsic gas as soon as possible and cache senders
|
// insufficient intrinsic gas as soon as possible and cache senders
|
||||||
// in transactions before obtaining lock
|
// in transactions before obtaining lock
|
||||||
|
|
|
||||||
|
|
@ -3778,7 +3778,7 @@ func newTxs(pool *LegacyPool) *types.Transaction {
|
||||||
|
|
||||||
// txCount++
|
// txCount++
|
||||||
// } else {
|
// } else {
|
||||||
// // we don't maximize fulfilment of the block. just fill somehow
|
// // we don't maximize fulfillment of the block. just fill somehow
|
||||||
// return blockGasLimit, txCount
|
// return blockGasLimit, txCount
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ type AddressReserver func(addr common.Address, reserve bool) error
|
||||||
// production, this interface defines the common methods that allow the primary
|
// production, this interface defines the common methods that allow the primary
|
||||||
// transaction pool to manage the subpools.
|
// transaction pool to manage the subpools.
|
||||||
type SubPool interface {
|
type SubPool interface {
|
||||||
// Filter is a selector used to decide whether a transaction whould be added
|
// Filter is a selector used to decide whether a transaction would be added
|
||||||
// to this particular subpool.
|
// to this particular subpool.
|
||||||
Filter(tx *types.Transaction) bool
|
Filter(tx *types.Transaction) bool
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,6 @@ import (
|
||||||
type ValidationOptions struct {
|
type ValidationOptions struct {
|
||||||
Config *params.ChainConfig // Chain configuration to selectively validate based on current fork rules
|
Config *params.ChainConfig // Chain configuration to selectively validate based on current fork rules
|
||||||
|
|
||||||
AllowUnprotectedTxs bool // Whether to allow unprotected transactions in the pool
|
|
||||||
|
|
||||||
Accept uint8 // Bitmap of transaction types that should be accepted for the calling pool
|
Accept uint8 // Bitmap of transaction types that should be accepted for the calling pool
|
||||||
MaxSize uint64 // Maximum size of a transaction that the caller can meaningfully handle
|
MaxSize uint64 // Maximum size of a transaction that the caller can meaningfully handle
|
||||||
MinTip *big.Int // Minimum gas tip needed to allow a transaction into the caller pool
|
MinTip *big.Int // Minimum gas tip needed to allow a transaction into the caller pool
|
||||||
|
|
@ -93,7 +91,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
||||||
return core.ErrTipAboveFeeCap
|
return core.ErrTipAboveFeeCap
|
||||||
}
|
}
|
||||||
// Make sure the transaction is signed properly
|
// Make sure the transaction is signed properly
|
||||||
if _, err := types.Sender(signer, tx); err != nil && !opts.AllowUnprotectedTxs {
|
if _, err := types.Sender(signer, tx); err != nil {
|
||||||
return ErrInvalidSender
|
return ErrInvalidSender
|
||||||
}
|
}
|
||||||
// Ensure the transaction has more gas than the bare minimum needed to cover
|
// Ensure the transaction has more gas than the bare minimum needed to cover
|
||||||
|
|
|
||||||
|
|
@ -463,8 +463,8 @@ func (b *Block) GetTxDependency() [][]uint64 {
|
||||||
return blockExtraData.TxDependency
|
return blockExtraData.TxDependency
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Header) GetValidatorBytes(config *params.BorConfig) []byte {
|
func (h *Header) GetValidatorBytes(chainConfig *params.ChainConfig) []byte {
|
||||||
if !config.IsParallelUniverse(h.Number) {
|
if !chainConfig.IsCancun(h.Number) {
|
||||||
return h.Extra[ExtraVanityLength : len(h.Extra)-ExtraSealLength]
|
return h.Extra[ExtraVanityLength : len(h.Extra)-ExtraSealLength]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,6 @@ func TestBlockEncoding(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a replica of `(h *Header) GetValidatorBytes` function
|
// This is a replica of `(h *Header) GetValidatorBytes` function
|
||||||
// This was needed because currently, `IsParallelUniverse` will always return false.
|
|
||||||
func GetValidatorBytesTest(h *Header) []byte {
|
func GetValidatorBytesTest(h *Header) []byte {
|
||||||
if len(h.Extra) < ExtraVanityLength+ExtraSealLength {
|
if len(h.Extra) < ExtraVanityLength+ExtraSealLength {
|
||||||
log.Error("length of extra less is than vanity and seal")
|
log.Error("length of extra less is than vanity and seal")
|
||||||
|
|
|
||||||
|
|
@ -582,38 +582,3 @@ func deriveChainId(v *big.Int) *big.Int {
|
||||||
v = new(big.Int).Sub(v, big.NewInt(35))
|
v = new(big.Int).Sub(v, big.NewInt(35))
|
||||||
return v.Div(v, big.NewInt(2))
|
return v.Div(v, big.NewInt(2))
|
||||||
}
|
}
|
||||||
|
|
||||||
// FakeSigner implements the Signer interface and accepts unprotected transactions
|
|
||||||
type FakeSigner struct{ londonSigner }
|
|
||||||
|
|
||||||
var _ Signer = FakeSigner{}
|
|
||||||
|
|
||||||
func NewFakeSigner(chainId *big.Int) Signer {
|
|
||||||
signer := NewLondonSigner(chainId)
|
|
||||||
ls, _ := signer.(londonSigner)
|
|
||||||
return FakeSigner{londonSigner: ls}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f FakeSigner) Sender(tx *Transaction) (common.Address, error) {
|
|
||||||
return f.londonSigner.Sender(tx)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f FakeSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v *big.Int, err error) {
|
|
||||||
return f.londonSigner.SignatureValues(tx, sig)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f FakeSigner) ChainID() *big.Int {
|
|
||||||
return f.londonSigner.ChainID()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash returns 'signature hash', i.e. the transaction hash that is signed by the
|
|
||||||
// private key. This hash does not uniquely identify the transaction.
|
|
||||||
func (f FakeSigner) Hash(tx *Transaction) common.Hash {
|
|
||||||
return f.londonSigner.Hash(tx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equal returns true if the given signer is the same as the receiver.
|
|
||||||
func (f FakeSigner) Equal(Signer) bool {
|
|
||||||
// Always return true
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ func TestEIP155Signing(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if from != addr {
|
if from != addr {
|
||||||
t.Errorf("exected from and address to be equal. Got %x want %x", from, addr)
|
t.Errorf("expected from and address to be equal. Got %x want %x", from, addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,6 @@ var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{
|
||||||
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
|
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
|
||||||
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
|
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
|
||||||
common.BytesToAddress([]byte{9}): &blake2F{},
|
common.BytesToAddress([]byte{9}): &blake2F{},
|
||||||
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
|
|
||||||
common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
|
common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,7 @@ func BenchmarkPrecompiledRipeMD(bench *testing.B) {
|
||||||
benchmarkPrecompiled("03", t, bench)
|
benchmarkPrecompiled("03", t, bench)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Benchmarks the sample inputs from the identiy precompile.
|
// Benchmarks the sample inputs from the identity precompile.
|
||||||
func BenchmarkPrecompiledIdentity(bench *testing.B) {
|
func BenchmarkPrecompiledIdentity(bench *testing.B) {
|
||||||
t := precompiledTest{
|
t := precompiledTest{
|
||||||
Input: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",
|
Input: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool, i
|
||||||
debug = in.evm.Config.Tracer != nil
|
debug = in.evm.Config.Tracer != nil
|
||||||
)
|
)
|
||||||
// Don't move this deferred function, it's placed before the capturestate-deferred method,
|
// Don't move this deferred function, it's placed before the capturestate-deferred method,
|
||||||
// so that it get's executed _after_: the capturestate needs the stacks before
|
// so that it gets executed _after_: the capturestate needs the stacks before
|
||||||
// they are returned to the pools
|
// they are returned to the pools
|
||||||
defer func() {
|
defer func() {
|
||||||
returnStack(stack)
|
returnStack(stack)
|
||||||
|
|
@ -411,7 +411,7 @@ func (in *EVMInterpreter) RunWithDelay(contract *Contract, input []byte, readOnl
|
||||||
debug = in.evm.Config.Tracer != nil
|
debug = in.evm.Config.Tracer != nil
|
||||||
)
|
)
|
||||||
// Don't move this deferrred function, it's placed before the capturestate-deferred method,
|
// Don't move this deferrred function, it's placed before the capturestate-deferred method,
|
||||||
// so that it get's executed _after_: the capturestate needs the stacks before
|
// so that it gets executed _after_: the capturestate needs the stacks before
|
||||||
// they are returned to the pools
|
// they are returned to the pools
|
||||||
defer func() {
|
defer func() {
|
||||||
returnStack(stack)
|
returnStack(stack)
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestJumpTableCopy tests that deep copy is necessery to prevent modify shared jump table
|
// TestJumpTableCopy tests that deep copy is necessary to prevent modify shared jump table
|
||||||
func TestJumpTableCopy(t *testing.T) {
|
func TestJumpTableCopy(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -703,7 +703,7 @@ func TestColdAccountAccessCost(t *testing.T) {
|
||||||
t.Logf("%d: %v %d", ii, op.OpName(), op.GasCost)
|
t.Logf("%d: %v %d", ii, op.OpName(), op.GasCost)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Fatalf("tescase %d, gas report wrong, step %d, have %d want %d", i, tc.step, have, want)
|
t.Fatalf("testcase %d, gas report wrong, step %d, have %d want %d", i, tc.step, have, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import (
|
||||||
// If z is equal to one the point is considered as in affine form.
|
// If z is equal to one the point is considered as in affine form.
|
||||||
type PointG2 [3]fe2
|
type PointG2 [3]fe2
|
||||||
|
|
||||||
// Set copies valeus of one point to another.
|
// Set copies values of one point to another.
|
||||||
func (p *PointG2) Set(p2 *PointG2) *PointG2 {
|
func (p *PointG2) Set(p2 *PointG2) *PointG2 {
|
||||||
p[0].set(&p2[0])
|
p[0].set(&p2[0])
|
||||||
p[1].set(&p2[1])
|
p[1].set(&p2[1])
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,8 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
|
|
||||||
eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil}
|
eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil}
|
||||||
if eth.APIBackend.allowUnprotectedTxs {
|
if eth.APIBackend.allowUnprotectedTxs {
|
||||||
log.Info("------Unprotected transactions allowed-------")
|
log.Debug(" ###########", "Unprotected transactions allowed")
|
||||||
|
|
||||||
config.TxPool.AllowUnprotectedTxs = true
|
config.TxPool.AllowUnprotectedTxs = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,6 +237,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
Preimages: config.Preimages,
|
Preimages: config.Preimages,
|
||||||
StateHistory: config.StateHistory,
|
StateHistory: config.StateHistory,
|
||||||
StateScheme: scheme,
|
StateScheme: scheme,
|
||||||
|
TriesInMemory: config.TriesInMemory,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,21 @@ func (b *EthAPIBackend) GetVoteOnHash(ctx context.Context, starBlockNr uint64, e
|
||||||
return false, fmt.Errorf("Hash mismatch: localChainHash %s, milestoneHash %s", localEndBlockHash, hash)
|
return false, fmt.Errorf("Hash mismatch: localChainHash %s, milestoneHash %s", localEndBlockHash, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ethHandler := (*ethHandler)(b.eth.handler)
|
||||||
|
|
||||||
|
bor, ok := ethHandler.chain.Engine().(*bor.Bor)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return false, fmt.Errorf("Bor not available")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = bor.HeimdallClient.FetchMilestoneID(ctx, milestoneId)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
downloader.UnlockMutex(false, "", endBlockNr, common.Hash{})
|
||||||
|
return false, fmt.Errorf("Milestone ID doesn't exist in Heimdall")
|
||||||
|
}
|
||||||
|
|
||||||
downloader.UnlockMutex(true, milestoneId, endBlockNr, localEndBlock.Hash())
|
downloader.UnlockMutex(true, milestoneId, endBlockNr, localEndBlock.Hash())
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
|
||||||
|
|
@ -620,7 +620,7 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td, ttd *
|
||||||
// For non-merged networks, if there is a checkpoint available, then calculate
|
// For non-merged networks, if there is a checkpoint available, then calculate
|
||||||
// the ancientLimit through that. Otherwise calculate the ancient limit through
|
// the ancientLimit through that. Otherwise calculate the ancient limit through
|
||||||
// the advertised height of the remote peer. This most is mostly a fallback for
|
// the advertised height of the remote peer. This most is mostly a fallback for
|
||||||
// legacy networks, but should eventually be droppped. TODO(karalabe).
|
// legacy networks, but should eventually be dropped. TODO(karalabe).
|
||||||
if beaconMode {
|
if beaconMode {
|
||||||
// Beacon sync, use the latest finalized block as the ancient limit
|
// Beacon sync, use the latest finalized block as the ancient limit
|
||||||
// or a reasonable height if no finalized block is yet announced.
|
// or a reasonable height if no finalized block is yet announced.
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ func (r *resultStore) HasCompletedItems() bool {
|
||||||
// countCompleted returns the number of items ready for delivery, stopping at
|
// countCompleted returns the number of items ready for delivery, stopping at
|
||||||
// the first non-complete item.
|
// the first non-complete item.
|
||||||
//
|
//
|
||||||
// The mthod assumes (at least) rlock is held.
|
// The method assumes (at least) rlock is held.
|
||||||
func (r *resultStore) countCompleted() int {
|
func (r *resultStore) countCompleted() int {
|
||||||
// We iterate from the already known complete point, and see
|
// We iterate from the already known complete point, and see
|
||||||
// if any more has completed since last count
|
// if any more has completed since last count
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@ func (m *milestone) enqueueFutureMilestone(key uint64, hash common.Hash) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("Enqueing new future milestone", "endBlockNumber", key, "futureMilestoneHash", hash)
|
log.Debug("Enqueuing new future milestone", "endBlockNumber", key, "futureMilestoneHash", hash)
|
||||||
|
|
||||||
m.FutureMilestoneList[key] = hash
|
m.FutureMilestoneList[key] = hash
|
||||||
m.FutureMilestoneOrder = append(m.FutureMilestoneOrder, key)
|
m.FutureMilestoneOrder = append(m.FutureMilestoneOrder, key)
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ func isValidChain(currentHeader *types.Header, chain []*types.Header, doExist bo
|
||||||
pastChain, _ := splitChain(current, chain)
|
pastChain, _ := splitChain(current, chain)
|
||||||
|
|
||||||
// Iterate over the chain and validate against the last milestone
|
// Iterate over the chain and validate against the last milestone
|
||||||
// It will handle all cases when the incoming chain has atleast one milestone
|
// It will handle all cases when the incoming chain has at least one milestone
|
||||||
for i := len(pastChain) - 1; i >= 0; i-- {
|
for i := len(pastChain) - 1; i >= 0; i-- {
|
||||||
if pastChain[i].Number.Uint64() == number {
|
if pastChain[i].Number.Uint64() == number {
|
||||||
res := pastChain[i].Hash() == hash
|
res := pastChain[i].Hash() == hash
|
||||||
|
|
@ -205,7 +205,7 @@ func isValidChain(currentHeader *types.Header, chain []*types.Header, doExist bo
|
||||||
|
|
||||||
// FIXME: remoteHeader is not used
|
// FIXME: remoteHeader is not used
|
||||||
func isValidPeer(fetchHeadersByNumber func(number uint64, amount int, skip int, reverse bool) ([]*types.Header, []common.Hash, error), doExist bool, number uint64, hash common.Hash) (bool, error) {
|
func isValidPeer(fetchHeadersByNumber func(number uint64, amount int, skip int, reverse bool) ([]*types.Header, []common.Hash, error), doExist bool, number uint64, hash common.Hash) (bool, error) {
|
||||||
// Check for availaibility of the last milestone block.
|
// Check for availability of the last milestone block.
|
||||||
// This can be also be empty if our heimdall is not responding
|
// This can be also be empty if our heimdall is not responding
|
||||||
// or we're running without it.
|
// or we're running without it.
|
||||||
if !doExist {
|
if !doExist {
|
||||||
|
|
|
||||||
|
|
@ -240,13 +240,13 @@ func TestMilestone(t *testing.T) {
|
||||||
require.Equal(t, order[0], uint64(16), "expected number to be 16 but got", order[0])
|
require.Equal(t, order[0], uint64(16), "expected number to be 16 but got", order[0])
|
||||||
require.Equal(t, list[order[0]], common.Hash{16}, "expected value is", common.Hash{16}.String()[2:], "but got", list[order[0]])
|
require.Equal(t, list[order[0]], common.Hash{16}, "expected value is", common.Hash{16}.String()[2:], "but got", list[order[0]])
|
||||||
|
|
||||||
capicity := milestone.MaxCapacity
|
capacity := milestone.MaxCapacity
|
||||||
for i := 16; i <= 16*(capicity+1); i = i + 16 {
|
for i := 16; i <= 16*(capacity+1); i = i + 16 {
|
||||||
s.ProcessFutureMilestone(uint64(i), common.Hash{16})
|
s.ProcessFutureMilestone(uint64(i), common.Hash{16})
|
||||||
}
|
}
|
||||||
|
|
||||||
require.Equal(t, len(milestone.FutureMilestoneOrder), capicity, "expected length is", capicity)
|
require.Equal(t, len(milestone.FutureMilestoneOrder), capacity, "expected length is", capacity)
|
||||||
require.Equal(t, milestone.FutureMilestoneOrder[capicity-1], uint64(16*capicity), "expected value is", uint64(16*capicity), "but got", milestone.FutureMilestoneOrder[capicity-1])
|
require.Equal(t, milestone.FutureMilestoneOrder[capacity-1], uint64(16*capacity), "expected value is", uint64(16*capacity), "but got", milestone.FutureMilestoneOrder[capacity-1])
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestIsValidPeer checks the IsValidPeer function in isolation
|
// TestIsValidPeer checks the IsValidPeer function in isolation
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ var (
|
||||||
// Request is a pending request to allow tracking it and delivering a response
|
// Request is a pending request to allow tracking it and delivering a response
|
||||||
// back to the requester on their chosen channel.
|
// back to the requester on their chosen channel.
|
||||||
type Request struct {
|
type Request struct {
|
||||||
peer *Peer // Peer to which this request belogs for untracking
|
peer *Peer // Peer to which this request belongs for untracking
|
||||||
id uint64 // Request ID to match up replies to
|
id uint64 // Request ID to match up replies to
|
||||||
|
|
||||||
sink chan *Response // Channel to deliver the response on
|
sink chan *Response // Channel to deliver the response on
|
||||||
|
|
@ -228,7 +228,7 @@ func (p *Peer) dispatcher() {
|
||||||
switch {
|
switch {
|
||||||
case res.Req == nil:
|
case res.Req == nil:
|
||||||
// Response arrived with an untracked ID. Since even cancelled
|
// Response arrived with an untracked ID. Since even cancelled
|
||||||
// requests are tracked until fulfilment, a dangling response
|
// requests are tracked until fulfillment, a dangling response
|
||||||
// means the remote peer implements the protocol badly.
|
// means the remote peer implements the protocol badly.
|
||||||
resOp.fail <- errDanglingResponse
|
resOp.fail <- errDanglingResponse
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ type Peer struct {
|
||||||
txBroadcast chan []common.Hash // Channel used to queue transaction propagation requests
|
txBroadcast chan []common.Hash // Channel used to queue transaction propagation requests
|
||||||
txAnnounce chan []common.Hash // Channel used to queue transaction announcement requests
|
txAnnounce chan []common.Hash // Channel used to queue transaction announcement requests
|
||||||
|
|
||||||
reqDispatch chan *request // Dispatch channel to send requests and track then until fulfilment
|
reqDispatch chan *request // Dispatch channel to send requests and track then until fulfillment
|
||||||
reqCancel chan *cancel // Dispatch channel to cancel pending requests and untrack them
|
reqCancel chan *cancel // Dispatch channel to cancel pending requests and untrack them
|
||||||
resDispatch chan *response // Dispatch channel to fulfil pending requests and untrack them
|
resDispatch chan *response // Dispatch channel to fulfil pending requests and untrack them
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ type TraceBlockRequest struct {
|
||||||
Config *TraceConfig
|
Config *TraceConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// If you use context as first parameter this function gets exposed automaticall on rpc endpoint
|
// If you use context as first parameter this function gets exposed automatically on rpc endpoint
|
||||||
func (api *API) TraceBorBlock(req *TraceBlockRequest) (*BlockTraceResult, error) {
|
func (api *API) TraceBorBlock(req *TraceBlockRequest) (*BlockTraceResult, error) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@
|
||||||
return this.finalize(result);
|
return this.finalize(result);
|
||||||
},
|
},
|
||||||
|
|
||||||
// finalize recreates a call object using the final desired field oder for json
|
// finalize recreates a call object using the final desired field order for json
|
||||||
// serialization. This is a nicety feature to pass meaningfully ordered results
|
// serialization. This is a nicety feature to pass meaningfully ordered results
|
||||||
// to users who don't interpret it, just display it.
|
// to users who don't interpret it, just display it.
|
||||||
finalize: function(call) {
|
finalize: function(call) {
|
||||||
|
|
|
||||||
|
|
@ -135,9 +135,9 @@ func TestMemCopying(t *testing.T) {
|
||||||
{0, 100, 0, "", 0}, // No need to pad (0 size)
|
{0, 100, 0, "", 0}, // No need to pad (0 size)
|
||||||
{100, 50, 100, "", 100}, // Should pad 100-150
|
{100, 50, 100, "", 100}, // Should pad 100-150
|
||||||
{100, 50, 5, "", 5}, // Wanted range fully within memory
|
{100, 50, 5, "", 5}, // Wanted range fully within memory
|
||||||
{100, -50, 0, "offset or size must not be negative", 0}, // Errror
|
{100, -50, 0, "offset or size must not be negative", 0}, // Error
|
||||||
{0, 1, 1024*1024 + 1, "reached limit for padding memory slice: 1048578", 0}, // Errror
|
{0, 1, 1024*1024 + 1, "reached limit for padding memory slice: 1048578", 0}, // Error
|
||||||
{10, 0, 1024*1024 + 100, "reached limit for padding memory slice: 1048666", 0}, // Errror
|
{10, 0, 1024*1024 + 100, "reached limit for padding memory slice: 1048666", 0}, // Error
|
||||||
|
|
||||||
} {
|
} {
|
||||||
mem := vm.NewMemory()
|
mem := vm.NewMemory()
|
||||||
|
|
|
||||||
|
|
@ -497,7 +497,7 @@ func TestOverrideAccountMarshal(t *testing.T) {
|
||||||
|
|
||||||
om := map[common.Address]OverrideAccount{
|
om := map[common.Address]OverrideAccount{
|
||||||
{0x11}: {
|
{0x11}: {
|
||||||
// Zero-valued nonce is not overriddden, but simply dropped by the encoder.
|
// Zero-valued nonce is not overridden, but simply dropped by the encoder.
|
||||||
Nonce: 0,
|
Nonce: 0,
|
||||||
},
|
},
|
||||||
{0xaa}: {
|
{0xaa}: {
|
||||||
|
|
|
||||||
|
|
@ -1194,7 +1194,7 @@ func (c *CallResult) Status() hexutil.Uint64 {
|
||||||
func (b *Block) Call(ctx context.Context, args struct {
|
func (b *Block) Call(ctx context.Context, args struct {
|
||||||
Data ethapi.TransactionArgs
|
Data ethapi.TransactionArgs
|
||||||
}) (*CallResult, error) {
|
}) (*CallResult, error) {
|
||||||
result, err := ethapi.DoCall(ctx, b.r.backend, args.Data, *b.numberOrHash, nil, nil, b.r.backend.RPCEVMTimeout(), b.r.backend.RPCGasCap())
|
result, err := ethapi.DoCall(ctx, b.r.backend, args.Data, *b.numberOrHash, nil, nil, nil, b.r.backend.RPCEVMTimeout(), b.r.backend.RPCGasCap())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -1257,7 +1257,7 @@ func (p *Pending) Call(ctx context.Context, args struct {
|
||||||
Data ethapi.TransactionArgs
|
Data ethapi.TransactionArgs
|
||||||
}) (*CallResult, error) {
|
}) (*CallResult, error) {
|
||||||
pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
|
pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
|
||||||
result, err := ethapi.DoCall(ctx, p.r.backend, args.Data, pendingBlockNr, nil, nil, p.r.backend.RPCEVMTimeout(), p.r.backend.RPCGasCap())
|
result, err := ethapi.DoCall(ctx, p.r.backend, args.Data, pendingBlockNr, nil, nil, nil, p.r.backend.RPCEVMTimeout(), p.r.backend.RPCGasCap())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -368,7 +368,7 @@ func (i *SliceStringFlag) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *SliceStringFlag) Set(value string) error {
|
func (i *SliceStringFlag) Set(value string) error {
|
||||||
// overwritting insted of appending
|
// overwriting instead of appending
|
||||||
*i.Value = SplitAndTrim(value)
|
*i.Value = SplitAndTrim(value)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,9 @@ var amoyTestnet = &Chain{
|
||||||
LondonBlock: big.NewInt(73100),
|
LondonBlock: big.NewInt(73100),
|
||||||
ShanghaiBlock: big.NewInt(73100),
|
ShanghaiBlock: big.NewInt(73100),
|
||||||
Bor: ¶ms.BorConfig{
|
Bor: ¶ms.BorConfig{
|
||||||
JaipurBlock: big.NewInt(73100),
|
JaipurBlock: big.NewInt(73100),
|
||||||
DelhiBlock: big.NewInt(73100),
|
DelhiBlock: big.NewInt(73100),
|
||||||
ParallelUniverseBlock: nil,
|
IndoreBlock: big.NewInt(73100),
|
||||||
IndoreBlock: big.NewInt(73100),
|
|
||||||
StateSyncConfirmationDelay: map[string]uint64{
|
StateSyncConfirmationDelay: map[string]uint64{
|
||||||
"0": 128,
|
"0": 128,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,9 @@ var mainnetBor = &Chain{
|
||||||
LondonBlock: big.NewInt(23850000),
|
LondonBlock: big.NewInt(23850000),
|
||||||
ShanghaiBlock: big.NewInt(50523000),
|
ShanghaiBlock: big.NewInt(50523000),
|
||||||
Bor: ¶ms.BorConfig{
|
Bor: ¶ms.BorConfig{
|
||||||
JaipurBlock: big.NewInt(23850000),
|
JaipurBlock: big.NewInt(23850000),
|
||||||
DelhiBlock: big.NewInt(38189056),
|
DelhiBlock: big.NewInt(38189056),
|
||||||
ParallelUniverseBlock: big.NewInt(0),
|
IndoreBlock: big.NewInt(44934656),
|
||||||
IndoreBlock: big.NewInt(44934656),
|
|
||||||
StateSyncConfirmationDelay: map[string]uint64{
|
StateSyncConfirmationDelay: map[string]uint64{
|
||||||
"44934656": 128,
|
"44934656": 128,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,9 @@ var mumbaiTestnet = &Chain{
|
||||||
LondonBlock: big.NewInt(22640000),
|
LondonBlock: big.NewInt(22640000),
|
||||||
ShanghaiBlock: big.NewInt(41874000),
|
ShanghaiBlock: big.NewInt(41874000),
|
||||||
Bor: ¶ms.BorConfig{
|
Bor: ¶ms.BorConfig{
|
||||||
JaipurBlock: big.NewInt(22770000),
|
JaipurBlock: big.NewInt(22770000),
|
||||||
DelhiBlock: big.NewInt(29638656),
|
DelhiBlock: big.NewInt(29638656),
|
||||||
ParallelUniverseBlock: big.NewInt(0),
|
IndoreBlock: big.NewInt(37075456),
|
||||||
IndoreBlock: big.NewInt(37075456),
|
|
||||||
StateSyncConfirmationDelay: map[string]uint64{
|
StateSyncConfirmationDelay: map[string]uint64{
|
||||||
"37075456": 128,
|
"37075456": 128,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,6 @@
|
||||||
},
|
},
|
||||||
"jaipurBlock": 22770000,
|
"jaipurBlock": 22770000,
|
||||||
"delhiBlock": 29638656,
|
"delhiBlock": 29638656,
|
||||||
"parallelUniverseBlock": 0,
|
|
||||||
"indoreBlock": 37075456,
|
"indoreBlock": 37075456,
|
||||||
"stateSyncConfirmationDelay": {
|
"stateSyncConfirmationDelay": {
|
||||||
"37075456": 128
|
"37075456": 128
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@
|
||||||
},
|
},
|
||||||
"jaipurBlock":22770000,
|
"jaipurBlock":22770000,
|
||||||
"delhiBlock": 29638656,
|
"delhiBlock": 29638656,
|
||||||
"parallelUniverseBlock": 0,
|
|
||||||
"indoreBlock": 37075456,
|
"indoreBlock": 37075456,
|
||||||
"stateSyncConfirmationDelay": {
|
"stateSyncConfirmationDelay": {
|
||||||
"37075456": 128
|
"37075456": 128
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ func (c *Command) extractFlags(args []string) error {
|
||||||
|
|
||||||
log.Warn("Config set via config file will be overridden by cli flags")
|
log.Warn("Config set via config file will be overridden by cli flags")
|
||||||
|
|
||||||
// Initialse a flagset based on the config created above
|
// Initialise a flagset based on the config created above
|
||||||
flags := c.Flags(cfg)
|
flags := c.Flags(cfg)
|
||||||
|
|
||||||
// Check for explicit cli args
|
// Check for explicit cli args
|
||||||
|
|
|
||||||
|
|
@ -42,22 +42,3 @@ func TestConfigLegacy(t *testing.T) {
|
||||||
readFile("./testdata/test.toml")
|
readFile("./testdata/test.toml")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefaultConfigLegacy(t *testing.T) {
|
|
||||||
readFile := func(path string) {
|
|
||||||
expectedConfig, err := readLegacyConfig(path)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
testConfig := DefaultConfig()
|
|
||||||
|
|
||||||
testConfig.Identity = "Polygon-Devs"
|
|
||||||
testConfig.DataDir = "/var/lib/bor"
|
|
||||||
|
|
||||||
assert.Equal(t, expectedConfig, testConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// read file in hcl format
|
|
||||||
t.Run("toml", func(t *testing.T) {
|
|
||||||
readFile("./testdata/default.toml")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
||||||
193
internal/cli/server/testdata/default.toml
vendored
193
internal/cli/server/testdata/default.toml
vendored
|
|
@ -1,193 +0,0 @@
|
||||||
chain = "mainnet"
|
|
||||||
identity = "Polygon-Devs"
|
|
||||||
verbosity = 3
|
|
||||||
log-level = ""
|
|
||||||
vmdebug = false
|
|
||||||
datadir = "/var/lib/bor"
|
|
||||||
ancient = ""
|
|
||||||
"db.engine" = "leveldb"
|
|
||||||
keystore = ""
|
|
||||||
"rpc.batchlimit" = 100
|
|
||||||
"rpc.returndatalimit" = 100000
|
|
||||||
syncmode = "full"
|
|
||||||
gcmode = "full"
|
|
||||||
snapshot = true
|
|
||||||
"bor.logs" = false
|
|
||||||
ethstats = ""
|
|
||||||
devfakeauthor = false
|
|
||||||
|
|
||||||
["eth.requiredblocks"]
|
|
||||||
|
|
||||||
[log]
|
|
||||||
vmodule = ""
|
|
||||||
json = false
|
|
||||||
backtrace = ""
|
|
||||||
debug = false
|
|
||||||
|
|
||||||
[p2p]
|
|
||||||
maxpeers = 50
|
|
||||||
maxpendpeers = 50
|
|
||||||
bind = "0.0.0.0"
|
|
||||||
port = 30303
|
|
||||||
nodiscover = false
|
|
||||||
nat = "any"
|
|
||||||
netrestrict = ""
|
|
||||||
nodekey = ""
|
|
||||||
nodekeyhex = ""
|
|
||||||
txarrivalwait = "500ms"
|
|
||||||
[p2p.discovery]
|
|
||||||
v4disc = true
|
|
||||||
v5disc = false
|
|
||||||
bootnodes = []
|
|
||||||
bootnodesv4 = []
|
|
||||||
bootnodesv5 = []
|
|
||||||
static-nodes = []
|
|
||||||
trusted-nodes = []
|
|
||||||
dns = []
|
|
||||||
|
|
||||||
[heimdall]
|
|
||||||
url = "http://localhost:1317"
|
|
||||||
"bor.without" = false
|
|
||||||
grpc-address = ""
|
|
||||||
"bor.runheimdall" = false
|
|
||||||
"bor.runheimdallargs" = ""
|
|
||||||
"bor.useheimdallapp" = false
|
|
||||||
|
|
||||||
[txpool]
|
|
||||||
locals = []
|
|
||||||
nolocals = false
|
|
||||||
journal = "transactions.rlp"
|
|
||||||
rejournal = "1h0m0s"
|
|
||||||
pricelimit = 1
|
|
||||||
pricebump = 10
|
|
||||||
accountslots = 16
|
|
||||||
globalslots = 32768
|
|
||||||
accountqueue = 16
|
|
||||||
globalqueue = 32768
|
|
||||||
lifetime = "3h0m0s"
|
|
||||||
|
|
||||||
[miner]
|
|
||||||
mine = false
|
|
||||||
etherbase = ""
|
|
||||||
extradata = ""
|
|
||||||
gaslimit = 30000000
|
|
||||||
gasprice = "1000000000"
|
|
||||||
recommit = "2m5s"
|
|
||||||
commitinterrupt = true
|
|
||||||
|
|
||||||
[jsonrpc]
|
|
||||||
ipcdisable = false
|
|
||||||
ipcpath = ""
|
|
||||||
gascap = 50000000
|
|
||||||
evmtimeout = "5s"
|
|
||||||
txfeecap = 1.0
|
|
||||||
allow-unprotected-txs = false
|
|
||||||
enabledeprecatedpersonal = false
|
|
||||||
[jsonrpc.http]
|
|
||||||
enabled = false
|
|
||||||
port = 8545
|
|
||||||
prefix = ""
|
|
||||||
host = "localhost"
|
|
||||||
api = ["eth", "net", "web3", "txpool", "bor"]
|
|
||||||
vhosts = ["localhost"]
|
|
||||||
corsdomain = ["localhost"]
|
|
||||||
ep-size = 40
|
|
||||||
ep-requesttimeout = "0s"
|
|
||||||
[jsonrpc.ws]
|
|
||||||
enabled = false
|
|
||||||
port = 8546
|
|
||||||
prefix = ""
|
|
||||||
host = "localhost"
|
|
||||||
api = ["net", "web3"]
|
|
||||||
origins = ["localhost"]
|
|
||||||
ep-size = 40
|
|
||||||
ep-requesttimeout = "0s"
|
|
||||||
[jsonrpc.graphql]
|
|
||||||
enabled = false
|
|
||||||
port = 0
|
|
||||||
prefix = ""
|
|
||||||
host = ""
|
|
||||||
vhosts = ["localhost"]
|
|
||||||
corsdomain = ["localhost"]
|
|
||||||
ep-size = 0
|
|
||||||
ep-requesttimeout = ""
|
|
||||||
[jsonrpc.auth]
|
|
||||||
jwtsecret = ""
|
|
||||||
addr = "localhost"
|
|
||||||
port = 8551
|
|
||||||
vhosts = ["localhost"]
|
|
||||||
[jsonrpc.timeouts]
|
|
||||||
read = "10s"
|
|
||||||
write = "30s"
|
|
||||||
idle = "2m0s"
|
|
||||||
|
|
||||||
[gpo]
|
|
||||||
blocks = 20
|
|
||||||
percentile = 60
|
|
||||||
maxheaderhistory = 1024
|
|
||||||
maxblockhistory = 1024
|
|
||||||
maxprice = "500000000000"
|
|
||||||
ignoreprice = "2"
|
|
||||||
|
|
||||||
[telemetry]
|
|
||||||
metrics = false
|
|
||||||
expensive = false
|
|
||||||
prometheus-addr = "127.0.0.1:7071"
|
|
||||||
opencollector-endpoint = ""
|
|
||||||
[telemetry.influx]
|
|
||||||
influxdb = false
|
|
||||||
endpoint = ""
|
|
||||||
database = ""
|
|
||||||
username = ""
|
|
||||||
password = ""
|
|
||||||
influxdbv2 = false
|
|
||||||
token = ""
|
|
||||||
bucket = ""
|
|
||||||
organization = ""
|
|
||||||
[telemetry.influx.tags]
|
|
||||||
|
|
||||||
[cache]
|
|
||||||
cache = 1024
|
|
||||||
gc = 25
|
|
||||||
snapshot = 10
|
|
||||||
database = 50
|
|
||||||
trie = 15
|
|
||||||
noprefetch = false
|
|
||||||
preimages = false
|
|
||||||
txlookuplimit = 2350000
|
|
||||||
triesinmemory = 128
|
|
||||||
blocklogs = 32
|
|
||||||
timeout = "1h0m0s"
|
|
||||||
fdlimit = 0
|
|
||||||
|
|
||||||
[leveldb]
|
|
||||||
compactiontablesize = 2
|
|
||||||
compactiontablesizemultiplier = 1.0
|
|
||||||
compactiontotalsize = 10
|
|
||||||
compactiontotalsizemultiplier = 10.0
|
|
||||||
|
|
||||||
[accounts]
|
|
||||||
unlock = []
|
|
||||||
password = ""
|
|
||||||
allow-insecure-unlock = false
|
|
||||||
lightkdf = false
|
|
||||||
disable-bor-wallet = true
|
|
||||||
|
|
||||||
[grpc]
|
|
||||||
addr = ":3131"
|
|
||||||
|
|
||||||
[developer]
|
|
||||||
dev = false
|
|
||||||
period = 0
|
|
||||||
gaslimit = 11500000
|
|
||||||
|
|
||||||
[parallelevm]
|
|
||||||
enable = true
|
|
||||||
procs = 8
|
|
||||||
|
|
||||||
[pprof]
|
|
||||||
pprof = false
|
|
||||||
port = 6060
|
|
||||||
addr = "127.0.0.1"
|
|
||||||
memprofilerate = 524288
|
|
||||||
blockprofilerate = 0
|
|
||||||
|
|
@ -703,8 +703,12 @@ func (s *BlockChainAPI) GetTransactionReceiptsByBlock(ctx context.Context, block
|
||||||
for idx, receipt := range receipts {
|
for idx, receipt := range receipts {
|
||||||
tx := txs[idx]
|
tx := txs[idx]
|
||||||
|
|
||||||
// Derive the sender.
|
var signer types.Signer = types.FrontierSigner{}
|
||||||
signer := types.MakeSigner(s.b.ChainConfig(), block.Number(), block.Time())
|
|
||||||
|
if tx.Protected() {
|
||||||
|
signer = types.NewEIP155Signer(tx.ChainId())
|
||||||
|
}
|
||||||
|
|
||||||
from, _ := types.Sender(signer, tx)
|
from, _ := types.Sender(signer, tx)
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
fields := map[string]interface{}{
|
||||||
|
|
@ -720,11 +724,6 @@ func (s *BlockChainAPI) GetTransactionReceiptsByBlock(ctx context.Context, block
|
||||||
"logs": receipt.Logs,
|
"logs": receipt.Logs,
|
||||||
"logsBloom": receipt.Bloom,
|
"logsBloom": receipt.Bloom,
|
||||||
"type": hexutil.Uint(tx.Type()),
|
"type": hexutil.Uint(tx.Type()),
|
||||||
"effectiveGasPrice": (*hexutil.Big)(receipt.EffectiveGasPrice),
|
|
||||||
}
|
|
||||||
|
|
||||||
if receipt.EffectiveGasPrice == nil {
|
|
||||||
fields["effectiveGasPrice"] = new(hexutil.Big)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign receipt status or post state.
|
// Assign receipt status or post state.
|
||||||
|
|
@ -735,7 +734,7 @@ func (s *BlockChainAPI) GetTransactionReceiptsByBlock(ctx context.Context, block
|
||||||
}
|
}
|
||||||
|
|
||||||
if receipt.Logs == nil {
|
if receipt.Logs == nil {
|
||||||
fields["logs"] = []*types.Log{}
|
fields["logs"] = [][]*types.Log{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if borReceipt != nil && idx == len(receipts)-1 {
|
if borReceipt != nil && idx == len(receipts)-1 {
|
||||||
|
|
@ -1299,12 +1298,31 @@ func doCallWithState(ctx context.Context, b Backend, args TransactionArgs, heade
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
|
func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, state *state.StateDB, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
|
||||||
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
|
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
|
||||||
|
|
||||||
state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
var (
|
||||||
if state == nil || err != nil {
|
header *types.Header
|
||||||
return nil, err
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
// BOR: This is used by bor consensus to fetch data from genesis contracts for state-sync
|
||||||
|
// Fetch the state and header from blockNumberOrHash if it's coming from normal eth_call path.
|
||||||
|
if state == nil {
|
||||||
|
state, header, err = b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
||||||
|
if state == nil || err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Fetch the header from the given blockNumberOrHash. Note that this path is only taken
|
||||||
|
// when we're doing a call from bor consensus to fetch data from genesis contracts. It's
|
||||||
|
// necessary to fetch header using header hash as we might be experiencing a reorg and there
|
||||||
|
// can be multiple headers with same number.
|
||||||
|
header, err = b.HeaderByHash(ctx, *blockNrOrHash.BlockHash)
|
||||||
|
if header == nil || err != nil {
|
||||||
|
log.Warn("Error fetching header on CallWithState", "err", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return doCall(ctx, b, args, state, header, overrides, blockOverrides, timeout, globalGasCap)
|
return doCall(ctx, b, args, state, header, overrides, blockOverrides, timeout, globalGasCap)
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ func doMigrateFlags(ctx *cli.Context) {
|
||||||
for _, parent := range ctx.Lineage()[1:] {
|
for _, parent := range ctx.Lineage()[1:] {
|
||||||
if parent.IsSet(name) {
|
if parent.IsSet(name) {
|
||||||
// When iterating across the lineage, we will be served both
|
// When iterating across the lineage, we will be served both
|
||||||
// the 'canon' and alias formats of all commmands. In most cases,
|
// the 'canon' and alias formats of all commands. In most cases,
|
||||||
// it's fine to set it in the ctx multiple times (one for each
|
// it's fine to set it in the ctx multiple times (one for each
|
||||||
// name), however, the Slice-flags are not fine.
|
// name), however, the Slice-flags are not fine.
|
||||||
// The slice-flags accumulate, so if we set it once as
|
// The slice-flags accumulate, so if we set it once as
|
||||||
|
|
|
||||||
|
|
@ -2031,7 +2031,7 @@ var fromAscii = function(str) {
|
||||||
*
|
*
|
||||||
* @method transformToFullName
|
* @method transformToFullName
|
||||||
* @param {Object} json-abi
|
* @param {Object} json-abi
|
||||||
* @return {String} full fnction/event name
|
* @return {String} full function/event name
|
||||||
*/
|
*/
|
||||||
var transformToFullName = function (json) {
|
var transformToFullName = function (json) {
|
||||||
if (json.name.indexOf('(') !== -1) {
|
if (json.name.indexOf('(') !== -1) {
|
||||||
|
|
@ -2089,7 +2089,7 @@ var fromDecimal = function (value) {
|
||||||
/**
|
/**
|
||||||
* Auto converts any given value into it's hex representation.
|
* Auto converts any given value into it's hex representation.
|
||||||
*
|
*
|
||||||
* And even stringifys objects before.
|
* And even stringifies objects before.
|
||||||
*
|
*
|
||||||
* @method toHex
|
* @method toHex
|
||||||
* @param {String|Number|BigNumber|Object}
|
* @param {String|Number|BigNumber|Object}
|
||||||
|
|
@ -2361,7 +2361,7 @@ var isFunction = function (object) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if object is Objet, otherwise false
|
* Returns true if object is Object, otherwise false
|
||||||
*
|
*
|
||||||
* @method isObject
|
* @method isObject
|
||||||
* @param {Object}
|
* @param {Object}
|
||||||
|
|
@ -2757,7 +2757,7 @@ var Batch = function (web3) {
|
||||||
* Should be called to add create new request to batch request
|
* Should be called to add create new request to batch request
|
||||||
*
|
*
|
||||||
* @method add
|
* @method add
|
||||||
* @param {Object} jsonrpc requet object
|
* @param {Object} jsonrpc request object
|
||||||
*/
|
*/
|
||||||
Batch.prototype.add = function (request) {
|
Batch.prototype.add = function (request) {
|
||||||
this.requests.push(request);
|
this.requests.push(request);
|
||||||
|
|
@ -4557,7 +4557,7 @@ Iban.createIndirect = function (options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thos method should be used to check if given string is valid iban object
|
* This method should be used to check if given string is valid iban object
|
||||||
*
|
*
|
||||||
* @method isValid
|
* @method isValid
|
||||||
* @param {String} iban string
|
* @param {String} iban string
|
||||||
|
|
@ -6721,7 +6721,7 @@ var exchangeAbi = require('../contracts/SmartExchange.json');
|
||||||
* @method transfer
|
* @method transfer
|
||||||
* @param {String} from
|
* @param {String} from
|
||||||
* @param {String} to iban
|
* @param {String} to iban
|
||||||
* @param {Value} value to be tranfered
|
* @param {Value} value to be transferred
|
||||||
* @param {Function} callback, callback
|
* @param {Function} callback, callback
|
||||||
*/
|
*/
|
||||||
var transfer = function (eth, from, to, value, callback) {
|
var transfer = function (eth, from, to, value, callback) {
|
||||||
|
|
@ -6751,7 +6751,7 @@ var transfer = function (eth, from, to, value, callback) {
|
||||||
* @method transferToAddress
|
* @method transferToAddress
|
||||||
* @param {String} from
|
* @param {String} from
|
||||||
* @param {String} to
|
* @param {String} to
|
||||||
* @param {Value} value to be tranfered
|
* @param {Value} value to be transferred
|
||||||
* @param {Function} callback, callback
|
* @param {Function} callback, callback
|
||||||
*/
|
*/
|
||||||
var transferToAddress = function (eth, from, to, value, callback) {
|
var transferToAddress = function (eth, from, to, value, callback) {
|
||||||
|
|
@ -7105,7 +7105,7 @@ module.exports = transfer;
|
||||||
/**
|
/**
|
||||||
* Initializes a newly created cipher.
|
* Initializes a newly created cipher.
|
||||||
*
|
*
|
||||||
* @param {number} xformMode Either the encryption or decryption transormation mode constant.
|
* @param {number} xformMode Either the encryption or decryption transformation mode constant.
|
||||||
* @param {WordArray} key The key.
|
* @param {WordArray} key The key.
|
||||||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||||||
*
|
*
|
||||||
|
|
@ -9459,7 +9459,7 @@ module.exports = transfer;
|
||||||
var M_offset_14 = M[offset + 14];
|
var M_offset_14 = M[offset + 14];
|
||||||
var M_offset_15 = M[offset + 15];
|
var M_offset_15 = M[offset + 15];
|
||||||
|
|
||||||
// Working varialbes
|
// Working variables
|
||||||
var a = H[0];
|
var a = H[0];
|
||||||
var b = H[1];
|
var b = H[1];
|
||||||
var c = H[2];
|
var c = H[2];
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,6 @@ func TestUpdateTimer(t *testing.T) {
|
||||||
}
|
}
|
||||||
timer = NewUpdateTimer(sim, 0)
|
timer = NewUpdateTimer(sim, 0)
|
||||||
if updated := timer.Update(func(diff time.Duration) bool { return true }); !updated {
|
if updated := timer.Update(func(diff time.Duration) bool { return true }); !updated {
|
||||||
t.Fatalf("Doesn't update the clock without threshold limitaion")
|
t.Fatalf("Doesn't update the clock without threshold limitation")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ on log level.
|
||||||
|
|
||||||
# Error Handling
|
# Error Handling
|
||||||
|
|
||||||
Becasuse log15 allows you to step around the type system, there are a few ways you can specify
|
Because log15 allows you to step around the type system, there are a few ways you can specify
|
||||||
invalid arguments to the logging functions. You could, for example, wrap something that is not
|
invalid arguments to the logging functions. You could, for example, wrap something that is not
|
||||||
a zero-argument function with log.Lazy or pass a context key that is not a string. Since logging libraries
|
a zero-argument function with log.Lazy or pass a context key that is not a string. Since logging libraries
|
||||||
are typically the mechanism by which errors are reported, it would be onerous for the logging functions
|
are typically the mechanism by which errors are reported, it would be onerous for the logging functions
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ var stackEnabled atomic.Bool
|
||||||
// should append the log locations too when printing entries.
|
// should append the log locations too when printing entries.
|
||||||
var locationEnabled atomic.Bool
|
var locationEnabled atomic.Bool
|
||||||
|
|
||||||
// locationLength is the maxmimum path length encountered, which all logs are
|
// locationLength is the maximum path length encountered, which all logs are
|
||||||
// padded to to aid in alignment.
|
// padded to to aid in alignment.
|
||||||
var locationLength atomic.Uint32
|
var locationLength atomic.Uint32
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,23 +55,23 @@ func TestBuildPayload(t *testing.T) {
|
||||||
verify := func(outer *engine.ExecutionPayloadEnvelope, txs int) {
|
verify := func(outer *engine.ExecutionPayloadEnvelope, txs int) {
|
||||||
payload := outer.ExecutionPayload
|
payload := outer.ExecutionPayload
|
||||||
if payload.ParentHash != b.chain.CurrentBlock().Hash() {
|
if payload.ParentHash != b.chain.CurrentBlock().Hash() {
|
||||||
t.Fatal("Unexpect parent hash")
|
t.Fatal("Unexpected parent hash")
|
||||||
}
|
}
|
||||||
|
|
||||||
if payload.Random != (common.Hash{}) {
|
if payload.Random != (common.Hash{}) {
|
||||||
t.Fatal("Unexpect random value")
|
t.Fatal("Unexpected random value")
|
||||||
}
|
}
|
||||||
|
|
||||||
if payload.Timestamp != timestamp {
|
if payload.Timestamp != timestamp {
|
||||||
t.Fatal("Unexpect timestamp")
|
t.Fatal("Unexpected timestamp")
|
||||||
}
|
}
|
||||||
|
|
||||||
if payload.FeeRecipient != recipient {
|
if payload.FeeRecipient != recipient {
|
||||||
t.Fatal("Unexpect fee recipient")
|
t.Fatal("Unexpected fee recipient")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(payload.Transactions) != txs {
|
if len(payload.Transactions) != txs {
|
||||||
t.Fatal("Unexpect transaction set")
|
t.Fatal("Unexpected transaction set")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
empty := payload.ResolveEmpty()
|
empty := payload.ResolveEmpty()
|
||||||
|
|
|
||||||
|
|
@ -111,17 +111,22 @@ type environment struct {
|
||||||
receipts []*types.Receipt
|
receipts []*types.Receipt
|
||||||
sidecars []*types.BlobTxSidecar
|
sidecars []*types.BlobTxSidecar
|
||||||
blobs int
|
blobs int
|
||||||
|
|
||||||
|
depsMVFullWriteList [][]blockstm.WriteDescriptor
|
||||||
|
mvReadMapList []map[blockstm.Key]blockstm.ReadDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy creates a deep copy of environment.
|
// copy creates a deep copy of environment.
|
||||||
func (env *environment) copy() *environment {
|
func (env *environment) copy() *environment {
|
||||||
cpy := &environment{
|
cpy := &environment{
|
||||||
signer: env.signer,
|
signer: env.signer,
|
||||||
state: env.state.Copy(),
|
state: env.state.Copy(),
|
||||||
tcount: env.tcount,
|
tcount: env.tcount,
|
||||||
coinbase: env.coinbase,
|
coinbase: env.coinbase,
|
||||||
header: types.CopyHeader(env.header),
|
header: types.CopyHeader(env.header),
|
||||||
receipts: copyReceipts(env.receipts),
|
receipts: copyReceipts(env.receipts),
|
||||||
|
depsMVFullWriteList: env.depsMVFullWriteList,
|
||||||
|
mvReadMapList: env.mvReadMapList,
|
||||||
}
|
}
|
||||||
|
|
||||||
if env.gasPool != nil {
|
if env.gasPool != nil {
|
||||||
|
|
@ -859,6 +864,9 @@ func (w *worker) makeEnv(parent *types.Header, header *types.Header, coinbase co
|
||||||
// Keep track of transactions which return errors so they can be removed
|
// Keep track of transactions which return errors so they can be removed
|
||||||
env.tcount = 0
|
env.tcount = 0
|
||||||
|
|
||||||
|
env.depsMVFullWriteList = [][]blockstm.WriteDescriptor{}
|
||||||
|
env.mvReadMapList = []map[blockstm.Key]blockstm.ReadDescriptor{}
|
||||||
|
|
||||||
return env, nil
|
return env, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -908,36 +916,20 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
|
||||||
|
|
||||||
var coalescedLogs []*types.Log
|
var coalescedLogs []*types.Log
|
||||||
|
|
||||||
var depsMVReadList [][]blockstm.ReadDescriptor
|
|
||||||
|
|
||||||
var depsMVFullWriteList [][]blockstm.WriteDescriptor
|
|
||||||
|
|
||||||
var mvReadMapList []map[blockstm.Key]blockstm.ReadDescriptor
|
|
||||||
|
|
||||||
var deps map[int]map[int]bool
|
var deps map[int]map[int]bool
|
||||||
|
|
||||||
chDeps := make(chan blockstm.TxDep)
|
chDeps := make(chan blockstm.TxDep)
|
||||||
|
|
||||||
var count int
|
|
||||||
|
|
||||||
var depsWg sync.WaitGroup
|
var depsWg sync.WaitGroup
|
||||||
|
|
||||||
EnableMVHashMap := w.chainConfig.Bor.IsParallelUniverse(env.header.Number)
|
EnableMVHashMap := w.chainConfig.IsCancun(env.header.Number)
|
||||||
|
|
||||||
// create and add empty mvHashMap in statedb
|
// create and add empty mvHashMap in statedb
|
||||||
if EnableMVHashMap {
|
if EnableMVHashMap {
|
||||||
depsMVReadList = [][]blockstm.ReadDescriptor{}
|
|
||||||
|
|
||||||
depsMVFullWriteList = [][]blockstm.WriteDescriptor{}
|
|
||||||
|
|
||||||
mvReadMapList = []map[blockstm.Key]blockstm.ReadDescriptor{}
|
|
||||||
|
|
||||||
deps = map[int]map[int]bool{}
|
deps = map[int]map[int]bool{}
|
||||||
|
|
||||||
chDeps = make(chan blockstm.TxDep)
|
chDeps = make(chan blockstm.TxDep)
|
||||||
|
|
||||||
count = 0
|
|
||||||
|
|
||||||
depsWg.Add(1)
|
depsWg.Add(1)
|
||||||
|
|
||||||
go func(chDeps chan blockstm.TxDep) {
|
go func(chDeps chan blockstm.TxDep) {
|
||||||
|
|
@ -1079,18 +1071,20 @@ mainloop:
|
||||||
env.tcount++
|
env.tcount++
|
||||||
|
|
||||||
if EnableMVHashMap {
|
if EnableMVHashMap {
|
||||||
depsMVReadList = append(depsMVReadList, env.state.MVReadList())
|
env.depsMVFullWriteList = append(env.depsMVFullWriteList, env.state.MVFullWriteList())
|
||||||
depsMVFullWriteList = append(depsMVFullWriteList, env.state.MVFullWriteList())
|
env.mvReadMapList = append(env.mvReadMapList, env.state.MVReadMap())
|
||||||
mvReadMapList = append(mvReadMapList, env.state.MVReadMap())
|
|
||||||
|
if env.tcount > len(env.depsMVFullWriteList) {
|
||||||
|
log.Warn("blockstm - env.tcount > len(env.depsMVFullWriteList)", "env.tcount", env.tcount, "len(depsMVFullWriteList)", len(env.depsMVFullWriteList))
|
||||||
|
}
|
||||||
|
|
||||||
temp := blockstm.TxDep{
|
temp := blockstm.TxDep{
|
||||||
Index: env.tcount - 1,
|
Index: env.tcount - 1,
|
||||||
ReadList: depsMVReadList[count],
|
ReadList: env.state.MVReadList(),
|
||||||
FullWriteList: depsMVFullWriteList,
|
FullWriteList: env.depsMVFullWriteList,
|
||||||
}
|
}
|
||||||
|
|
||||||
chDeps <- temp
|
chDeps <- temp
|
||||||
count++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
txs.Shift()
|
txs.Shift()
|
||||||
|
|
@ -1122,8 +1116,8 @@ mainloop:
|
||||||
tempVanity := env.header.Extra[:types.ExtraVanityLength]
|
tempVanity := env.header.Extra[:types.ExtraVanityLength]
|
||||||
tempSeal := env.header.Extra[len(env.header.Extra)-types.ExtraSealLength:]
|
tempSeal := env.header.Extra[len(env.header.Extra)-types.ExtraSealLength:]
|
||||||
|
|
||||||
if len(mvReadMapList) > 0 {
|
if len(env.mvReadMapList) > 0 {
|
||||||
tempDeps := make([][]uint64, len(mvReadMapList))
|
tempDeps := make([][]uint64, len(env.mvReadMapList))
|
||||||
|
|
||||||
for j := range deps[0] {
|
for j := range deps[0] {
|
||||||
tempDeps[0] = append(tempDeps[0], uint64(j))
|
tempDeps[0] = append(tempDeps[0], uint64(j))
|
||||||
|
|
@ -1131,14 +1125,15 @@ mainloop:
|
||||||
|
|
||||||
delayFlag := true
|
delayFlag := true
|
||||||
|
|
||||||
for i := 1; i <= len(mvReadMapList)-1; i++ {
|
for i := 1; i <= len(env.mvReadMapList)-1; i++ {
|
||||||
reads := mvReadMapList[i-1]
|
reads := env.mvReadMapList[i-1]
|
||||||
|
|
||||||
_, ok1 := reads[blockstm.NewSubpathKey(env.coinbase, state.BalancePath)]
|
_, ok1 := reads[blockstm.NewSubpathKey(env.coinbase, state.BalancePath)]
|
||||||
_, ok2 := reads[blockstm.NewSubpathKey(common.HexToAddress(w.chainConfig.Bor.CalculateBurntContract(env.header.Number.Uint64())), state.BalancePath)]
|
_, ok2 := reads[blockstm.NewSubpathKey(common.HexToAddress(w.chainConfig.Bor.CalculateBurntContract(env.header.Number.Uint64())), state.BalancePath)]
|
||||||
|
|
||||||
if ok1 || ok2 {
|
if ok1 || ok2 {
|
||||||
delayFlag = false
|
delayFlag = false
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
for j := range deps[i] {
|
for j := range deps[i] {
|
||||||
|
|
@ -1194,7 +1189,7 @@ mainloop:
|
||||||
|
|
||||||
// generateParams wraps various of settings for generating sealing task.
|
// generateParams wraps various of settings for generating sealing task.
|
||||||
type generateParams struct {
|
type generateParams struct {
|
||||||
timestamp uint64 // The timstamp for sealing task
|
timestamp uint64 // The timestamp for sealing task
|
||||||
forceTime bool // Flag whether the given timestamp is immutable or not
|
forceTime bool // Flag whether the given timestamp is immutable or not
|
||||||
parentHash common.Hash // Parent block hash, empty means the latest chain head
|
parentHash common.Hash // Parent block hash, empty means the latest chain head
|
||||||
coinbase common.Address // The fee recipient address for including transaction
|
coinbase common.Address // The fee recipient address for including transaction
|
||||||
|
|
|
||||||
|
|
@ -928,7 +928,7 @@ func BenchmarkBorMining(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// uses core.NewParallelBlockChain to use the dependencies present in the block header
|
// uses core.NewParallelBlockChain to use the dependencies present in the block header
|
||||||
// params.BorUnittestChainConfig contains the ParallelUniverseBlock ad big.NewInt(5), so the first 4 blocks will not have metadata.
|
// params.BorUnittestChainConfig contains the NapoliBlock as big.NewInt(5), so the first 4 blocks will not have metadata.
|
||||||
// nolint: gocognit
|
// nolint: gocognit
|
||||||
func BenchmarkBorMiningBlockSTMMetadata(b *testing.B) {
|
func BenchmarkBorMiningBlockSTMMetadata(b *testing.B) {
|
||||||
chainConfig := params.BorUnittestChainConfig
|
chainConfig := params.BorUnittestChainConfig
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ const ttlLimit = time.Minute
|
||||||
|
|
||||||
// tuningConfidenceCap is the number of active peers above which to stop detuning
|
// tuningConfidenceCap is the number of active peers above which to stop detuning
|
||||||
// the confidence number. The idea here is that once we hone in on the capacity
|
// the confidence number. The idea here is that once we hone in on the capacity
|
||||||
// of a meaningful number of peers, adding one more should ot have a significant
|
// of a meaningful number of peers, adding one more should not have a significant
|
||||||
// impact on things, so just ron with the originals.
|
// impact on things, so just ron with the originals.
|
||||||
const tuningConfidenceCap = 10
|
const tuningConfidenceCap = 10
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -450,7 +450,7 @@ func BenchmarkThroughput(b *testing.B) {
|
||||||
conn2.SetSnappy(true)
|
conn2.SetSnappy(true)
|
||||||
|
|
||||||
if err := <-handshakeDone; err != nil {
|
if err := <-handshakeDone; err != nil {
|
||||||
b.Fatal("server hanshake error:", err)
|
b.Fatal("server handshake error:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read N messages.
|
// Read N messages.
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ type SimNode struct {
|
||||||
registerOnce sync.Once
|
registerOnce sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the underlaying node.Node to release
|
// Close closes the underlying node.Node to release
|
||||||
// acquired resources.
|
// acquired resources.
|
||||||
func (sn *SimNode) Close() error {
|
func (sn *SimNode) Close() error {
|
||||||
return sn.node.Close()
|
return sn.node.Close()
|
||||||
|
|
|
||||||
|
|
@ -740,7 +740,7 @@ func triggerChecks(ctx context.Context, ids []enode.ID, trigger chan enode.ID, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// \todo: refactor to implement shapshots
|
// \todo: refactor to implement snapshots
|
||||||
// and connect configuration methods once these are moved from
|
// and connect configuration methods once these are moved from
|
||||||
// swarm/network/simulations/connect.go
|
// swarm/network/simulations/connect.go
|
||||||
func BenchmarkMinimalService(b *testing.B) {
|
func BenchmarkMinimalService(b *testing.B) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
Source: bor
|
Source: bor
|
||||||
Version: 1.2.0-beta
|
Version: 1.2.3
|
||||||
Section: develop
|
Section: develop
|
||||||
Priority: standard
|
Priority: standard
|
||||||
Maintainer: Polygon <release-team@polygon.technology>
|
Maintainer: Polygon <release-team@polygon.technology>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
Source: bor
|
Source: bor
|
||||||
Version: 1.2.0-beta
|
Version: 1.2.3
|
||||||
Section: develop
|
Section: develop
|
||||||
Priority: standard
|
Priority: standard
|
||||||
Maintainer: Polygon <release-team@polygon.technology>
|
Maintainer: Polygon <release-team@polygon.technology>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
Source: bor-profile
|
Source: bor-profile
|
||||||
Version: 1.2.0-beta
|
Version: 1.2.3
|
||||||
Section: develop
|
Section: develop
|
||||||
Priority: standard
|
Priority: standard
|
||||||
Maintainer: Polygon <release-team@polygon.technology>
|
Maintainer: Polygon <release-team@polygon.technology>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
Source: bor-profile
|
Source: bor-profile
|
||||||
Version: 1.2.0-beta
|
Version: 1.2.3
|
||||||
Section: develop
|
Section: develop
|
||||||
Priority: standard
|
Priority: standard
|
||||||
Maintainer: Polygon <release-team@polygon.technology>
|
Maintainer: Polygon <release-team@polygon.technology>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
Source: bor-profile
|
Source: bor-profile
|
||||||
Version: 1.2.0-beta
|
Version: 1.2.3
|
||||||
Section: develop
|
Section: develop
|
||||||
Priority: standard
|
Priority: standard
|
||||||
Maintainer: Polygon <release-team@polygon.technology>
|
Maintainer: Polygon <release-team@polygon.technology>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
Source: bor-profile
|
Source: bor-profile
|
||||||
Version: 1.2.0-beta
|
Version: 1.2.3
|
||||||
Section: develop
|
Section: develop
|
||||||
Priority: standard
|
Priority: standard
|
||||||
Maintainer: Polygon <release-team@polygon.technology>
|
Maintainer: Polygon <release-team@polygon.technology>
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,6 @@ var (
|
||||||
BerlinBlock: big.NewInt(0),
|
BerlinBlock: big.NewInt(0),
|
||||||
LondonBlock: big.NewInt(0),
|
LondonBlock: big.NewInt(0),
|
||||||
Bor: &BorConfig{
|
Bor: &BorConfig{
|
||||||
ParallelUniverseBlock: big.NewInt(5),
|
|
||||||
Period: map[string]uint64{
|
Period: map[string]uint64{
|
||||||
"0": 1,
|
"0": 1,
|
||||||
},
|
},
|
||||||
|
|
@ -201,10 +200,9 @@ var (
|
||||||
LondonBlock: big.NewInt(22640000),
|
LondonBlock: big.NewInt(22640000),
|
||||||
ShanghaiBlock: big.NewInt(41874000),
|
ShanghaiBlock: big.NewInt(41874000),
|
||||||
Bor: &BorConfig{
|
Bor: &BorConfig{
|
||||||
JaipurBlock: big.NewInt(22770000),
|
JaipurBlock: big.NewInt(22770000),
|
||||||
DelhiBlock: big.NewInt(29638656),
|
DelhiBlock: big.NewInt(29638656),
|
||||||
ParallelUniverseBlock: big.NewInt(0),
|
IndoreBlock: big.NewInt(37075456),
|
||||||
IndoreBlock: big.NewInt(37075456),
|
|
||||||
StateSyncConfirmationDelay: map[string]uint64{
|
StateSyncConfirmationDelay: map[string]uint64{
|
||||||
"37075456": 128,
|
"37075456": 128,
|
||||||
},
|
},
|
||||||
|
|
@ -268,10 +266,9 @@ var (
|
||||||
LondonBlock: big.NewInt(73100),
|
LondonBlock: big.NewInt(73100),
|
||||||
ShanghaiBlock: big.NewInt(73100),
|
ShanghaiBlock: big.NewInt(73100),
|
||||||
Bor: &BorConfig{
|
Bor: &BorConfig{
|
||||||
JaipurBlock: big.NewInt(73100),
|
JaipurBlock: big.NewInt(73100),
|
||||||
DelhiBlock: big.NewInt(73100),
|
DelhiBlock: big.NewInt(73100),
|
||||||
ParallelUniverseBlock: nil,
|
IndoreBlock: big.NewInt(73100),
|
||||||
IndoreBlock: big.NewInt(73100),
|
|
||||||
StateSyncConfirmationDelay: map[string]uint64{
|
StateSyncConfirmationDelay: map[string]uint64{
|
||||||
"0": 128,
|
"0": 128,
|
||||||
},
|
},
|
||||||
|
|
@ -313,10 +310,9 @@ var (
|
||||||
LondonBlock: big.NewInt(23850000),
|
LondonBlock: big.NewInt(23850000),
|
||||||
ShanghaiBlock: big.NewInt(50523000),
|
ShanghaiBlock: big.NewInt(50523000),
|
||||||
Bor: &BorConfig{
|
Bor: &BorConfig{
|
||||||
JaipurBlock: big.NewInt(23850000),
|
JaipurBlock: big.NewInt(23850000),
|
||||||
DelhiBlock: big.NewInt(38189056),
|
DelhiBlock: big.NewInt(38189056),
|
||||||
ParallelUniverseBlock: big.NewInt(0),
|
IndoreBlock: big.NewInt(44934656),
|
||||||
IndoreBlock: big.NewInt(44934656),
|
|
||||||
StateSyncConfirmationDelay: map[string]uint64{
|
StateSyncConfirmationDelay: map[string]uint64{
|
||||||
"44934656": 128,
|
"44934656": 128,
|
||||||
},
|
},
|
||||||
|
|
@ -617,7 +613,6 @@ type BorConfig struct {
|
||||||
BurntContract map[string]string `json:"burntContract"` // governance contract where the token will be sent to and burnt in london fork
|
BurntContract map[string]string `json:"burntContract"` // governance contract where the token will be sent to and burnt in london fork
|
||||||
JaipurBlock *big.Int `json:"jaipurBlock"` // Jaipur switch block (nil = no fork, 0 = already on jaipur)
|
JaipurBlock *big.Int `json:"jaipurBlock"` // Jaipur switch block (nil = no fork, 0 = already on jaipur)
|
||||||
DelhiBlock *big.Int `json:"delhiBlock"` // Delhi switch block (nil = no fork, 0 = already on delhi)
|
DelhiBlock *big.Int `json:"delhiBlock"` // Delhi switch block (nil = no fork, 0 = already on delhi)
|
||||||
ParallelUniverseBlock *big.Int `json:"parallelUniverseBlock"` // TODO: update all occurrence, change name and finalize number (hardfork for block-stm related changes)
|
|
||||||
IndoreBlock *big.Int `json:"indoreBlock"` // Indore switch block (nil = no fork, 0 = already on indore)
|
IndoreBlock *big.Int `json:"indoreBlock"` // Indore switch block (nil = no fork, 0 = already on indore)
|
||||||
StateSyncConfirmationDelay map[string]uint64 `json:"stateSyncConfirmationDelay"` // StateSync Confirmation Delay, in seconds, to calculate `to`
|
StateSyncConfirmationDelay map[string]uint64 `json:"stateSyncConfirmationDelay"` // StateSync Confirmation Delay, in seconds, to calculate `to`
|
||||||
}
|
}
|
||||||
|
|
@ -659,16 +654,16 @@ func (c *BorConfig) CalculateStateSyncDelay(number uint64) uint64 {
|
||||||
return borKeyValueConfigHelper(c.StateSyncConfirmationDelay, number)
|
return borKeyValueConfigHelper(c.StateSyncConfirmationDelay, number)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: modify this function once the block number is finalized
|
// // TODO: modify this function once the block number is finalized
|
||||||
func (c *BorConfig) IsParallelUniverse(number *big.Int) bool {
|
// func (c *BorConfig) IsNapoli(number *big.Int) bool {
|
||||||
if c.ParallelUniverseBlock != nil {
|
// if c.NapoliBlock != nil {
|
||||||
if c.ParallelUniverseBlock.Cmp(big.NewInt(0)) == 0 {
|
// if c.NapoliBlock.Cmp(big.NewInt(0)) == 0 {
|
||||||
return false
|
// return false
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return isBlockForked(c.ParallelUniverseBlock, number)
|
// return isBlockForked(c.NapoliBlock, number)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (c *BorConfig) IsSprintStart(number uint64) bool {
|
func (c *BorConfig) IsSprintStart(number uint64) bool {
|
||||||
return number%c.CalculateSprint(number) == 0
|
return number%c.CalculateSprint(number) == 0
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,10 @@ 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 = 0 // Patch version component of the current release
|
VersionPatch = 3 // Patch version component of the current release
|
||||||
VersionMeta = "beta" // Version metadata to append to the version string
|
VersionMeta = "" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
var GitCommit string
|
var GitCommit string
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ type op interface {
|
||||||
// basicOp handles basic types bool, uint*, string.
|
// basicOp handles basic types bool, uint*, string.
|
||||||
type basicOp struct {
|
type basicOp struct {
|
||||||
typ types.Type
|
typ types.Type
|
||||||
writeMethod string // calle write the value
|
writeMethod string // calls write value
|
||||||
writeArgType types.Type // parameter type of writeMethod
|
writeArgType types.Type // parameter type of writeMethod
|
||||||
decMethod string
|
decMethod string
|
||||||
decResultType types.Type // return type of decMethod
|
decResultType types.Type // return type of decMethod
|
||||||
|
|
|
||||||
|
|
@ -692,7 +692,7 @@ func (api *SignerAPI) SignGnosisSafeTx(ctx context.Context, signerAddress common
|
||||||
}
|
}
|
||||||
|
|
||||||
typedData := gnosisTx.ToTypedData()
|
typedData := gnosisTx.ToTypedData()
|
||||||
// might aswell error early.
|
// might as well error early.
|
||||||
// we are expected to sign. If our calculated hash does not match what they want,
|
// we are expected to sign. If our calculated hash does not match what they want,
|
||||||
// The gnosis safetx input contains a 'safeTxHash' which is the expected safeTxHash that
|
// The gnosis safetx input contains a 'safeTxHash' which is the expected safeTxHash that
|
||||||
sighash, _, err := apitypes.TypedDataAndHash(typedData)
|
sighash, _, err := apitypes.TypedDataAndHash(typedData)
|
||||||
|
|
|
||||||
|
|
@ -299,7 +299,7 @@ func TestForkWithBlockTime(t *testing.T) {
|
||||||
// Iterate over all the nodes and start mining
|
// Iterate over all the nodes and start mining
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
if err := node.StartMining(); err != nil {
|
if err := node.StartMining(); err != nil {
|
||||||
t.Fatal("Error occured while starting miner", "node", node, "error", err)
|
t.Fatal("Error occurred while starting miner", "node", node, "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
@ -333,22 +333,22 @@ func TestForkWithBlockTime(t *testing.T) {
|
||||||
|
|
||||||
author0, err := nodes[0].Engine().Author(blockHeaderVal0)
|
author0, err := nodes[0].Engine().Author(blockHeaderVal0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("Error occured while fetching author", "err", err)
|
t.Error("Error occurred while fetching author", "err", err)
|
||||||
}
|
}
|
||||||
author1, err := nodes[1].Engine().Author(blockHeaderVal1)
|
author1, err := nodes[1].Engine().Author(blockHeaderVal1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("Error occured while fetching author", "err", err)
|
t.Error("Error occurred while fetching author", "err", err)
|
||||||
}
|
}
|
||||||
assert.Equal(t, author0, author1)
|
assert.Equal(t, author0, author1)
|
||||||
|
|
||||||
// After the end of sprint
|
// After the end of sprint
|
||||||
author2, err := nodes[0].Engine().Author(blockHeaders[0])
|
author2, err := nodes[0].Engine().Author(blockHeaders[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("Error occured while fetching author", "err", err)
|
t.Error("Error occurred while fetching author", "err", err)
|
||||||
}
|
}
|
||||||
author3, err := nodes[1].Engine().Author(blockHeaders[1])
|
author3, err := nodes[1].Engine().Author(blockHeaders[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("Error occured while fetching author", "err", err)
|
t.Error("Error occurred while fetching author", "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.forkExpected {
|
if test.forkExpected {
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ func setupMiner(t *testing.T, n int, genesis *core.Genesis) ([]*node.Node, []*et
|
||||||
// Start the node and wait until it's up
|
// Start the node and wait until it's up
|
||||||
stack, ethBackend, err := InitMiner(genesis, keys[i], true)
|
stack, ethBackend, err := InitMiner(genesis, keys[i], true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Error occured while initialising miner", "error", err)
|
t.Fatal("Error occurred while initialising miner", "error", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for stack.Server().NodeInfo().Ports.Listener == 0 {
|
for stack.Server().NodeInfo().Ports.Listener == 0 {
|
||||||
|
|
|
||||||
|
|
@ -428,7 +428,7 @@ func unset(parent node, child node, key []byte, pos int, removeLeft bool) error
|
||||||
} else {
|
} else {
|
||||||
if bytes.Compare(cld.Key, key[pos:]) > 0 {
|
if bytes.Compare(cld.Key, key[pos:]) > 0 {
|
||||||
// The key of fork shortnode is greater than the
|
// The key of fork shortnode is greater than the
|
||||||
// path(it belongs to the range), unset the entrie
|
// path(it belongs to the range), unset the entire
|
||||||
// branch. The parent must be a fullnode.
|
// branch. The parent must be a fullnode.
|
||||||
fn := parent.(*fullNode)
|
fn := parent.(*fullNode)
|
||||||
fn.Children[key[pos-1]] = nil
|
fn.Children[key[pos-1]] = nil
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,7 @@ func TestLargeValue(t *testing.T) {
|
||||||
trie.Hash()
|
trie.Hash()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestRandomCases tests som cases that were found via random fuzzing
|
// TestRandomCases tests some cases that were found via random fuzzing
|
||||||
func TestRandomCases(t *testing.T) {
|
func TestRandomCases(t *testing.T) {
|
||||||
var rt = []randTestStep{
|
var rt = []randTestStep{
|
||||||
{op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 0
|
{op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 0
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue