Merge branch 'ethereum:master' into master

This commit is contained in:
kant777 2024-02-05 13:44:49 -08:00 committed by GitHub
commit 993e208db9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 273 additions and 108 deletions

View file

@ -29,7 +29,7 @@ import (
)
// The ABI holds information about a contract's context and available
// invokable methods. It will allow you to type check function calls and
// invocable methods. It will allow you to type check function calls and
// packs data accordingly.
type ABI struct {
Constructor Method

View file

@ -241,7 +241,7 @@ func (hub *Hub) refreshWallets() {
card.Disconnect(pcsc.LeaveCard)
continue
}
// Card connected, start tracking in amongs the wallets
// Card connected, start tracking among the wallets
hub.wallets[reader] = wallet
events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletArrived})
}

View file

@ -75,7 +75,7 @@ Example:
},
{
"type": "Info",
"message": "User should see this aswell"
"message": "User should see this as well"
}
],
"meta": {

View file

@ -1673,7 +1673,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
// 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
// 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 {
activeState.StopPrefetcher()
}

View file

@ -894,7 +894,7 @@ func getChunk(size int, b int) []byte {
}
// 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
// Right now, the freezer would fail on these conditions:
// 1. have data files d0, d1, d2, d3

View file

@ -121,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
// 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
// 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
// theory will never ever be visited again.
var (

View file

@ -43,7 +43,7 @@ var (
aggregatorMemoryLimit = uint64(4 * 1024 * 1024)
// 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
// 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

View file

@ -139,7 +139,7 @@ func TestDiskMerge(t *testing.T) {
// Retrieve all the data through the disk layer and validate it
base = snaps.Snapshot(diffRoot)
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.
@ -362,7 +362,7 @@ func TestDiskPartialMerge(t *testing.T) {
// Retrieve all the data through the disk layer and validate it
base = snaps.Snapshot(diffRoot)
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(accNoModCache, accNoModCache[:])

View file

@ -237,7 +237,7 @@ func testIterativeStateSync(t *testing.T, count int, commit bool, bypath bool, s
id := trie.StorageTrieID(srcRoot, common.BytesToHash(node.syncPath[0]), acc.Root)
stTrie, err := trie.New(id, ndb)
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])
if err != nil {

View file

@ -386,6 +386,8 @@ func (p *BlobPool) Init(gasTip *big.Int, head *types.Header, reserve txpool.Addr
if len(fails) > 0 {
log.Warn("Dropping invalidated blob transactions", "ids", fails)
dropInvalidMeter.Mark(int64(len(fails)))
for _, id := range fails {
if err := p.store.Delete(id); err != nil {
p.Close()
@ -456,7 +458,7 @@ func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error {
tx := new(types.Transaction)
if err := rlp.DecodeBytes(blob, tx); err != nil {
// 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.
log.Error("Failed to decode blob pool entry", "id", id, "err", err)
return err
@ -467,11 +469,17 @@ func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error {
}
meta := newBlobTxMeta(id, size, tx)
if _, exists := p.lookup[meta.hash]; exists {
// This path is only possible after a crash, where deleted items are not
// removed via the normal shutdown-startup procedure and thus may get
// partially resurrected.
log.Error("Rejecting duplicate blob pool entry", "id", id, "hash", tx.Hash())
return errors.New("duplicate blob entry")
}
sender, err := p.signer.Sender(tx)
if err != nil {
// 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.
log.Error("Failed to recover blob tx sender", "id", id, "hash", tx.Hash(), "err", err)
return err
@ -537,8 +545,10 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
if gapped {
log.Warn("Dropping dangling blob transactions", "from", addr, "missing", next, "drop", nonces, "ids", ids)
dropDanglingMeter.Mark(int64(len(ids)))
} else {
log.Trace("Dropping filled blob transactions", "from", addr, "filled", nonces, "ids", ids)
dropFilledMeter.Mark(int64(len(ids)))
}
for _, id := range ids {
if err := p.store.Delete(id); err != nil {
@ -569,6 +579,8 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
txs = txs[1:]
}
log.Trace("Dropping overlapped blob transactions", "from", addr, "overlapped", nonces, "ids", ids, "left", len(txs))
dropOverlappedMeter.Mark(int64(len(ids)))
for _, id := range ids {
if err := p.store.Delete(id); err != nil {
log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err)
@ -600,10 +612,30 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
}
continue
}
// Sanity check that there's no double nonce. This case would be a coding
// error, but better know about it
// Sanity check that there's no double nonce. This case would generally
// be a coding error, so better know about it.
//
// Also, Billy behind the blobpool does not journal deletes. A process
// crash would result in previously deleted entities being resurrected.
// That could potentially cause a duplicate nonce to appear.
if txs[i].nonce == txs[i-1].nonce {
log.Error("Duplicate nonce blob transaction", "from", addr, "nonce", txs[i].nonce)
id := p.lookup[txs[i].hash]
log.Error("Dropping repeat nonce blob transaction", "from", addr, "nonce", txs[i].nonce, "id", id)
dropRepeatedMeter.Mark(1)
p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[i].costCap)
p.stored -= uint64(txs[i].size)
delete(p.lookup, txs[i].hash)
if err := p.store.Delete(id); err != nil {
log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err)
}
txs = append(txs[:i], txs[i+1:]...)
p.index[addr] = txs
i--
continue
}
// Otherwise if there's a nonce gap evict all later transactions
var (
@ -621,6 +653,8 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
txs = txs[:i]
log.Error("Dropping gapped blob transactions", "from", addr, "missing", txs[i-1].nonce+1, "drop", nonces, "ids", ids)
dropGappedMeter.Mark(int64(len(ids)))
for _, id := range ids {
if err := p.store.Delete(id); err != nil {
log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err)
@ -665,6 +699,8 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
p.index[addr] = txs
}
log.Warn("Dropping overdrafted blob transactions", "from", addr, "balance", balance, "spent", spent, "drop", nonces, "ids", ids)
dropOverdraftedMeter.Mark(int64(len(ids)))
for _, id := range ids {
if err := p.store.Delete(id); err != nil {
log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err)
@ -695,6 +731,8 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
p.index[addr] = txs
log.Warn("Dropping overcapped blob transactions", "from", addr, "kept", len(txs), "drop", nonces, "ids", ids)
dropOvercappedMeter.Mark(int64(len(ids)))
for _, id := range ids {
if err := p.store.Delete(id); err != nil {
log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err)
@ -711,7 +749,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
// 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
// issues, others caused by signers mining MEV stuff or swapping transactions. In
// all cases, the pool needs to continue operating.
@ -952,7 +990,7 @@ func (p *BlobPool) reinject(addr common.Address, txhash common.Hash) error {
return err
}
// Update the indixes and metrics
// Update the indices and metrics
meta := newBlobTxMeta(id, p.store.Size(id), tx)
if _, ok := p.index[addr]; !ok {
if err := p.reserve(addr, true); err != nil {
@ -1019,6 +1057,8 @@ func (p *BlobPool) SetGasTip(tip *big.Int) {
}
// Clear out the transactions from the data store
log.Warn("Dropping underpriced blob transaction", "from", addr, "rejected", tx.nonce, "tip", tx.execTipCap, "want", tip, "drop", nonces, "ids", ids)
dropUnderpricedMeter.Mark(int64(len(ids)))
for _, id := range ids {
if err := p.store.Delete(id); err != nil {
log.Error("Failed to delete dropped transaction", "id", id, "err", err)
@ -1161,7 +1201,7 @@ func (p *BlobPool) Get(hash common.Hash) *types.Transaction {
}
// Add inserts a set of blob transactions into the pool if they pass validation (both
// consensus validity and pool restictions).
// consensus validity and pool restrictions).
func (p *BlobPool) Add(txs []*types.Transaction, local bool, sync bool) []error {
var (
adds = make([]*types.Transaction, 0, len(txs))
@ -1181,7 +1221,7 @@ func (p *BlobPool) Add(txs []*types.Transaction, local bool, sync bool) []error
}
// Add inserts a new blob transaction into the pool if it passes validation (both
// consensus validity and pool restictions).
// consensus validity and pool restrictions).
func (p *BlobPool) add(tx *types.Transaction) (err error) {
// The blob pool blocks on adding a transaction. This is because blob txs are
// only even pulled form the network, so this method will act as the overload
@ -1198,6 +1238,22 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) {
// Ensure the transaction is valid from all perspectives
if err := p.validateTx(tx); err != nil {
log.Trace("Transaction validation failed", "hash", tx.Hash(), "err", err)
switch {
case errors.Is(err, txpool.ErrUnderpriced):
addUnderpricedMeter.Mark(1)
case errors.Is(err, core.ErrNonceTooLow):
addStaleMeter.Mark(1)
case errors.Is(err, core.ErrNonceTooHigh):
addGappedMeter.Mark(1)
case errors.Is(err, core.ErrInsufficientFunds):
addOverdraftedMeter.Mark(1)
case errors.Is(err, txpool.ErrAccountLimitExceeded):
addOvercappedMeter.Mark(1)
case errors.Is(err, txpool.ErrReplaceUnderpriced):
addNoreplaceMeter.Mark(1)
default:
addInvalidMeter.Mark(1)
}
return err
}
// If the address is not yet known, request exclusivity to track the account
@ -1205,6 +1261,7 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) {
from, _ := types.Sender(p.signer, tx) // already validated above
if _, ok := p.index[from]; !ok {
if err := p.reserve(from, true); err != nil {
addNonExclusiveMeter.Mark(1)
return err
}
defer func() {
@ -1244,6 +1301,8 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) {
}
if len(p.index[from]) > offset {
// Transaction replaces a previously queued one
dropReplacedMeter.Mark(1)
prev := p.index[from][offset]
if err := p.store.Delete(prev.id); err != nil {
// Shitty situation, but try to recover gracefully instead of going boom
@ -1322,6 +1381,7 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) {
}
p.updateStorageMetrics()
addValidMeter.Mark(1)
return nil
}
@ -1371,7 +1431,9 @@ func (p *BlobPool) drop() {
}
}
// Remove the transaction from the data store
log.Warn("Evicting overflown blob transaction", "from", from, "evicted", drop.nonce, "id", drop.id)
log.Debug("Evicting overflown blob transaction", "from", from, "evicted", drop.nonce, "id", drop.id)
dropOverflownMeter.Mark(1)
if err := p.store.Delete(drop.id); err != nil {
log.Error("Failed to drop evicted transaction", "id", drop.id, "err", err)
}

View file

@ -305,7 +305,16 @@ func verifyPoolInternals(t *testing.T, pool *BlobPool) {
// - 1. A transaction that cannot be decoded must be dropped
// - 2. A transaction that cannot be recovered (bad signature) must be dropped
// - 3. All transactions after a nonce gap must be dropped
// - 4. All transactions after an underpriced one (including it) must be dropped
// - 4. All transactions after an already included nonce must be dropped
// - 5. All transactions after an underpriced one (including it) must be dropped
// - 6. All transactions after an overdrafting sequence must be dropped
// - 7. All transactions exceeding the per-account limit must be dropped
//
// Furthermore, some strange corner-cases can also occur after a crash, as Billy's
// simplicity also allows it to resurrect past deleted entities:
//
// - 8. Fully duplicate transactions (matching hash) must be dropped
// - 9. Duplicate nonces from the same account must be dropped
func TestOpenDrops(t *testing.T) {
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true)))
@ -338,7 +347,7 @@ func TestOpenDrops(t *testing.T) {
badsig, _ := store.Put(blob)
// Insert a sequence of transactions with a nonce gap in between to verify
// that anything gapped will get evicted (case 3)
// that anything gapped will get evicted (case 3).
var (
gapper, _ = crypto.GenerateKey()
@ -357,7 +366,7 @@ func TestOpenDrops(t *testing.T) {
}
}
// Insert a sequence of transactions with a gapped starting nonce to verify
// that the entire set will get dropped.
// that the entire set will get dropped (case 3).
var (
dangler, _ = crypto.GenerateKey()
dangling = make(map[uint64]struct{})
@ -370,7 +379,7 @@ func TestOpenDrops(t *testing.T) {
dangling[id] = struct{}{}
}
// Insert a sequence of transactions with already passed nonces to veirfy
// that the entire set will get dropped.
// that the entire set will get dropped (case 4).
var (
filler, _ = crypto.GenerateKey()
filled = make(map[uint64]struct{})
@ -383,7 +392,7 @@ func TestOpenDrops(t *testing.T) {
filled[id] = struct{}{}
}
// Insert a sequence of transactions with partially passed nonces to veirfy
// that the included part of the set will get dropped
// that the included part of the set will get dropped (case 4).
var (
overlapper, _ = crypto.GenerateKey()
overlapped = make(map[uint64]struct{})
@ -400,7 +409,7 @@ func TestOpenDrops(t *testing.T) {
}
}
// Insert a sequence of transactions with an underpriced first to verify that
// the entire set will get dropped (case 4).
// the entire set will get dropped (case 5).
var (
underpayer, _ = crypto.GenerateKey()
underpaid = make(map[uint64]struct{})
@ -419,7 +428,7 @@ func TestOpenDrops(t *testing.T) {
}
// Insert a sequence of transactions with an underpriced in between to verify
// that it and anything newly gapped will get evicted (case 4).
// that it and anything newly gapped will get evicted (case 5).
var (
outpricer, _ = crypto.GenerateKey()
outpriced = make(map[uint64]struct{})
@ -441,7 +450,7 @@ func TestOpenDrops(t *testing.T) {
}
}
// Insert a sequence of transactions fully overdrafted to verify that the
// entire set will get invalidated.
// entire set will get invalidated (case 6).
var (
exceeder, _ = crypto.GenerateKey()
exceeded = make(map[uint64]struct{})
@ -459,7 +468,7 @@ func TestOpenDrops(t *testing.T) {
exceeded[id] = struct{}{}
}
// Insert a sequence of transactions partially overdrafted to verify that part
// of the set will get invalidated.
// of the set will get invalidated (case 6).
var (
overdrafter, _ = crypto.GenerateKey()
overdrafted = make(map[uint64]struct{})
@ -481,7 +490,7 @@ func TestOpenDrops(t *testing.T) {
}
}
// Insert a sequence of transactions overflowing the account cap to verify
// that part of the set will get invalidated.
// that part of the set will get invalidated (case 7).
var (
overcapper, _ = crypto.GenerateKey()
overcapped = make(map[uint64]struct{})
@ -496,6 +505,42 @@ func TestOpenDrops(t *testing.T) {
overcapped[id] = struct{}{}
}
}
// Insert a batch of duplicated transactions to verify that only one of each
// version will remain (case 8).
var (
duplicater, _ = crypto.GenerateKey()
duplicated = make(map[uint64]struct{})
)
for _, nonce := range []uint64{0, 1, 2} {
blob, _ := rlp.EncodeToBytes(makeTx(nonce, 1, 1, 1, duplicater))
for i := 0; i < int(nonce)+1; i++ {
id, _ := store.Put(blob)
if i == 0 {
valids[id] = struct{}{}
} else {
duplicated[id] = struct{}{}
}
}
}
// Insert a batch of duplicated nonces to verify that only one of each will
// remain (case 9).
var (
repeater, _ = crypto.GenerateKey()
repeated = make(map[uint64]struct{})
)
for _, nonce := range []uint64{0, 1, 2} {
for i := 0; i < int(nonce)+1; i++ {
blob, _ := rlp.EncodeToBytes(makeTx(nonce, 1, uint64(i)+1 /* unique hashes */, 1, repeater))
id, _ := store.Put(blob)
if i == 0 {
valids[id] = struct{}{}
} else {
repeated[id] = struct{}{}
}
}
}
store.Close()
// Create a blob pool out of the pre-seeded data
@ -511,6 +556,8 @@ func TestOpenDrops(t *testing.T) {
statedb.AddBalance(crypto.PubkeyToAddress(exceeder.PublicKey), uint256.NewInt(1000000))
statedb.AddBalance(crypto.PubkeyToAddress(overdrafter.PublicKey), uint256.NewInt(1000000))
statedb.AddBalance(crypto.PubkeyToAddress(overcapper.PublicKey), uint256.NewInt(10000000))
statedb.AddBalance(crypto.PubkeyToAddress(duplicater.PublicKey), uint256.NewInt(1000000))
statedb.AddBalance(crypto.PubkeyToAddress(repeater.PublicKey), uint256.NewInt(1000000))
statedb.Commit(0, true)
chain := &testBlockChain{
@ -554,6 +601,10 @@ func TestOpenDrops(t *testing.T) {
t.Errorf("partially overdrafted transaction remained in storage: %d", tx.id)
} else if _, ok := overcapped[tx.id]; ok {
t.Errorf("overcapped transaction remained in storage: %d", tx.id)
} else if _, ok := duplicated[tx.id]; ok {
t.Errorf("duplicated transaction remained in storage: %d", tx.id)
} else if _, ok := repeated[tx.id]; ok {
t.Errorf("repeated nonce transaction remained in storage: %d", tx.id)
} else {
alive[tx.id] = struct{}{}
}
@ -584,7 +635,7 @@ func TestOpenDrops(t *testing.T) {
// 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
// - 3. Balance usage of an account is totals across all transactions
func TestOpenIndex(t *testing.T) {
@ -598,7 +649,7 @@ func TestOpenIndex(t *testing.T) {
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil)
// Insert a sequence of transactions with varying price points to check that
// the cumulative minimumw will be maintained.
// the cumulative minimum will be maintained.
var (
key, _ = crypto.GenerateKey()
addr = crypto.PubkeyToAddress(key.PublicKey)
@ -1197,7 +1248,7 @@ func TestAdd(t *testing.T) {
keys[acc], _ = crypto.GenerateKey()
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(uint256.Int).SetUint64(seed.balance))
statedb.SetNonce(addrs[acc], seed.nonce)

View file

@ -53,7 +53,7 @@ func newLimbo(datadir string) (*limbo, error) {
index: make(map[common.Hash]uint64),
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
index := func(id uint64, size uint32, data []byte) {
if l.parseBlob(id, data) != nil {
@ -89,7 +89,7 @@ func (l *limbo) parseBlob(id uint64, data []byte) error {
item := new(limboBlob)
if err := rlp.DecodeBytes(data, item); err != nil {
// 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.
log.Error("Failed to decode blob limbo entry", "id", id, "err", 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
// 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
// issues, others caused by signers mining MEV stuff or swapping transactions. In
// all cases, the pool needs to continue operating.

View file

@ -65,8 +65,8 @@ var (
pooltipGauge = metrics.NewRegisteredGauge("blobpool/pooltip", nil)
// addwait/time, resetwait/time and getwait/time track the rough health of
// the pool and whether or not it's capable of keeping up with the load from
// the network.
// the pool and whether it's capable of keeping up with the load from the
// network.
addwaitHist = metrics.NewRegisteredHistogram("blobpool/addwait", nil, metrics.NewExpDecaySample(1028, 0.015))
addtimeHist = metrics.NewRegisteredHistogram("blobpool/addtime", nil, metrics.NewExpDecaySample(1028, 0.015))
getwaitHist = metrics.NewRegisteredHistogram("blobpool/getwait", nil, metrics.NewExpDecaySample(1028, 0.015))
@ -75,4 +75,31 @@ var (
pendtimeHist = metrics.NewRegisteredHistogram("blobpool/pendtime", nil, metrics.NewExpDecaySample(1028, 0.015))
resetwaitHist = metrics.NewRegisteredHistogram("blobpool/resetwait", nil, metrics.NewExpDecaySample(1028, 0.015))
resettimeHist = metrics.NewRegisteredHistogram("blobpool/resettime", nil, metrics.NewExpDecaySample(1028, 0.015))
// The below metrics track various cases where transactions are dropped out
// of the pool. Most are exceptional, some are chain progression and some
// threshold cappings.
dropInvalidMeter = metrics.NewRegisteredMeter("blobpool/drop/invalid", nil) // Invalid transaction, consensus change or bugfix, neutral-ish
dropDanglingMeter = metrics.NewRegisteredMeter("blobpool/drop/dangling", nil) // First nonce gapped, bad
dropFilledMeter = metrics.NewRegisteredMeter("blobpool/drop/filled", nil) // State full-overlap, chain progress, ok
dropOverlappedMeter = metrics.NewRegisteredMeter("blobpool/drop/overlapped", nil) // State partial-overlap, chain progress, ok
dropRepeatedMeter = metrics.NewRegisteredMeter("blobpool/drop/repeated", nil) // Repeated nonce, bad
dropGappedMeter = metrics.NewRegisteredMeter("blobpool/drop/gapped", nil) // Non-first nonce gapped, bad
dropOverdraftedMeter = metrics.NewRegisteredMeter("blobpool/drop/overdrafted", nil) // Balance exceeded, bad
dropOvercappedMeter = metrics.NewRegisteredMeter("blobpool/drop/overcapped", nil) // Per-account cap exceeded, bad
dropOverflownMeter = metrics.NewRegisteredMeter("blobpool/drop/overflown", nil) // Global disk cap exceeded, neutral-ish
dropUnderpricedMeter = metrics.NewRegisteredMeter("blobpool/drop/underpriced", nil) // Gas tip changed, neutral
dropReplacedMeter = metrics.NewRegisteredMeter("blobpool/drop/replaced", nil) // Transaction replaced, neutral
// The below metrics track various outcomes of transactions being added to
// the pool.
addInvalidMeter = metrics.NewRegisteredMeter("blobpool/add/invalid", nil) // Invalid transaction, reject, neutral
addUnderpricedMeter = metrics.NewRegisteredMeter("blobpool/add/underpriced", nil) // Gas tip too low, neutral
addStaleMeter = metrics.NewRegisteredMeter("blobpool/add/stale", nil) // Nonce already filled, reject, bad-ish
addGappedMeter = metrics.NewRegisteredMeter("blobpool/add/gapped", nil) // Nonce gapped, reject, bad-ish
addOverdraftedMeter = metrics.NewRegisteredMeter("blobpool/add/overdrafted", nil) // Balance exceeded, reject, neutral
addOvercappedMeter = metrics.NewRegisteredMeter("blobpool/add/overcapped", nil) // Per-account cap exceeded, reject, neutral
addNoreplaceMeter = metrics.NewRegisteredMeter("blobpool/add/noreplace", nil) // Replacement fees or tips too low, neutral
addNonExclusiveMeter = metrics.NewRegisteredMeter("blobpool/add/nonexclusive", nil) // Plain transaction from same account exists, reject, neutral
addValidMeter = metrics.NewRegisteredMeter("blobpool/add/valid", nil) // Valid transaction, add, neutral
)

View file

@ -44,11 +44,17 @@ type LazyTransaction struct {
// Resolve retrieves the full transaction belonging to a lazy handle if it is still
// maintained by the transaction pool.
//
// Note, the method will *not* cache the retrieved transaction if the original
// pool has not cached it. The idea being, that if the tx was too big to insert
// originally, silently saving it will cause more trouble down the line (and
// indeed seems to have caused a memory bloat in the original implementation
// which did just that).
func (ltx *LazyTransaction) Resolve() *types.Transaction {
if ltx.Tx == nil {
ltx.Tx = ltx.Pool.Get(ltx.Hash)
if ltx.Tx != nil {
return ltx.Tx
}
return ltx.Tx
return ltx.Pool.Get(ltx.Hash)
}
// LazyResolver is a minimal interface needed for a transaction pool to satisfy
@ -69,7 +75,7 @@ type AddressReserver func(addr common.Address, reserve bool) error
// production, this interface defines the common methods that allow the primary
// transaction pool to manage the subpools.
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.
Filter(tx *types.Transaction) bool

View file

@ -43,7 +43,7 @@ func TestEIP155Signing(t *testing.T) {
t.Fatal(err)
}
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)
}
}

View file

@ -43,7 +43,7 @@ type BlobTx struct {
BlobHashes []common.Hash
// A blob transaction can optionally contain blobs. This field must be set when BlobTx
// is used to create a transaction for sigining.
// is used to create a transaction for signing.
Sidecar *BlobTxSidecar `rlp:"-"`
// Signature values

View file

@ -224,7 +224,7 @@ func BenchmarkPrecompiledRipeMD(bench *testing.B) {
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) {
t := precompiledTest{
Input: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",

View file

@ -163,7 +163,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
debug = in.evm.Config.Tracer != nil
)
// 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
defer func() {
returnStack(stack)

View file

@ -22,7 +22,7 @@ import (
"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) {
tbl := newMergeInstructionSet()
require.Equal(t, uint64(0), tbl[SLOAD].constantGas)

View file

@ -27,7 +27,7 @@ import (
// If z is equal to one the point is considered as in affine form.
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 {
p[0].set(&p2[0])
p[1].set(&p2[1])

View file

@ -50,7 +50,8 @@ func newBeaconBackfiller(dl *Downloader, success func()) backfiller {
}
// suspend cancels any background downloader threads and returns the last header
// that has been successfully backfilled.
// that has been successfully backfilled (potentially in a previous run), or the
// genesis.
func (b *beaconBackfiller) suspend() *types.Header {
// If no filling is running, don't waste cycles
b.lock.Lock()

View file

@ -611,6 +611,7 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td, ttd *
if err := d.lightchain.SetHead(origin); err != nil {
return err
}
log.Info("Truncated excess ancient chain segment", "oldhead", frozen-1, "newhead", origin)
}
}
// Initiate the sync using a concurrent header and content retrieval algorithm

View file

@ -161,7 +161,7 @@ type backfiller interface {
// on initial startup.
//
// The method should return the last block header that has been successfully
// backfilled, or nil if the backfiller was not resumed.
// backfilled (in the current or a previous run), falling back to the genesis.
suspend() *types.Header
// resume requests the backfiller to start running fill or snap sync based on
@ -382,14 +382,17 @@ func (s *skeleton) sync(head *types.Header) (*types.Header, error) {
done := make(chan struct{})
go func() {
defer close(done)
if filled := s.filler.suspend(); filled != nil {
// If something was filled, try to delete stale sync helpers. If
// unsuccessful, warn the user, but not much else we can do (it's
// a programming error, just let users report an issue and don't
// choke in the meantime).
if err := s.cleanStales(filled); err != nil {
log.Error("Failed to clean stale beacon headers", "err", err)
}
filled := s.filler.suspend()
if filled == nil {
log.Error("Latest filled block is not available")
return
}
// If something was filled, try to delete stale sync helpers. If
// unsuccessful, warn the user, but not much else we can do (it's
// a programming error, just let users report an issue and don't
// choke in the meantime).
if err := s.cleanStales(filled); err != nil {
log.Error("Failed to clean stale beacon headers", "err", err)
}
}()
// Wait for the suspend to finish, consuming head events in the meantime
@ -1120,33 +1123,46 @@ func (s *skeleton) cleanStales(filled *types.Header) error {
number := filled.Number.Uint64()
log.Trace("Cleaning stale beacon headers", "filled", number, "hash", filled.Hash())
// If the filled header is below the linked subchain, something's
// corrupted internally. Report and error and refuse to do anything.
if number < s.progress.Subchains[0].Tail {
// If the filled header is below the linked subchain, something's corrupted
// internally. Report and error and refuse to do anything.
if number+1 < s.progress.Subchains[0].Tail {
return fmt.Errorf("filled header below beacon header tail: %d < %d", number, s.progress.Subchains[0].Tail)
}
// Subchain seems trimmable, push the tail forward up to the last
// filled header and delete everything before it - if available. In
// case we filled past the head, recreate the subchain with a new
// head to keep it consistent with the data on disk.
// If nothing in subchain is filled, don't bother to do cleanup.
if number+1 == s.progress.Subchains[0].Tail {
return nil
}
var (
start = s.progress.Subchains[0].Tail // start deleting from the first known header
end = number // delete until the requested threshold
start uint64
end uint64
batch = s.db.NewBatch()
)
s.progress.Subchains[0].Tail = number
s.progress.Subchains[0].Next = filled.ParentHash
if number < s.progress.Subchains[0].Head {
// The skeleton chain is partially consumed, set the new tail as filled+1.
tail := rawdb.ReadSkeletonHeader(s.db, number+1)
if tail.ParentHash != filled.Hash() {
return fmt.Errorf("filled header is discontinuous with subchain: %d %s, please file an issue", number, filled.Hash())
}
start, end = s.progress.Subchains[0].Tail, number+1 // remove headers in [tail, filled]
s.progress.Subchains[0].Tail = tail.Number.Uint64()
s.progress.Subchains[0].Next = tail.ParentHash
} else {
// The skeleton chain is fully consumed, set both head and tail as filled.
start, end = s.progress.Subchains[0].Tail, filled.Number.Uint64() // remove headers in [tail, filled)
s.progress.Subchains[0].Tail = filled.Number.Uint64()
s.progress.Subchains[0].Next = filled.ParentHash
if s.progress.Subchains[0].Head < number {
// If more headers were filled than available, push the entire
// subchain forward to keep tracking the node's block imports
end = s.progress.Subchains[0].Head + 1 // delete the entire original range, including the head
s.progress.Subchains[0].Head = number // assign a new head (tail is already assigned to this)
// If more headers were filled than available, push the entire subchain
// forward to keep tracking the node's block imports.
if number > s.progress.Subchains[0].Head {
end = s.progress.Subchains[0].Head + 1 // delete the entire original range, including the head
s.progress.Subchains[0].Head = number // assign a new head (tail is already assigned to this)
// The entire original skeleton chain was deleted and a new one
// defined. Make sure the new single-header chain gets pushed to
// disk to keep internal state consistent.
rawdb.WriteSkeletonHeader(batch, filled)
// The entire original skeleton chain was deleted and a new one
// defined. Make sure the new single-header chain gets pushed to
// disk to keep internal state consistent.
rawdb.WriteSkeletonHeader(batch, filled)
}
}
// Execute the trimming and the potential rewiring of the progress
s.saveSyncStatus(batch)

View file

@ -219,7 +219,7 @@
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
// to users who don't interpret it, just display it.
finalize: function(call) {

View file

@ -124,9 +124,9 @@ func TestMemCopying(t *testing.T) {
{0, 100, 0, "", 0}, // No need to pad (0 size)
{100, 50, 100, "", 100}, // Should pad 100-150
{100, 50, 5, "", 5}, // Wanted range fully within memory
{100, -50, 0, "offset or size must not be negative", 0}, // Errror
{0, 1, 1024*1024 + 1, "reached limit for padding memory slice: 1048578", 0}, // Errror
{10, 0, 1024*1024 + 100, "reached limit for padding memory slice: 1048666", 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}, // Error
{10, 0, 1024*1024 + 100, "reached limit for padding memory slice: 1048666", 0}, // Error
} {
mem := vm.NewMemory()

2
go.mod
View file

@ -23,7 +23,7 @@ require (
github.com/ethereum/c-kzg-4844 v0.4.0
github.com/fatih/color v1.13.0
github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5
github.com/fjl/memsize v0.0.2
github.com/fsnotify/fsnotify v1.6.0
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff
github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46

7
go.sum
View file

@ -189,8 +189,8 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e h1:bBLctRc7kr01YGvaDfgLbTwjFNW5jdp5y5rj8XXBHfY=
github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA=
github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
@ -221,7 +221,6 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
@ -777,8 +776,6 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=

View file

@ -40,7 +40,7 @@ func MustLoadChecksums(file string) *ChecksumDB {
if err != nil {
log.Fatal("can't load checksum file: " + err.Error())
}
return &ChecksumDB{strings.Split(string(content), "\n")}
return &ChecksumDB{strings.Split(strings.ReplaceAll(string(content), "\r\n", "\n"), "\n")}
}
// Verify checks whether the given file is valid according to the checksum database.

View file

@ -256,7 +256,8 @@ type BigFlag struct {
Hidden bool
HasBeenSet bool
Value *big.Int
Value *big.Int
defaultValue *big.Int
Aliases []string
EnvVars []string
@ -269,6 +270,10 @@ func (f *BigFlag) IsSet() bool { return f.HasBeenSet }
func (f *BigFlag) String() string { return cli.FlagStringer(f) }
func (f *BigFlag) Apply(set *flag.FlagSet) error {
// Set default value so that environment wont be able to overwrite it
if f.Value != nil {
f.defaultValue = new(big.Int).Set(f.Value)
}
for _, envVar := range f.EnvVars {
envVar = strings.TrimSpace(envVar)
if value, found := syscall.Getenv(envVar); found {
@ -283,7 +288,6 @@ func (f *BigFlag) Apply(set *flag.FlagSet) error {
f.Value = new(big.Int)
set.Var((*bigValue)(f.Value), f.Name, f.Usage)
})
return nil
}
@ -310,7 +314,7 @@ func (f *BigFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
return f.defaultValue.String()
}
// bigValue turns *big.Int into a flag.Value

View file

@ -2031,7 +2031,7 @@ var fromAscii = function(str) {
*
* @method transformToFullName
* @param {Object} json-abi
* @return {String} full fnction/event name
* @return {String} full function/event name
*/
var transformToFullName = function (json) {
if (json.name.indexOf('(') !== -1) {
@ -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
* @param {Object}
@ -2757,7 +2757,7 @@ var Batch = function (web3) {
* Should be called to add create new request to batch request
*
* @method add
* @param {Object} jsonrpc requet object
* @param {Object} jsonrpc request object
*/
Batch.prototype.add = function (request) {
this.requests.push(request);
@ -4559,7 +4559,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
* @param {String} iban string
@ -6708,7 +6708,7 @@ var exchangeAbi = require('../contracts/SmartExchange.json');
* @method transfer
* @param {String} from
* @param {String} to iban
* @param {Value} value to be tranfered
* @param {Value} value to be transferred
* @param {Function} callback, callback
*/
var transfer = function (eth, from, to, value, callback) {
@ -6738,7 +6738,7 @@ var transfer = function (eth, from, to, value, callback) {
* @method transferToAddress
* @param {String} from
* @param {String} to
* @param {Value} value to be tranfered
* @param {Value} value to be transferred
* @param {Function} callback, callback
*/
var transferToAddress = function (eth, from, to, value, callback) {
@ -7092,7 +7092,7 @@ module.exports = transfer;
/**
* 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 {Object} cfg (Optional) The configuration options to use for this operation.
*
@ -9446,7 +9446,7 @@ module.exports = transfer;
var M_offset_14 = M[offset + 14];
var M_offset_15 = M[offset + 15];
// Working varialbes
// Working variables
var a = H[0];
var b = H[1];
var c = H[2];

View file

@ -74,7 +74,7 @@ func (g *StandardGauge) Update(v int64) {
g.value.Store(v)
}
// Update updates the gauge's value if v is larger then the current valie.
// Update updates the gauge's value if v is larger then the current value.
func (g *StandardGauge) UpdateIfGt(v int64) {
for {
exist := g.value.Load()

View file

@ -888,7 +888,7 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
// generateParams wraps various of settings for generating sealing task.
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
parentHash common.Hash // Parent block hash, empty means the latest chain head
coinbase common.Address // The fee recipient address for including transaction

View file

@ -127,7 +127,7 @@ func (srv *Server) portMappingLoop() {
} else if !ip.Equal(lastExtIP) {
log.Debug("External IP changed", "ip", extip, "interface", srv.NAT)
} else {
return
continue
}
// Here, we either failed to get the external IP, or it has changed.
lastExtIP = ip

View file

@ -172,7 +172,7 @@ type SimNode struct {
registerOnce sync.Once
}
// Close closes the underlaying node.Node to release
// Close closes the underlying node.Node to release
// acquired resources.
func (sn *SimNode) Close() error {
return sn.node.Close()

View file

@ -631,7 +631,7 @@ func (api *SignerAPI) SignGnosisSafeTx(ctx context.Context, signerAddress common
}
}
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,
// The gnosis safetx input contains a 'safeTxHash' which is the expected safeTxHash that
sighash, _, err := apitypes.TypedDataAndHash(typedData)

View file

@ -389,7 +389,7 @@ func unset(parent node, child node, key []byte, pos int, removeLeft bool) error
} else {
if bytes.Compare(cld.Key, key[pos:]) > 0 {
// 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 entries
// branch. The parent must be a fullnode.
fn := parent.(*fullNode)
fn.Children[key[pos-1]] = nil

View file

@ -333,7 +333,7 @@ func TestLargeValue(t *testing.T) {
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) {
var rt = []randTestStep{
{op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 0