revert the changes in blobTxMeta

This commit is contained in:
maskpp 2025-08-09 20:00:17 +08:00
parent 98af70fdb7
commit e9da3f2369
5 changed files with 208 additions and 208 deletions

View file

@ -90,20 +90,20 @@ const (
// bare minimum needed fields to keep the size down (and thus number of entries // bare minimum needed fields to keep the size down (and thus number of entries
// larger with the same memory consumption). // larger with the same memory consumption).
type blobTxMeta struct { type blobTxMeta struct {
TxHash common.Hash // Transaction hash to maintain the lookup table hash common.Hash // Transaction hash to maintain the lookup table
VHashes []common.Hash // Blob versioned hashes to maintain the lookup table vhashes []common.Hash // Blob versioned hashes to maintain the lookup table
Id uint64 // Storage ID in the pool's persistent store id uint64 // Storage ID in the pool's persistent store
StorageSize uint32 // Byte size in the pool's persistent store storageSize uint32 // Byte size in the pool's persistent store
Size uint64 // RLP-encoded size of transaction including the attached blob size uint64 // RLP-encoded size of transaction including the attached blob
Nonce uint64 // Needed to prioritize inclusion order within an account nonce uint64 // Needed to prioritize inclusion order within an account
CostCap *uint256.Int // Needed to validate cumulative balance sufficiency costCap *uint256.Int // Needed to validate cumulative balance sufficiency
ExecTipCap *uint256.Int // Needed to prioritize inclusion order across accounts and validate replacement price bump execTipCap *uint256.Int // Needed to prioritize inclusion order across accounts and validate replacement price bump
ExecFeeCap *uint256.Int // Needed to validate replacement price bump execFeeCap *uint256.Int // Needed to validate replacement price bump
BlobFeeCap *uint256.Int // Needed to validate replacement price bump blobFeeCap *uint256.Int // Needed to validate replacement price bump
ExecGas uint64 // Needed to check inclusion validity before reading the blob execGas uint64 // Needed to check inclusion validity before reading the blob
BlobGas uint64 // Needed to check inclusion validity before reading the blob blobGas uint64 // Needed to check inclusion validity before reading the blob
basefeeJumps float64 // Absolute number of 1559 fee adjustments needed to reach the tx's fee cap basefeeJumps float64 // Absolute number of 1559 fee adjustments needed to reach the tx's fee cap
blobfeeJumps float64 // Absolute number of 4844 fee adjustments needed to reach the tx's blob fee cap blobfeeJumps float64 // Absolute number of 4844 fee adjustments needed to reach the tx's blob fee cap
@ -117,21 +117,21 @@ type blobTxMeta struct {
// and assembles a helper struct to track in memory. // and assembles a helper struct to track in memory.
func newBlobTxMeta(id uint64, size uint64, storageSize uint32, tx *types.Transaction) *blobTxMeta { func newBlobTxMeta(id uint64, size uint64, storageSize uint32, tx *types.Transaction) *blobTxMeta {
meta := &blobTxMeta{ meta := &blobTxMeta{
TxHash: tx.Hash(), hash: tx.Hash(),
VHashes: tx.BlobHashes(), vhashes: tx.BlobHashes(),
Id: id, id: id,
StorageSize: storageSize, storageSize: storageSize,
Size: size, size: size,
Nonce: tx.Nonce(), nonce: tx.Nonce(),
CostCap: uint256.MustFromBig(tx.Cost()), costCap: uint256.MustFromBig(tx.Cost()),
ExecTipCap: uint256.MustFromBig(tx.GasTipCap()), execTipCap: uint256.MustFromBig(tx.GasTipCap()),
ExecFeeCap: uint256.MustFromBig(tx.GasFeeCap()), execFeeCap: uint256.MustFromBig(tx.GasFeeCap()),
BlobFeeCap: uint256.MustFromBig(tx.BlobGasFeeCap()), blobFeeCap: uint256.MustFromBig(tx.BlobGasFeeCap()),
ExecGas: tx.Gas(), execGas: tx.Gas(),
BlobGas: tx.BlobGas(), blobGas: tx.BlobGas(),
} }
meta.basefeeJumps = dynamicFeeJumps(meta.ExecFeeCap) meta.basefeeJumps = dynamicFeeJumps(meta.execFeeCap)
meta.blobfeeJumps = dynamicFeeJumps(meta.BlobFeeCap) meta.blobfeeJumps = dynamicFeeJumps(meta.blobFeeCap)
return meta return meta
} }
@ -486,7 +486,7 @@ func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error {
} }
meta := newBlobTxMeta(id, tx.Size(), size, tx) meta := newBlobTxMeta(id, tx.Size(), size, tx)
if p.lookup.exists(meta.TxHash) { if p.lookup.exists(meta.hash) {
// This path is only possible after a crash, where deleted items are not // This path is only possible after a crash, where deleted items are not
// removed via the normal shutdown-startup procedure and thus may get // removed via the normal shutdown-startup procedure and thus may get
// partially resurrected. // partially resurrected.
@ -509,10 +509,10 @@ func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error {
p.spent[sender] = new(uint256.Int) p.spent[sender] = new(uint256.Int)
} }
p.index[sender] = append(p.index[sender], meta) p.index[sender] = append(p.index[sender], meta)
p.spent[sender] = new(uint256.Int).Add(p.spent[sender], meta.CostCap) p.spent[sender] = new(uint256.Int).Add(p.spent[sender], meta.costCap)
p.lookup.track(meta) p.lookup.track(meta)
p.stored += uint64(meta.StorageSize) p.stored += uint64(meta.storageSize)
return nil return nil
} }
@ -525,15 +525,15 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
return return
} }
sort.Slice(txs, func(i, j int) bool { sort.Slice(txs, func(i, j int) bool {
return txs[i].Nonce < txs[j].Nonce return txs[i].nonce < txs[j].nonce
}) })
// If there is a gap between the chain state and the blob pool, drop // If there is a gap between the chain state and the blob pool, drop
// all the transactions as they are non-executable. Similarly, if the // all the transactions as they are non-executable. Similarly, if the
// entire tx range was included, drop all. // entire tx range was included, drop all.
var ( var (
next = p.state.GetNonce(addr) next = p.state.GetNonce(addr)
gapped = txs[0].Nonce > next gapped = txs[0].nonce > next
filled = txs[len(txs)-1].Nonce < next filled = txs[len(txs)-1].nonce < next
) )
if gapped || filled { if gapped || filled {
var ( var (
@ -541,13 +541,13 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
nonces []uint64 nonces []uint64
) )
for i := 0; i < len(txs); i++ { for i := 0; i < len(txs); i++ {
ids = append(ids, txs[i].Id) ids = append(ids, txs[i].id)
nonces = append(nonces, txs[i].Nonce) nonces = append(nonces, txs[i].nonce)
p.stored -= uint64(txs[i].StorageSize) p.stored -= uint64(txs[i].storageSize)
p.lookup.untrack(txs[i]) p.lookup.untrack(txs[i])
// Included transactions blobs need to be recorded in the limbo // Included transactions blobs need to be moved to the limbo
if filled && inclusions != nil { if filled && inclusions != nil {
p.offload(addr, txs[i], inclusions) p.offload(addr, txs[i], inclusions)
} }
@ -579,20 +579,20 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
} }
// If there is overlap between the chain state and the blob pool, drop // If there is overlap between the chain state and the blob pool, drop
// anything below the current state // anything below the current state
if txs[0].Nonce < next { if txs[0].nonce < next {
var ( var (
ids []uint64 ids []uint64
nonces []uint64 nonces []uint64
) )
for len(txs) > 0 && txs[0].Nonce < next { for len(txs) > 0 && txs[0].nonce < next {
ids = append(ids, txs[0].Id) ids = append(ids, txs[0].id)
nonces = append(nonces, txs[0].Nonce) nonces = append(nonces, txs[0].nonce)
p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[0].CostCap) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[0].costCap)
p.stored -= uint64(txs[0].StorageSize) p.stored -= uint64(txs[0].storageSize)
p.lookup.untrack(txs[0]) p.lookup.untrack(txs[0])
// Included transactions blobs need to be recorded in the limbo. // Included transactions blobs need to be moved to the limbo
if inclusions != nil { if inclusions != nil {
p.offload(addr, txs[0], inclusions) p.offload(addr, txs[0], inclusions)
} }
@ -613,17 +613,17 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
} }
// Iterate over the transactions to initialize their eviction thresholds // Iterate over the transactions to initialize their eviction thresholds
// and to detect any nonce gaps // and to detect any nonce gaps
txs[0].evictionExecTip = txs[0].ExecTipCap txs[0].evictionExecTip = txs[0].execTipCap
txs[0].evictionExecFeeJumps = txs[0].basefeeJumps txs[0].evictionExecFeeJumps = txs[0].basefeeJumps
txs[0].evictionBlobFeeJumps = txs[0].blobfeeJumps txs[0].evictionBlobFeeJumps = txs[0].blobfeeJumps
for i := 1; i < len(txs); i++ { for i := 1; i < len(txs); i++ {
// If there's no nonce gap, initialize the eviction thresholds as the // If there's no nonce gap, initialize the eviction thresholds as the
// minimum between the cumulative thresholds and the current tx fees // minimum between the cumulative thresholds and the current tx fees
if txs[i].Nonce == txs[i-1].Nonce+1 { if txs[i].nonce == txs[i-1].nonce+1 {
txs[i].evictionExecTip = txs[i-1].evictionExecTip txs[i].evictionExecTip = txs[i-1].evictionExecTip
if txs[i].evictionExecTip.Cmp(txs[i].ExecTipCap) > 0 { if txs[i].evictionExecTip.Cmp(txs[i].execTipCap) > 0 {
txs[i].evictionExecTip = txs[i].ExecTipCap txs[i].evictionExecTip = txs[i].execTipCap
} }
txs[i].evictionExecFeeJumps = txs[i-1].evictionExecFeeJumps txs[i].evictionExecFeeJumps = txs[i-1].evictionExecFeeJumps
if txs[i].evictionExecFeeJumps > txs[i].basefeeJumps { if txs[i].evictionExecFeeJumps > txs[i].basefeeJumps {
@ -641,14 +641,14 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
// Also, Billy behind the blobpool does not journal deletes. A process // Also, Billy behind the blobpool does not journal deletes. A process
// crash would result in previously deleted entities being resurrected. // crash would result in previously deleted entities being resurrected.
// That could potentially cause a duplicate nonce to appear. // 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 {
id, _ := p.lookup.storeidOfTx(txs[i].TxHash) id, _ := p.lookup.storeidOfTx(txs[i].hash)
log.Error("Dropping repeat Nonce blob transaction", "from", addr, "nonce", txs[i].Nonce, "id", id) log.Error("Dropping repeat nonce blob transaction", "from", addr, "nonce", txs[i].nonce, "id", id)
dropRepeatedMeter.Mark(1) dropRepeatedMeter.Mark(1)
p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[i].CostCap) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[i].costCap)
p.stored -= uint64(txs[i].StorageSize) p.stored -= uint64(txs[i].storageSize)
p.lookup.untrack(txs[i]) p.lookup.untrack(txs[i])
if err := p.store.Delete(id); err != nil { if err := p.store.Delete(id); err != nil {
@ -666,16 +666,16 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
nonces []uint64 nonces []uint64
) )
for j := i; j < len(txs); j++ { for j := i; j < len(txs); j++ {
ids = append(ids, txs[j].Id) ids = append(ids, txs[j].id)
nonces = append(nonces, txs[j].Nonce) nonces = append(nonces, txs[j].nonce)
p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[j].CostCap) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[j].costCap)
p.stored -= uint64(txs[j].StorageSize) p.stored -= uint64(txs[j].storageSize)
p.lookup.untrack(txs[j]) p.lookup.untrack(txs[j])
} }
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))) dropGappedMeter.Mark(int64(len(ids)))
for _, id := range ids { for _, id := range ids {
@ -704,11 +704,11 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
txs[len(txs)-1] = nil txs[len(txs)-1] = nil
txs = txs[:len(txs)-1] txs = txs[:len(txs)-1]
ids = append(ids, last.Id) ids = append(ids, last.id)
nonces = append(nonces, last.Nonce) nonces = append(nonces, last.nonce)
p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], last.CostCap) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], last.costCap)
p.stored -= uint64(last.StorageSize) p.stored -= uint64(last.storageSize)
p.lookup.untrack(last) p.lookup.untrack(last)
} }
if len(txs) == 0 { if len(txs) == 0 {
@ -744,11 +744,11 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
txs[len(txs)-1] = nil txs[len(txs)-1] = nil
txs = txs[:len(txs)-1] txs = txs[:len(txs)-1]
ids = append(ids, last.Id) ids = append(ids, last.id)
nonces = append(nonces, last.Nonce) nonces = append(nonces, last.nonce)
p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], last.CostCap) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], last.costCap)
p.stored -= uint64(last.StorageSize) p.stored -= uint64(last.storageSize)
p.lookup.untrack(last) p.lookup.untrack(last)
} }
p.index[addr] = txs p.index[addr] = txs
@ -777,9 +777,9 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
// 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.
func (p *BlobPool) offload(addr common.Address, blobTxMeta *blobTxMeta, inclusions map[common.Hash]uint64) { func (p *BlobPool) offload(addr common.Address, blobTxMeta *blobTxMeta, inclusions map[common.Hash]uint64) {
block, ok := inclusions[blobTxMeta.TxHash] block, ok := inclusions[blobTxMeta.hash]
if !ok { if !ok {
log.Warn("Blob transaction swapped out by signer", "from", addr, "nonce", blobTxMeta.Nonce, "id", blobTxMeta.Id) log.Warn("Blob transaction swapped out by signer", "from", addr, "nonce", blobTxMeta.nonce, "id", blobTxMeta.id)
return return
} }
if err := p.limbo.push(blobTxMeta, block); err != nil { if err := p.limbo.push(blobTxMeta, block); err != nil {
@ -995,18 +995,18 @@ func (p *BlobPool) reinject(addr common.Address, txhash common.Hash) error {
} }
if _, ok := p.index[addr]; !ok { if _, ok := p.index[addr]; !ok {
if err := p.reserver.Hold(addr); err != nil { if err := p.reserver.Hold(addr); err != nil {
log.Warn("Failed to reserve account for blob pool", "tx", meta.TxHash, "from", addr, "err", err) log.Warn("Failed to reserve account for blob pool", "tx", meta.hash, "from", addr, "err", err)
return err return err
} }
p.index[addr] = []*blobTxMeta{meta} p.index[addr] = []*blobTxMeta{meta}
p.spent[addr] = meta.CostCap p.spent[addr] = meta.costCap
p.evict.Push(addr) p.evict.Push(addr)
} else { } else {
p.index[addr] = append(p.index[addr], meta) p.index[addr] = append(p.index[addr], meta)
p.spent[addr] = new(uint256.Int).Add(p.spent[addr], meta.CostCap) p.spent[addr] = new(uint256.Int).Add(p.spent[addr], meta.costCap)
} }
p.lookup.track(meta) p.lookup.track(meta)
p.stored += uint64(meta.StorageSize) p.stored += uint64(meta.storageSize)
return nil return nil
} }
@ -1024,24 +1024,24 @@ func (p *BlobPool) SetGasTip(tip *big.Int) {
if old == nil || p.gasTip.Cmp(old) > 0 { if old == nil || p.gasTip.Cmp(old) > 0 {
for addr, txs := range p.index { for addr, txs := range p.index {
for i, tx := range txs { for i, tx := range txs {
if tx.ExecTipCap.Cmp(p.gasTip) < 0 { if tx.execTipCap.Cmp(p.gasTip) < 0 {
// Drop the offending transaction // Drop the offending transaction
var ( var (
ids = []uint64{tx.Id} ids = []uint64{tx.id}
nonces = []uint64{tx.Nonce} nonces = []uint64{tx.nonce}
) )
p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[i].CostCap) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[i].costCap)
p.stored -= uint64(tx.StorageSize) p.stored -= uint64(tx.storageSize)
p.lookup.untrack(tx) p.lookup.untrack(tx)
txs[i] = nil txs[i] = nil
// Drop everything afterwards, no gaps allowed // Drop everything afterwards, no gaps allowed
for j, tx := range txs[i+1:] { for j, tx := range txs[i+1:] {
ids = append(ids, tx.Id) ids = append(ids, tx.id)
nonces = append(nonces, tx.Nonce) nonces = append(nonces, tx.nonce)
p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], tx.CostCap) p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], tx.costCap)
p.stored -= uint64(tx.StorageSize) p.stored -= uint64(tx.storageSize)
p.lookup.untrack(tx) p.lookup.untrack(tx)
txs[i+1+j] = nil txs[i+1+j] = nil
} }
@ -1057,7 +1057,7 @@ func (p *BlobPool) SetGasTip(tip *big.Int) {
p.reserver.Release(addr) p.reserver.Release(addr)
} }
// 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))) dropUnderpricedMeter.Mark(int64(len(ids)))
for _, id := range ids { for _, id := range ids {
@ -1117,7 +1117,7 @@ func (p *BlobPool) checkDelegationLimit(tx *types.Transaction) error {
return nil return nil
} }
// If account already has a pending transaction, allow replacement only. // If account already has a pending transaction, allow replacement only.
if len(pending) == 1 && pending[0].Nonce == tx.Nonce() { if len(pending) == 1 && pending[0].nonce == tx.Nonce() {
return nil return nil
} }
return txpool.ErrInflightTxLimitReached return txpool.ErrInflightTxLimitReached
@ -1155,7 +1155,7 @@ func (p *BlobPool) validateTx(tx *types.Transaction) error {
ExistingCost: func(addr common.Address, nonce uint64) *big.Int { ExistingCost: func(addr common.Address, nonce uint64) *big.Int {
next := p.state.GetNonce(addr) next := p.state.GetNonce(addr)
if uint64(len(p.index[addr])) > nonce-next { if uint64(len(p.index[addr])) > nonce-next {
return p.index[addr][int(nonce-next)].CostCap.ToBig() return p.index[addr][int(nonce-next)].costCap.ToBig()
} }
return nil return nil
}, },
@ -1175,33 +1175,33 @@ func (p *BlobPool) validateTx(tx *types.Transaction) error {
if uint64(len(p.index[from])) > tx.Nonce()-next { if uint64(len(p.index[from])) > tx.Nonce()-next {
prev := p.index[from][int(tx.Nonce()-next)] prev := p.index[from][int(tx.Nonce()-next)]
// Ensure the transaction is different than the one tracked locally // Ensure the transaction is different than the one tracked locally
if prev.TxHash == tx.Hash() { if prev.hash == tx.Hash() {
return txpool.ErrAlreadyKnown return txpool.ErrAlreadyKnown
} }
// Account can support the replacement, but the price bump must also be met // Account can support the replacement, but the price bump must also be met
switch { switch {
case tx.GasFeeCapIntCmp(prev.ExecFeeCap.ToBig()) <= 0: case tx.GasFeeCapIntCmp(prev.execFeeCap.ToBig()) <= 0:
return fmt.Errorf("%w: new tx gas fee cap %v <= %v queued", txpool.ErrReplaceUnderpriced, tx.GasFeeCap(), prev.ExecFeeCap) return fmt.Errorf("%w: new tx gas fee cap %v <= %v queued", txpool.ErrReplaceUnderpriced, tx.GasFeeCap(), prev.execFeeCap)
case tx.GasTipCapIntCmp(prev.ExecTipCap.ToBig()) <= 0: case tx.GasTipCapIntCmp(prev.execTipCap.ToBig()) <= 0:
return fmt.Errorf("%w: new tx gas tip cap %v <= %v queued", txpool.ErrReplaceUnderpriced, tx.GasTipCap(), prev.ExecTipCap) return fmt.Errorf("%w: new tx gas tip cap %v <= %v queued", txpool.ErrReplaceUnderpriced, tx.GasTipCap(), prev.execTipCap)
case tx.BlobGasFeeCapIntCmp(prev.BlobFeeCap.ToBig()) <= 0: case tx.BlobGasFeeCapIntCmp(prev.blobFeeCap.ToBig()) <= 0:
return fmt.Errorf("%w: new tx blob gas fee cap %v <= %v queued", txpool.ErrReplaceUnderpriced, tx.BlobGasFeeCap(), prev.BlobFeeCap) return fmt.Errorf("%w: new tx blob gas fee cap %v <= %v queued", txpool.ErrReplaceUnderpriced, tx.BlobGasFeeCap(), prev.blobFeeCap)
} }
var ( var (
multiplier = uint256.NewInt(100 + p.config.PriceBump) multiplier = uint256.NewInt(100 + p.config.PriceBump)
onehundred = uint256.NewInt(100) onehundred = uint256.NewInt(100)
minGasFeeCap = new(uint256.Int).Div(new(uint256.Int).Mul(multiplier, prev.ExecFeeCap), onehundred) minGasFeeCap = new(uint256.Int).Div(new(uint256.Int).Mul(multiplier, prev.execFeeCap), onehundred)
minGasTipCap = new(uint256.Int).Div(new(uint256.Int).Mul(multiplier, prev.ExecTipCap), onehundred) minGasTipCap = new(uint256.Int).Div(new(uint256.Int).Mul(multiplier, prev.execTipCap), onehundred)
minBlobGasFeeCap = new(uint256.Int).Div(new(uint256.Int).Mul(multiplier, prev.BlobFeeCap), onehundred) minBlobGasFeeCap = new(uint256.Int).Div(new(uint256.Int).Mul(multiplier, prev.blobFeeCap), onehundred)
) )
switch { switch {
case tx.GasFeeCapIntCmp(minGasFeeCap.ToBig()) < 0: case tx.GasFeeCapIntCmp(minGasFeeCap.ToBig()) < 0:
return fmt.Errorf("%w: new tx gas fee cap %v < %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.GasFeeCap(), prev.ExecFeeCap, p.config.PriceBump) return fmt.Errorf("%w: new tx gas fee cap %v < %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.GasFeeCap(), prev.execFeeCap, p.config.PriceBump)
case tx.GasTipCapIntCmp(minGasTipCap.ToBig()) < 0: case tx.GasTipCapIntCmp(minGasTipCap.ToBig()) < 0:
return fmt.Errorf("%w: new tx gas tip cap %v < %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.GasTipCap(), prev.ExecTipCap, p.config.PriceBump) return fmt.Errorf("%w: new tx gas tip cap %v < %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.GasTipCap(), prev.execTipCap, p.config.PriceBump)
case tx.BlobGasFeeCapIntCmp(minBlobGasFeeCap.ToBig()) < 0: case tx.BlobGasFeeCapIntCmp(minBlobGasFeeCap.ToBig()) < 0:
return fmt.Errorf("%w: new tx blob gas fee cap %v < %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.BlobGasFeeCap(), prev.BlobFeeCap, p.config.PriceBump) return fmt.Errorf("%w: new tx blob gas fee cap %v < %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.BlobGasFeeCap(), prev.blobFeeCap, p.config.PriceBump)
} }
} }
return nil return nil
@ -1422,7 +1422,7 @@ 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", "TxHash", tx.Hash(), "err", err) log.Trace("Transaction validation failed", "hash", tx.Hash(), "err", err)
switch { switch {
case errors.Is(err, txpool.ErrUnderpriced): case errors.Is(err, txpool.ErrUnderpriced):
addUnderpricedMeter.Mark(1) addUnderpricedMeter.Mark(1)
@ -1491,18 +1491,18 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) {
dropReplacedMeter.Mark(1) 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
log.Error("Failed to delete replaced transaction", "id", prev.Id, "err", err) log.Error("Failed to delete replaced transaction", "id", prev.id, "err", err)
} }
// Update the transaction index // Update the transaction index
p.index[from][offset] = meta p.index[from][offset] = meta
p.spent[from] = new(uint256.Int).Sub(p.spent[from], prev.CostCap) p.spent[from] = new(uint256.Int).Sub(p.spent[from], prev.costCap)
p.spent[from] = new(uint256.Int).Add(p.spent[from], meta.CostCap) p.spent[from] = new(uint256.Int).Add(p.spent[from], meta.costCap)
p.lookup.untrack(prev) p.lookup.untrack(prev)
p.lookup.track(meta) p.lookup.track(meta)
p.stored += uint64(meta.StorageSize) - uint64(prev.StorageSize) p.stored += uint64(meta.storageSize) - uint64(prev.storageSize)
} else { } else {
// Transaction extends previously scheduled ones // Transaction extends previously scheduled ones
p.index[from] = append(p.index[from], meta) p.index[from] = append(p.index[from], meta)
@ -1510,9 +1510,9 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) {
p.spent[from] = new(uint256.Int) p.spent[from] = new(uint256.Int)
newacc = true newacc = true
} }
p.spent[from] = new(uint256.Int).Add(p.spent[from], meta.CostCap) p.spent[from] = new(uint256.Int).Add(p.spent[from], meta.costCap)
p.lookup.track(meta) p.lookup.track(meta)
p.stored += uint64(meta.StorageSize) p.stored += uint64(meta.storageSize)
} }
// Recompute the rolling eviction fields. In case of a replacement, this will // Recompute the rolling eviction fields. In case of a replacement, this will
// recompute all subsequent fields. In case of an append, this will only do // recompute all subsequent fields. In case of an append, this will only do
@ -1522,7 +1522,7 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) {
for i := offset; i < len(txs); i++ { for i := offset; i < len(txs); i++ {
// The first transaction will always use itself // The first transaction will always use itself
if i == 0 { if i == 0 {
txs[0].evictionExecTip = txs[0].ExecTipCap txs[0].evictionExecTip = txs[0].execTipCap
txs[0].evictionExecFeeJumps = txs[0].basefeeJumps txs[0].evictionExecFeeJumps = txs[0].basefeeJumps
txs[0].evictionBlobFeeJumps = txs[0].blobfeeJumps txs[0].evictionBlobFeeJumps = txs[0].blobfeeJumps
@ -1530,8 +1530,8 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) {
} }
// Subsequent transactions will use a rolling calculation // Subsequent transactions will use a rolling calculation
txs[i].evictionExecTip = txs[i-1].evictionExecTip txs[i].evictionExecTip = txs[i-1].evictionExecTip
if txs[i].evictionExecTip.Cmp(txs[i].ExecTipCap) > 0 { if txs[i].evictionExecTip.Cmp(txs[i].execTipCap) > 0 {
txs[i].evictionExecTip = txs[i].ExecTipCap txs[i].evictionExecTip = txs[i].execTipCap
} }
txs[i].evictionExecFeeJumps = txs[i-1].evictionExecFeeJumps txs[i].evictionExecFeeJumps = txs[i-1].evictionExecFeeJumps
if txs[i].evictionExecFeeJumps > txs[i].basefeeJumps { if txs[i].evictionExecFeeJumps > txs[i].basefeeJumps {
@ -1597,9 +1597,9 @@ func (p *BlobPool) drop() {
txs = txs[:len(txs)-1] txs = txs[:len(txs)-1]
p.index[from] = txs p.index[from] = txs
p.spent[from] = new(uint256.Int).Sub(p.spent[from], drop.CostCap) p.spent[from] = new(uint256.Int).Sub(p.spent[from], drop.costCap)
} }
p.stored -= uint64(drop.StorageSize) p.stored -= uint64(drop.storageSize)
p.lookup.untrack(drop) p.lookup.untrack(drop)
// Remove the transaction from the pool's eviction heap: // Remove the transaction from the pool's eviction heap:
@ -1618,11 +1618,11 @@ func (p *BlobPool) drop() {
} }
} }
// Remove the transaction from the data store // Remove the transaction from the data store
log.Debug("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) 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)
} }
} }
@ -1657,36 +1657,36 @@ func (p *BlobPool) Pending(filter txpool.PendingFilter) map[common.Address][]*tx
for _, tx := range txs { for _, tx := range txs {
// If transaction filtering was requested, discard badly priced ones // If transaction filtering was requested, discard badly priced ones
if filter.MinTip != nil && filter.BaseFee != nil { if filter.MinTip != nil && filter.BaseFee != nil {
if tx.ExecFeeCap.Lt(filter.BaseFee) { if tx.execFeeCap.Lt(filter.BaseFee) {
break // basefee too low, cannot be included, discard rest of txs from the account break // basefee too low, cannot be included, discard rest of txs from the account
} }
tip := new(uint256.Int).Sub(tx.ExecFeeCap, filter.BaseFee) tip := new(uint256.Int).Sub(tx.execFeeCap, filter.BaseFee)
if tip.Gt(tx.ExecTipCap) { if tip.Gt(tx.execTipCap) {
tip = tx.ExecTipCap tip = tx.execTipCap
} }
if tip.Lt(filter.MinTip) { if tip.Lt(filter.MinTip) {
break // allowed or remaining tip too low, cannot be included, discard rest of txs from the account break // allowed or remaining tip too low, cannot be included, discard rest of txs from the account
} }
} }
if filter.BlobFee != nil { if filter.BlobFee != nil {
if tx.BlobFeeCap.Lt(filter.BlobFee) { if tx.blobFeeCap.Lt(filter.BlobFee) {
break // blobfee too low, cannot be included, discard rest of txs from the account break // blobfee too low, cannot be included, discard rest of txs from the account
} }
} }
if filter.GasLimitCap != 0 { if filter.GasLimitCap != 0 {
if tx.ExecGas > filter.GasLimitCap { if tx.execGas > filter.GasLimitCap {
break // execution gas limit is too high break // execution gas limit is too high
} }
} }
// Transaction was accepted according to the filter, append to the pending list // Transaction was accepted according to the filter, append to the pending list
lazies = append(lazies, &txpool.LazyTransaction{ lazies = append(lazies, &txpool.LazyTransaction{
Pool: p, Pool: p,
Hash: tx.TxHash, Hash: tx.hash,
Time: execStart, // TODO(karalabe): Maybe save these and use that? Time: execStart, // TODO(karalabe): Maybe save these and use that?
GasFeeCap: tx.ExecFeeCap, GasFeeCap: tx.execFeeCap,
GasTipCap: tx.ExecTipCap, GasTipCap: tx.execTipCap,
Gas: tx.ExecGas, Gas: tx.execGas,
BlobGas: tx.BlobGas, BlobGas: tx.blobGas,
}) })
} }
if len(lazies) > 0 { if len(lazies) > 0 {
@ -1790,7 +1790,7 @@ func (p *BlobPool) Nonce(addr common.Address) uint64 {
defer p.lock.Unlock() defer p.lock.Unlock()
if txs, ok := p.index[addr]; ok { if txs, ok := p.index[addr]; ok {
return txs[len(txs)-1].Nonce + 1 return txs[len(txs)-1].nonce + 1
} }
return p.state.GetNonce(addr) return p.state.GetNonce(addr)
} }

View file

@ -283,10 +283,10 @@ func verifyPoolInternals(t *testing.T, pool *BlobPool) {
seen := make(map[common.Hash]struct{}) seen := make(map[common.Hash]struct{})
for addr, txs := range pool.index { for addr, txs := range pool.index {
for _, tx := range txs { for _, tx := range txs {
if _, ok := seen[tx.TxHash]; ok { if _, ok := seen[tx.hash]; ok {
t.Errorf("duplicate hash #%x in transaction index: address %s, nonce %d", tx.TxHash, addr, tx.Nonce) t.Errorf("duplicate hash #%x in transaction index: address %s, nonce %d", tx.hash, addr, tx.nonce)
} }
seen[tx.TxHash] = struct{}{} seen[tx.hash] = struct{}{}
} }
} }
for hash, id := range pool.lookup.txIndex { for hash, id := range pool.lookup.txIndex {
@ -302,11 +302,11 @@ func verifyPoolInternals(t *testing.T, pool *BlobPool) {
blobs := make(map[common.Hash]map[common.Hash]struct{}) blobs := make(map[common.Hash]map[common.Hash]struct{})
for _, txs := range pool.index { for _, txs := range pool.index {
for _, tx := range txs { for _, tx := range txs {
for _, vhash := range tx.VHashes { for _, vhash := range tx.vhashes {
if blobs[vhash] == nil { if blobs[vhash] == nil {
blobs[vhash] = make(map[common.Hash]struct{}) blobs[vhash] = make(map[common.Hash]struct{})
} }
blobs[vhash][tx.TxHash] = struct{}{} blobs[vhash][tx.hash] = struct{}{}
} }
} }
} }
@ -328,18 +328,18 @@ func verifyPoolInternals(t *testing.T, pool *BlobPool) {
// and that the first nonce is the next expected one based on the state. // and that the first nonce is the next expected one based on the state.
for addr, txs := range pool.index { for addr, txs := range pool.index {
for i := 1; i < len(txs); i++ { for i := 1; i < len(txs); i++ {
if txs[i].Nonce != txs[i-1].Nonce+1 { if txs[i].nonce != txs[i-1].nonce+1 {
t.Errorf("addr %v, tx %d nonce mismatch: have %d, want %d", addr, i, txs[i].Nonce, txs[i-1].Nonce+1) t.Errorf("addr %v, tx %d nonce mismatch: have %d, want %d", addr, i, txs[i].nonce, txs[i-1].nonce+1)
} }
} }
if txs[0].Nonce != pool.state.GetNonce(addr) { if txs[0].nonce != pool.state.GetNonce(addr) {
t.Errorf("addr %v, first tx nonce mismatch: have %d, want %d", addr, txs[0].Nonce, pool.state.GetNonce(addr)) t.Errorf("addr %v, first tx nonce mismatch: have %d, want %d", addr, txs[0].nonce, pool.state.GetNonce(addr))
} }
} }
// Verify that calculated evacuation thresholds are correct // Verify that calculated evacuation thresholds are correct
for addr, txs := range pool.index { for addr, txs := range pool.index {
if !txs[0].evictionExecTip.Eq(txs[0].ExecTipCap) { if !txs[0].evictionExecTip.Eq(txs[0].execTipCap) {
t.Errorf("addr %v, tx %d eviction execution tip mismatch: have %d, want %d", addr, 0, txs[0].evictionExecTip, txs[0].ExecTipCap) t.Errorf("addr %v, tx %d eviction execution tip mismatch: have %d, want %d", addr, 0, txs[0].evictionExecTip, txs[0].execTipCap)
} }
if math.Abs(txs[0].evictionExecFeeJumps-txs[0].basefeeJumps) > 0.001 { if math.Abs(txs[0].evictionExecFeeJumps-txs[0].basefeeJumps) > 0.001 {
t.Errorf("addr %v, tx %d eviction execution fee jumps mismatch: have %f, want %f", addr, 0, txs[0].evictionExecFeeJumps, txs[0].basefeeJumps) t.Errorf("addr %v, tx %d eviction execution fee jumps mismatch: have %f, want %f", addr, 0, txs[0].evictionExecFeeJumps, txs[0].basefeeJumps)
@ -349,8 +349,8 @@ func verifyPoolInternals(t *testing.T, pool *BlobPool) {
} }
for i := 1; i < len(txs); i++ { for i := 1; i < len(txs); i++ {
wantExecTip := txs[i-1].evictionExecTip wantExecTip := txs[i-1].evictionExecTip
if wantExecTip.Gt(txs[i].ExecTipCap) { if wantExecTip.Gt(txs[i].execTipCap) {
wantExecTip = txs[i].ExecTipCap wantExecTip = txs[i].execTipCap
} }
if !txs[i].evictionExecTip.Eq(wantExecTip) { if !txs[i].evictionExecTip.Eq(wantExecTip) {
t.Errorf("addr %v, tx %d eviction execution tip mismatch: have %d, want %d", addr, i, txs[i].evictionExecTip, wantExecTip) t.Errorf("addr %v, tx %d eviction execution tip mismatch: have %d, want %d", addr, i, txs[i].evictionExecTip, wantExecTip)
@ -377,7 +377,7 @@ func verifyPoolInternals(t *testing.T, pool *BlobPool) {
for addr, txs := range pool.index { for addr, txs := range pool.index {
spent := new(uint256.Int) spent := new(uint256.Int)
for _, tx := range txs { for _, tx := range txs {
spent.Add(spent, tx.CostCap) spent.Add(spent, tx.costCap)
} }
if !pool.spent[addr].Eq(spent) { if !pool.spent[addr].Eq(spent) {
t.Errorf("addr %v expenditure mismatch: have %d, want %d", addr, pool.spent[addr], spent) t.Errorf("addr %v expenditure mismatch: have %d, want %d", addr, pool.spent[addr], spent)
@ -387,7 +387,7 @@ func verifyPoolInternals(t *testing.T, pool *BlobPool) {
var stored uint64 var stored uint64
for _, txs := range pool.index { for _, txs := range pool.index {
for _, tx := range txs { for _, tx := range txs {
stored += uint64(tx.StorageSize) stored += uint64(tx.storageSize)
} }
} }
if pool.stored != stored { if pool.stored != stored {
@ -410,7 +410,7 @@ func verifyBlobRetrievals(t *testing.T, pool *BlobPool) {
) )
for _, txs := range pool.index { for _, txs := range pool.index {
for _, tx := range txs { for _, tx := range txs {
for _, vhash := range tx.VHashes { for _, vhash := range tx.vhashes {
known[vhash] = struct{}{} known[vhash] = struct{}{}
} }
hashes = append(hashes, tx.vhashes...) hashes = append(hashes, tx.vhashes...)
@ -721,36 +721,36 @@ func TestOpenDrops(t *testing.T) {
alive := make(map[uint64]struct{}) alive := make(map[uint64]struct{})
for _, txs := range pool.index { for _, txs := range pool.index {
for _, tx := range txs { for _, tx := range txs {
switch tx.Id { switch tx.id {
case malformed: case malformed:
t.Errorf("malformed RLP transaction remained in storage") t.Errorf("malformed RLP transaction remained in storage")
case badsig: case badsig:
t.Errorf("invalidly signed transaction remained in storage") t.Errorf("invalidly signed transaction remained in storage")
default: default:
if _, ok := dangling[tx.Id]; ok { if _, ok := dangling[tx.id]; ok {
t.Errorf("dangling transaction remained in storage: %d", tx.Id) t.Errorf("dangling transaction remained in storage: %d", tx.id)
} else if _, ok := filled[tx.Id]; ok { } else if _, ok := filled[tx.id]; ok {
t.Errorf("filled transaction remained in storage: %d", tx.Id) t.Errorf("filled transaction remained in storage: %d", tx.id)
} else if _, ok := overlapped[tx.Id]; ok { } else if _, ok := overlapped[tx.id]; ok {
t.Errorf("overlapped transaction remained in storage: %d", tx.Id) t.Errorf("overlapped transaction remained in storage: %d", tx.id)
} else if _, ok := gapped[tx.Id]; ok { } else if _, ok := gapped[tx.id]; ok {
t.Errorf("gapped transaction remained in storage: %d", tx.Id) t.Errorf("gapped transaction remained in storage: %d", tx.id)
} else if _, ok := underpaid[tx.Id]; ok { } else if _, ok := underpaid[tx.id]; ok {
t.Errorf("underpaid transaction remained in storage: %d", tx.Id) t.Errorf("underpaid transaction remained in storage: %d", tx.id)
} else if _, ok := outpriced[tx.Id]; ok { } else if _, ok := outpriced[tx.id]; ok {
t.Errorf("outpriced transaction remained in storage: %d", tx.Id) t.Errorf("outpriced transaction remained in storage: %d", tx.id)
} else if _, ok := exceeded[tx.Id]; ok { } else if _, ok := exceeded[tx.id]; ok {
t.Errorf("fully overdrafted transaction remained in storage: %d", tx.Id) t.Errorf("fully overdrafted transaction remained in storage: %d", tx.id)
} else if _, ok := overdrafted[tx.Id]; ok { } else if _, ok := overdrafted[tx.id]; ok {
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 { } else if _, ok := duplicated[tx.id]; ok {
t.Errorf("duplicated transaction remained in storage: %d", tx.Id) t.Errorf("duplicated transaction remained in storage: %d", tx.id)
} else if _, ok := repeated[tx.Id]; ok { } else if _, ok := repeated[tx.id]; ok {
t.Errorf("repeated Nonce transaction remained in storage: %d", tx.Id) t.Errorf("repeated nonce transaction remained in storage: %d", tx.id)
} else { } else {
alive[tx.Id] = struct{}{} alive[tx.id] = struct{}{}
} }
} }
} }
@ -836,8 +836,8 @@ func TestOpenIndex(t *testing.T) {
// Verify that the transactions have been sorted by nonce (case 1) // Verify that the transactions have been sorted by nonce (case 1)
for i := 0; i < len(pool.index[addr]); i++ { for i := 0; i < len(pool.index[addr]); i++ {
if pool.index[addr][i].Nonce != uint64(i) { if pool.index[addr][i].nonce != uint64(i) {
t.Errorf("tx %d nonce mismatch: have %d, want %d", i, pool.index[addr][i].Nonce, uint64(i)) t.Errorf("tx %d nonce mismatch: have %d, want %d", i, pool.index[addr][i].nonce, uint64(i))
} }
} }
// Verify that the cumulative fee minimums have been correctly calculated (case 2) // Verify that the cumulative fee minimums have been correctly calculated (case 2)

View file

@ -145,12 +145,12 @@ func TestPriceHeapSorting(t *testing.T) {
blobfeeJumps = dynamicFeeJumps(blobFee) blobfeeJumps = dynamicFeeJumps(blobFee)
) )
index[addr] = []*blobTxMeta{{ index[addr] = []*blobTxMeta{{
Id: uint64(j), id: uint64(j),
StorageSize: 128 * 1024, storageSize: 128 * 1024,
Nonce: 0, nonce: 0,
ExecTipCap: execTip, execTipCap: execTip,
ExecFeeCap: execFee, execFeeCap: execFee,
BlobFeeCap: blobFee, blobFeeCap: blobFee,
basefeeJumps: basefeeJumps, basefeeJumps: basefeeJumps,
blobfeeJumps: blobfeeJumps, blobfeeJumps: blobfeeJumps,
evictionExecTip: execTip, evictionExecTip: execTip,
@ -204,12 +204,12 @@ func benchmarkPriceHeapReinit(b *testing.B, datacap uint64) {
blobfeeJumps = dynamicFeeJumps(blobFee) blobfeeJumps = dynamicFeeJumps(blobFee)
) )
index[addr] = []*blobTxMeta{{ index[addr] = []*blobTxMeta{{
Id: uint64(i), id: uint64(i),
StorageSize: 128 * 1024, storageSize: 128 * 1024,
Nonce: 0, nonce: 0,
ExecTipCap: execTip, execTipCap: execTip,
ExecFeeCap: execFee, execFeeCap: execFee,
BlobFeeCap: blobFee, blobFeeCap: blobFee,
basefeeJumps: basefeeJumps, basefeeJumps: basefeeJumps,
blobfeeJumps: blobfeeJumps, blobfeeJumps: blobfeeJumps,
evictionExecTip: execTip, evictionExecTip: execTip,
@ -280,12 +280,12 @@ func benchmarkPriceHeapOverflow(b *testing.B, datacap uint64) {
blobfeeJumps = dynamicFeeJumps(blobFee) blobfeeJumps = dynamicFeeJumps(blobFee)
) )
index[addr] = []*blobTxMeta{{ index[addr] = []*blobTxMeta{{
Id: uint64(i), id: uint64(i),
StorageSize: 128 * 1024, storageSize: 128 * 1024,
Nonce: 0, nonce: 0,
ExecTipCap: execTip, execTipCap: execTip,
ExecFeeCap: execFee, execFeeCap: execFee,
BlobFeeCap: blobFee, blobFeeCap: blobFee,
basefeeJumps: basefeeJumps, basefeeJumps: basefeeJumps,
blobfeeJumps: blobfeeJumps, blobfeeJumps: blobfeeJumps,
evictionExecTip: execTip, evictionExecTip: execTip,
@ -311,12 +311,12 @@ func benchmarkPriceHeapOverflow(b *testing.B, datacap uint64) {
blobfeeJumps = dynamicFeeJumps(blobFee) blobfeeJumps = dynamicFeeJumps(blobFee)
) )
metas[i] = &blobTxMeta{ metas[i] = &blobTxMeta{
Id: uint64(int(blobs) + i), id: uint64(int(blobs) + i),
StorageSize: 128 * 1024, storageSize: 128 * 1024,
Nonce: 0, nonce: 0,
ExecTipCap: execTip, execTipCap: execTip,
ExecFeeCap: execFee, execFeeCap: execFee,
BlobFeeCap: blobFee, blobFeeCap: blobFee,
basefeeJumps: basefeeJumps, basefeeJumps: basefeeJumps,
blobfeeJumps: blobfeeJumps, blobfeeJumps: blobfeeJumps,
evictionExecTip: execTip, evictionExecTip: execTip,

View file

@ -91,7 +91,7 @@ func (l *limbo) parseBlob(id uint64, data []byte) error {
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
} }
txHash := item.BlobTxMeta.TxHash txHash := item.BlobTxMeta.hash
if _, ok := l.index[txHash]; ok { if _, ok := l.index[txHash]; ok {
// This path is impossible, unless due to a programming error a blob gets // This path is impossible, unless due to a programming error a blob gets
// inserted into the limbo which was already part of if. Recover gracefully // inserted into the limbo which was already part of if. Recover gracefully
@ -121,10 +121,10 @@ func (l *limbo) finalize(final *types.Header, fn func(id uint64, txHash common.H
if err := l.store.Delete(id); err != nil { if err := l.store.Delete(id); err != nil {
log.Error("Failed to drop finalized blob", "block", item.Block, "id", id, "err", err) log.Error("Failed to drop finalized blob", "block", item.Block, "id", id, "err", err)
} }
delete(l.index, item.BlobTxMeta.TxHash) delete(l.index, item.BlobTxMeta.hash)
delete(l.limbos, id) delete(l.limbos, id)
if fn != nil { // Delete blob tx if fn is not null. if fn != nil { // Delete blob tx if fn is not null.
fn(item.BlobTxMeta.Id, item.BlobTxMeta.TxHash) fn(item.BlobTxMeta.id, item.BlobTxMeta.hash)
} }
} }
} }
@ -134,12 +134,12 @@ func (l *limbo) finalize(final *types.Header, fn func(id uint64, txHash common.H
func (l *limbo) push(metaData *blobTxMeta, block uint64) error { func (l *limbo) push(metaData *blobTxMeta, block uint64) error {
// If the blobs are already tracked by the limbo, consider it a programming // If the blobs are already tracked by the limbo, consider it a programming
// error. There's not much to do against it, but be loud. // error. There's not much to do against it, but be loud.
if _, ok := l.index[metaData.TxHash]; ok { if _, ok := l.index[metaData.hash]; ok {
log.Error("Limbo cannot push already tracked blobs", "tx", metaData.TxHash) log.Error("Limbo cannot push already tracked blobs", "tx", metaData.hash)
return errors.New("already tracked blob transaction") return errors.New("already tracked blob transaction")
} }
if err := l.setAndIndex(metaData, block); err != nil { if err := l.setAndIndex(metaData, block); err != nil {
log.Error("Failed to set and index limboed blobs", "tx", metaData.TxHash, "err", err) log.Error("Failed to set and index limboed blobs", "tx", metaData.hash, "err", err)
return err return err
} }
return nil return nil
@ -163,8 +163,8 @@ func (l *limbo) pull(tx common.Hash) (*blobTxMeta, error) {
return nil, err return nil, err
} }
meta := item.BlobTxMeta meta := item.BlobTxMeta
meta.basefeeJumps = dynamicFeeJumps(meta.ExecFeeCap) meta.basefeeJumps = dynamicFeeJumps(meta.execFeeCap)
meta.blobfeeJumps = dynamicFeeJumps(meta.BlobFeeCap) meta.blobfeeJumps = dynamicFeeJumps(meta.blobFeeCap)
return meta, nil return meta, nil
} }
@ -208,7 +208,7 @@ func (l *limbo) update(txhash common.Hash, block uint64) {
// the store and indices. // the store and indices.
func (l *limbo) getAndDrop(id uint64) (*limboBlob, error) { func (l *limbo) getAndDrop(id uint64) (*limboBlob, error) {
item := l.limbos[id] item := l.limbos[id]
delete(l.index, item.BlobTxMeta.TxHash) delete(l.index, item.BlobTxMeta.hash)
delete(l.limbos, id) delete(l.limbos, id)
if err := l.store.Delete(id); err != nil { if err := l.store.Delete(id); err != nil {
return nil, err return nil, err
@ -231,7 +231,7 @@ func (l *limbo) setAndIndex(metaData *blobTxMeta, block uint64) error {
if err != nil { if err != nil {
return err return err
} }
l.index[item.BlobTxMeta.TxHash] = id l.index[item.BlobTxMeta.hash] = id
l.limbos[id] = item l.limbos[id] = item
return nil return nil
} }

View file

@ -83,16 +83,16 @@ func (l *lookup) sizeOfTx(txhash common.Hash) (uint64, bool) {
// hashes; and from transaction hashes to datastore storage item ids. // hashes; and from transaction hashes to datastore storage item ids.
func (l *lookup) track(tx *blobTxMeta) { func (l *lookup) track(tx *blobTxMeta) {
// Map all the blobs to the transaction hash // Map all the blobs to the transaction hash
for _, vhash := range tx.VHashes { for _, vhash := range tx.vhashes {
if _, ok := l.blobIndex[vhash]; !ok { if _, ok := l.blobIndex[vhash]; !ok {
l.blobIndex[vhash] = make(map[common.Hash]struct{}) l.blobIndex[vhash] = make(map[common.Hash]struct{})
} }
l.blobIndex[vhash][tx.TxHash] = struct{}{} // may be double mapped if a tx contains the same blob twice l.blobIndex[vhash][tx.hash] = struct{}{} // may be double mapped if a tx contains the same blob twice
} }
// Map the transaction hash to the datastore id and RLP-encoded transaction size // Map the transaction hash to the datastore id and RLP-encoded transaction size
l.txIndex[tx.TxHash] = &txMetadata{ l.txIndex[tx.hash] = &txMetadata{
id: tx.Id, id: tx.id,
size: tx.Size, size: tx.size,
} }
} }
@ -100,11 +100,11 @@ func (l *lookup) track(tx *blobTxMeta) {
// hashes from the blob index. // hashes from the blob index.
func (l *lookup) untrack(tx *blobTxMeta) { func (l *lookup) untrack(tx *blobTxMeta) {
// Unmap the transaction hash from the datastore id // Unmap the transaction hash from the datastore id
delete(l.txIndex, tx.TxHash) delete(l.txIndex, tx.hash)
// Unmap all the blobs from the transaction hash // Unmap all the blobs from the transaction hash
for _, vhash := range tx.VHashes { for _, vhash := range tx.vhashes {
delete(l.blobIndex[vhash], tx.TxHash) // may be double deleted if a tx contains the same blob twice delete(l.blobIndex[vhash], tx.hash) // may be double deleted if a tx contains the same blob twice
if len(l.blobIndex[vhash]) == 0 { if len(l.blobIndex[vhash]) == 0 {
delete(l.blobIndex, vhash) delete(l.blobIndex, vhash)
} }