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 // 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. // packs data accordingly.
type ABI struct { type ABI struct {
Constructor Method Constructor Method

View file

@ -241,7 +241,7 @@ func (hub *Hub) refreshWallets() {
card.Disconnect(pcsc.LeaveCard) card.Disconnect(pcsc.LeaveCard)
continue continue
} }
// Card connected, start tracking in amongs the wallets // Card connected, start tracking among 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})
} }

View file

@ -75,7 +75,7 @@ Example:
}, },
{ {
"type": "Info", "type": "Info",
"message": "User should see this aswell" "message": "User should see this as well"
} }
], ],
"meta": { "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 // 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()
} }

View file

@ -894,7 +894,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

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 // 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 (

View file

@ -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

View file

@ -139,7 +139,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.
@ -362,7 +362,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[:])
assertAccount(accNoModCache, accNoModCache[:]) 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) 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])
if err != nil { 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 { if len(fails) > 0 {
log.Warn("Dropping invalidated blob transactions", "ids", fails) log.Warn("Dropping invalidated blob transactions", "ids", fails)
dropInvalidMeter.Mark(int64(len(fails)))
for _, id := range fails { for _, id := range fails {
if err := p.store.Delete(id); err != nil { if err := p.store.Delete(id); err != nil {
p.Close() p.Close()
@ -456,7 +458,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
@ -467,11 +469,17 @@ func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error {
} }
meta := newBlobTxMeta(id, size, tx) 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) 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
@ -537,8 +545,10 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
if gapped { if gapped {
log.Warn("Dropping dangling blob transactions", "from", addr, "missing", next, "drop", nonces, "ids", ids) log.Warn("Dropping dangling blob transactions", "from", addr, "missing", next, "drop", nonces, "ids", ids)
dropDanglingMeter.Mark(int64(len(ids)))
} else { } else {
log.Trace("Dropping filled blob transactions", "from", addr, "filled", nonces, "ids", ids) log.Trace("Dropping filled blob transactions", "from", addr, "filled", nonces, "ids", ids)
dropFilledMeter.Mark(int64(len(ids)))
} }
for _, id := range ids { for _, id := range ids {
if err := p.store.Delete(id); err != nil { 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:] txs = txs[1:]
} }
log.Trace("Dropping overlapped blob transactions", "from", addr, "overlapped", nonces, "ids", ids, "left", len(txs)) log.Trace("Dropping overlapped blob transactions", "from", addr, "overlapped", nonces, "ids", ids, "left", len(txs))
dropOverlappedMeter.Mark(int64(len(ids)))
for _, id := range ids { for _, id := range ids {
if err := p.store.Delete(id); err != nil { if err := p.store.Delete(id); err != nil {
log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err) 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 continue
} }
// Sanity check that there's no double nonce. This case would be a coding // Sanity check that there's no double nonce. This case would generally
// error, but better know about it // 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 { 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 // Otherwise if there's a nonce gap evict all later transactions
var ( var (
@ -621,6 +653,8 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
txs = txs[:i] txs = txs[:i]
log.Error("Dropping gapped blob transactions", "from", addr, "missing", txs[i-1].nonce+1, "drop", nonces, "ids", ids) 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 { for _, id := range ids {
if err := p.store.Delete(id); err != nil { if err := p.store.Delete(id); err != nil {
log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err) 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 p.index[addr] = txs
} }
log.Warn("Dropping overdrafted blob transactions", "from", addr, "balance", balance, "spent", spent, "drop", nonces, "ids", ids) 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 { for _, id := range ids {
if err := p.store.Delete(id); err != nil { if err := p.store.Delete(id); err != nil {
log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err) 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 p.index[addr] = txs
log.Warn("Dropping overcapped blob transactions", "from", addr, "kept", len(txs), "drop", nonces, "ids", ids) log.Warn("Dropping overcapped blob transactions", "from", addr, "kept", len(txs), "drop", nonces, "ids", ids)
dropOvercappedMeter.Mark(int64(len(ids)))
for _, id := range ids { for _, id := range ids {
if err := p.store.Delete(id); err != nil { if err := p.store.Delete(id); err != nil {
log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err) 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 // 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.
@ -952,7 +990,7 @@ func (p *BlobPool) reinject(addr common.Address, txhash common.Hash) error {
return err return err
} }
// Update the indixes and metrics // Update the indices and metrics
meta := newBlobTxMeta(id, p.store.Size(id), tx) meta := newBlobTxMeta(id, p.store.Size(id), tx)
if _, ok := p.index[addr]; !ok { if _, ok := p.index[addr]; !ok {
if err := p.reserve(addr, true); err != nil { 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 // 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) 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 { for _, id := range ids {
if err := p.store.Delete(id); err != nil { if err := p.store.Delete(id); err != nil {
log.Error("Failed to delete dropped transaction", "id", id, "err", err) 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 // 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 { func (p *BlobPool) Add(txs []*types.Transaction, local bool, sync bool) []error {
var ( var (
adds = make([]*types.Transaction, 0, len(txs)) 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 // 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) { func (p *BlobPool) add(tx *types.Transaction) (err error) {
// The blob pool blocks on adding a transaction. This is because blob txs are // 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 // 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 // Ensure the transaction is valid from all perspectives
if err := p.validateTx(tx); err != nil { if err := p.validateTx(tx); err != nil {
log.Trace("Transaction validation failed", "hash", tx.Hash(), "err", err) 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 return err
} }
// If the address is not yet known, request exclusivity to track the account // 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 from, _ := types.Sender(p.signer, tx) // already validated above
if _, ok := p.index[from]; !ok { if _, ok := p.index[from]; !ok {
if err := p.reserve(from, true); err != nil { if err := p.reserve(from, true); err != nil {
addNonExclusiveMeter.Mark(1)
return err return err
} }
defer func() { defer func() {
@ -1244,6 +1301,8 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) {
} }
if len(p.index[from]) > offset { if len(p.index[from]) > offset {
// Transaction replaces a previously queued one // Transaction replaces a previously queued one
dropReplacedMeter.Mark(1)
prev := p.index[from][offset] prev := p.index[from][offset]
if err := p.store.Delete(prev.id); err != nil { if err := p.store.Delete(prev.id); err != nil {
// Shitty situation, but try to recover gracefully instead of going boom // 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() p.updateStorageMetrics()
addValidMeter.Mark(1)
return nil return nil
} }
@ -1371,7 +1431,9 @@ func (p *BlobPool) drop() {
} }
} }
// Remove the transaction from the data store // 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 { if err := p.store.Delete(drop.id); err != nil {
log.Error("Failed to drop evicted transaction", "id", drop.id, "err", err) 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 // - 1. A transaction that cannot be decoded must be dropped
// - 2. A transaction that cannot be recovered (bad signature) 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 // - 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) { func TestOpenDrops(t *testing.T) {
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true))) log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true)))
@ -338,7 +347,7 @@ func TestOpenDrops(t *testing.T) {
badsig, _ := store.Put(blob) badsig, _ := store.Put(blob)
// Insert a sequence of transactions with a nonce gap in between to verify // 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 ( var (
gapper, _ = crypto.GenerateKey() gapper, _ = crypto.GenerateKey()
@ -357,7 +366,7 @@ func TestOpenDrops(t *testing.T) {
} }
} }
// Insert a sequence of transactions with a gapped starting nonce to verify // 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 ( var (
dangler, _ = crypto.GenerateKey() dangler, _ = crypto.GenerateKey()
dangling = make(map[uint64]struct{}) dangling = make(map[uint64]struct{})
@ -370,7 +379,7 @@ func TestOpenDrops(t *testing.T) {
dangling[id] = struct{}{} dangling[id] = struct{}{}
} }
// Insert a sequence of transactions with already passed nonces to veirfy // 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 ( var (
filler, _ = crypto.GenerateKey() filler, _ = crypto.GenerateKey()
filled = make(map[uint64]struct{}) filled = make(map[uint64]struct{})
@ -383,7 +392,7 @@ func TestOpenDrops(t *testing.T) {
filled[id] = struct{}{} filled[id] = struct{}{}
} }
// Insert a sequence of transactions with partially passed nonces to veirfy // 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 ( var (
overlapper, _ = crypto.GenerateKey() overlapper, _ = crypto.GenerateKey()
overlapped = make(map[uint64]struct{}) 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 // 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 ( var (
underpayer, _ = crypto.GenerateKey() underpayer, _ = crypto.GenerateKey()
underpaid = make(map[uint64]struct{}) 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 // 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 ( var (
outpricer, _ = crypto.GenerateKey() outpricer, _ = crypto.GenerateKey()
outpriced = make(map[uint64]struct{}) 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 // Insert a sequence of transactions fully overdrafted to verify that the
// entire set will get invalidated. // entire set will get invalidated (case 6).
var ( var (
exceeder, _ = crypto.GenerateKey() exceeder, _ = crypto.GenerateKey()
exceeded = make(map[uint64]struct{}) exceeded = make(map[uint64]struct{})
@ -459,7 +468,7 @@ func TestOpenDrops(t *testing.T) {
exceeded[id] = struct{}{} exceeded[id] = struct{}{}
} }
// Insert a sequence of transactions partially overdrafted to verify that part // 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 ( var (
overdrafter, _ = crypto.GenerateKey() overdrafter, _ = crypto.GenerateKey()
overdrafted = make(map[uint64]struct{}) 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 // 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 ( var (
overcapper, _ = crypto.GenerateKey() overcapper, _ = crypto.GenerateKey()
overcapped = make(map[uint64]struct{}) overcapped = make(map[uint64]struct{})
@ -496,6 +505,42 @@ func TestOpenDrops(t *testing.T) {
overcapped[id] = struct{}{} 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() store.Close()
// Create a blob pool out of the pre-seeded data // 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(exceeder.PublicKey), uint256.NewInt(1000000))
statedb.AddBalance(crypto.PubkeyToAddress(overdrafter.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(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) statedb.Commit(0, true)
chain := &testBlockChain{ chain := &testBlockChain{
@ -554,6 +601,10 @@ func TestOpenDrops(t *testing.T) {
t.Errorf("partially overdrafted transaction remained in storage: %d", tx.id) t.Errorf("partially overdrafted transaction remained in storage: %d", tx.id)
} else if _, ok := overcapped[tx.id]; ok { } else if _, ok := overcapped[tx.id]; ok {
t.Errorf("overcapped transaction remained in storage: %d", tx.id) 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 { } else {
alive[tx.id] = struct{}{} alive[tx.id] = struct{}{}
} }
@ -584,7 +635,7 @@ func TestOpenDrops(t *testing.T) {
// Tests that transactions loaded from disk are indexed correctly. // 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) {
@ -598,7 +649,7 @@ func TestOpenIndex(t *testing.T) {
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil) store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil)
// Insert a sequence of transactions with varying price points to check that // 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 ( var (
key, _ = crypto.GenerateKey() key, _ = crypto.GenerateKey()
addr = crypto.PubkeyToAddress(key.PublicKey) addr = crypto.PubkeyToAddress(key.PublicKey)
@ -1197,7 +1248,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(uint256.Int).SetUint64(seed.balance)) statedb.AddBalance(addrs[acc], new(uint256.Int).SetUint64(seed.balance))
statedb.SetNonce(addrs[acc], seed.nonce) statedb.SetNonce(addrs[acc], seed.nonce)

View file

@ -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.

View file

@ -65,8 +65,8 @@ 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 whether or not it's capable of keeping up with the load from // the pool and whether it's capable of keeping up with the load from the
// the network. // 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))
getwaitHist = metrics.NewRegisteredHistogram("blobpool/getwait", 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)) pendtimeHist = metrics.NewRegisteredHistogram("blobpool/pendtime", nil, metrics.NewExpDecaySample(1028, 0.015))
resetwaitHist = metrics.NewRegisteredHistogram("blobpool/resetwait", 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)) 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 // Resolve retrieves the full transaction belonging to a lazy handle if it is still
// maintained by the transaction pool. // 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 { func (ltx *LazyTransaction) Resolve() *types.Transaction {
if ltx.Tx == nil { if ltx.Tx != nil {
ltx.Tx = ltx.Pool.Get(ltx.Hash) return ltx.Tx
} }
return ltx.Tx return ltx.Pool.Get(ltx.Hash)
} }
// LazyResolver is a minimal interface needed for a transaction pool to satisfy // 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 // 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

View file

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

View file

@ -43,7 +43,7 @@ type BlobTx struct {
BlobHashes []common.Hash BlobHashes []common.Hash
// A blob transaction can optionally contain blobs. This field must be set when BlobTx // 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:"-"` Sidecar *BlobTxSidecar `rlp:"-"`
// Signature values // Signature values

View file

@ -224,7 +224,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",

View file

@ -163,7 +163,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
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)

View file

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

View file

@ -50,7 +50,8 @@ func newBeaconBackfiller(dl *Downloader, success func()) backfiller {
} }
// suspend cancels any background downloader threads and returns the last header // 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 { func (b *beaconBackfiller) suspend() *types.Header {
// If no filling is running, don't waste cycles // If no filling is running, don't waste cycles
b.lock.Lock() 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 { if err := d.lightchain.SetHead(origin); err != nil {
return err 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 // Initiate the sync using a concurrent header and content retrieval algorithm

View file

@ -161,7 +161,7 @@ type backfiller interface {
// on initial startup. // on initial startup.
// //
// The method should return the last block header that has been successfully // 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 suspend() *types.Header
// resume requests the backfiller to start running fill or snap sync based on // 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{}) done := make(chan struct{})
go func() { go func() {
defer close(done) defer close(done)
if filled := s.filler.suspend(); filled != nil { filled := s.filler.suspend()
// If something was filled, try to delete stale sync helpers. If if filled == nil {
// unsuccessful, warn the user, but not much else we can do (it's log.Error("Latest filled block is not available")
// a programming error, just let users report an issue and don't return
// choke in the meantime). }
if err := s.cleanStales(filled); err != nil { // If something was filled, try to delete stale sync helpers. If
log.Error("Failed to clean stale beacon headers", "err", err) // 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 // 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() number := filled.Number.Uint64()
log.Trace("Cleaning stale beacon headers", "filled", number, "hash", filled.Hash()) log.Trace("Cleaning stale beacon headers", "filled", number, "hash", filled.Hash())
// If the filled header is below the linked subchain, something's // If the filled header is below the linked subchain, something's corrupted
// corrupted internally. Report and error and refuse to do anything. // internally. Report and error and refuse to do anything.
if number < s.progress.Subchains[0].Tail { 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) 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 // If nothing in subchain is filled, don't bother to do cleanup.
// filled header and delete everything before it - if available. In if number+1 == s.progress.Subchains[0].Tail {
// case we filled past the head, recreate the subchain with a new return nil
// head to keep it consistent with the data on disk. }
var ( var (
start = s.progress.Subchains[0].Tail // start deleting from the first known header start uint64
end = number // delete until the requested threshold end uint64
batch = s.db.NewBatch() batch = s.db.NewBatch()
) )
s.progress.Subchains[0].Tail = number if number < s.progress.Subchains[0].Head {
s.progress.Subchains[0].Next = filled.ParentHash // 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
// If more headers were filled than available, push the entire // forward to keep tracking the node's block imports.
// 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 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) 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 // The entire original skeleton chain was deleted and a new one
// defined. Make sure the new single-header chain gets pushed to // defined. Make sure the new single-header chain gets pushed to
// disk to keep internal state consistent. // disk to keep internal state consistent.
rawdb.WriteSkeletonHeader(batch, filled) rawdb.WriteSkeletonHeader(batch, filled)
}
} }
// Execute the trimming and the potential rewiring of the progress // Execute the trimming and the potential rewiring of the progress
s.saveSyncStatus(batch) s.saveSyncStatus(batch)

View file

@ -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) {

View file

@ -124,9 +124,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()

2
go.mod
View file

@ -23,7 +23,7 @@ require (
github.com/ethereum/c-kzg-4844 v0.4.0 github.com/ethereum/c-kzg-4844 v0.4.0
github.com/fatih/color v1.13.0 github.com/fatih/color v1.13.0
github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e 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/fsnotify/fsnotify v1.6.0
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff
github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 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/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 h1:bBLctRc7kr01YGvaDfgLbTwjFNW5jdp5y5rj8XXBHfY=
github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= 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.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= 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/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.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 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.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= 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-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.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 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= 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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.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.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 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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= 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 { if err != nil {
log.Fatal("can't load checksum file: " + err.Error()) 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. // Verify checks whether the given file is valid according to the checksum database.

View file

@ -256,7 +256,8 @@ type BigFlag struct {
Hidden bool Hidden bool
HasBeenSet bool HasBeenSet bool
Value *big.Int Value *big.Int
defaultValue *big.Int
Aliases []string Aliases []string
EnvVars []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) String() string { return cli.FlagStringer(f) }
func (f *BigFlag) Apply(set *flag.FlagSet) error { 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 { for _, envVar := range f.EnvVars {
envVar = strings.TrimSpace(envVar) envVar = strings.TrimSpace(envVar)
if value, found := syscall.Getenv(envVar); found { if value, found := syscall.Getenv(envVar); found {
@ -283,7 +288,6 @@ func (f *BigFlag) Apply(set *flag.FlagSet) error {
f.Value = new(big.Int) f.Value = new(big.Int)
set.Var((*bigValue)(f.Value), f.Name, f.Usage) set.Var((*bigValue)(f.Value), f.Name, f.Usage)
}) })
return nil return nil
} }
@ -310,7 +314,7 @@ func (f *BigFlag) GetDefaultText() string {
if f.DefaultText != "" { if f.DefaultText != "" {
return f.DefaultText return f.DefaultText
} }
return f.GetValue() return f.defaultValue.String()
} }
// bigValue turns *big.Int into a flag.Value // bigValue turns *big.Int into a flag.Value

View file

@ -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) {
@ -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);
@ -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 * @method isValid
* @param {String} iban string * @param {String} iban string
@ -6708,7 +6708,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) {
@ -6738,7 +6738,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) {
@ -7092,7 +7092,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.
* *
@ -9446,7 +9446,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];

View file

@ -74,7 +74,7 @@ func (g *StandardGauge) Update(v int64) {
g.value.Store(v) 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) { func (g *StandardGauge) UpdateIfGt(v int64) {
for { for {
exist := g.value.Load() 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. // 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

View file

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

View file

@ -172,7 +172,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()

View file

@ -631,7 +631,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)

View file

@ -389,7 +389,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 entries
// 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

View file

@ -333,7 +333,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