mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 08:49:29 +00:00
work around billy slotter interface limitations
This commit is contained in:
parent
4daf354b2c
commit
f8a0b6fa1c
2 changed files with 53 additions and 20 deletions
|
|
@ -346,10 +346,10 @@ type BlobPool struct {
|
|||
reserver txpool.Reserver // Address reserver to ensure exclusivity across subpools
|
||||
hasPendingAuth func(common.Address) bool // Determine whether the specified address has a pending 7702-auth
|
||||
|
||||
store billy.Database // Persistent data store for the tx metadata and blobs
|
||||
newSlotter func() billy.SlotSizeFn // Factory to create fresh slotter instances for slot size lookups
|
||||
stored uint64 // Useful data size of all transactions on disk
|
||||
limbo *limbo // Persistent data store for the non-finalized blobs
|
||||
store billy.Database // Persistent data store for the tx metadata and blobs
|
||||
slotter slotSizer // O(1) slot size calculator matching the active billy shelves
|
||||
stored uint64 // Useful data size of all transactions on disk
|
||||
limbo *limbo // Persistent data store for the non-finalized blobs
|
||||
|
||||
gapped map[common.Address][]*types.Transaction // Transactions that are currently gapped (nonce too high)
|
||||
gappedSource map[common.Hash]common.Address // Source of gapped transactions to allow rechecking on inclusion
|
||||
|
|
@ -437,16 +437,19 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserver txpool.Reser
|
|||
|
||||
// Create new slotter for pre-Osaka blob configuration.
|
||||
slotter := newSlotter(params.BlobTxMaxBlobs)
|
||||
p.newSlotter = func() billy.SlotSizeFn { return newSlotter(params.BlobTxMaxBlobs) }
|
||||
|
||||
// See if we need to migrate the queue blob store after fusaka
|
||||
slotter, err = tryMigrate(p.chain.Config(), slotter, queuedir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Update the slotter factory if Osaka is active
|
||||
// Build an O(1) slot size calculator from the active slotter configuration.
|
||||
// We need a fresh slotter instance since tryMigrate may have consumed the
|
||||
// previous one, and billy.Open below will consume this one.
|
||||
if p.chain.Config().OsakaTime != nil {
|
||||
p.newSlotter = func() billy.SlotSizeFn { return newSlotterEIP7594(params.BlobTxMaxBlobs) }
|
||||
p.slotter = newSlotSizer(newSlotterEIP7594(params.BlobTxMaxBlobs))
|
||||
} else {
|
||||
p.slotter = newSlotSizer(newSlotter(params.BlobTxMaxBlobs))
|
||||
}
|
||||
// Index all transactions on disk and delete anything unprocessable
|
||||
var fails []uint64
|
||||
|
|
@ -1593,7 +1596,7 @@ func (p *BlobPool) addLocked(tx *types.Transaction, checkGapped bool) (err error
|
|||
|
||||
// Create meta, in preparation of adding to the pool.
|
||||
// Having the meta simplifies the check below for underpriced transactions.
|
||||
// Note: the meta will be finalized with storage information after the transaction is stored
|
||||
// Note: the meta will be finalized with storage information after the transaction is stored.
|
||||
meta := newBlobTxMeta(tx)
|
||||
|
||||
// Calculate the eviction parameters for the transaction
|
||||
|
|
@ -1627,9 +1630,9 @@ func (p *BlobPool) addLocked(tx *types.Transaction, checkGapped bool) (err error
|
|||
log.Error("Failed to encode transaction for storage", "hash", tx.Hash(), "err", err)
|
||||
return err
|
||||
}
|
||||
newStorageSize, err := getSlotSize(p.newSlotter(), uint32(len(blob)))
|
||||
newStorageSize, err := p.slotter.getSlotSize(uint32(len(blob)))
|
||||
if err != nil {
|
||||
// This should also not happen at this stage
|
||||
// This should never happen, but better safe than sorry.
|
||||
log.Warn("Dropping blob transaction due to size", "tx", tx.Hash(), "size", meta.size, "err", err)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,17 +23,47 @@ import (
|
|||
"github.com/holiman/billy"
|
||||
)
|
||||
|
||||
// getSlotSize return the storage size for a given transaction size based on the current slotter.
|
||||
func getSlotSize(slotter billy.SlotSizeFn, size uint32) (uint32, error) {
|
||||
for {
|
||||
slotSize, done := slotter()
|
||||
if size <= slotSize {
|
||||
return slotSize, nil
|
||||
}
|
||||
if done {
|
||||
return size, errors.New("size exceeds maximum slot size")
|
||||
}
|
||||
// slotSizer computes the storage shelf size for a given transaction size using
|
||||
// O(1) arithmetic. Shelf sizes form an arithmetic sequence:
|
||||
//
|
||||
// base, base+step, base+2*step, ...
|
||||
//
|
||||
// This mirrors the progression in newSlotter and newSlotterEIP7594, but avoids
|
||||
// creating and iterating a stateful closure on every lookup.
|
||||
type slotSizer struct {
|
||||
base uint32 // Size of the first shelf (txAvgSize)
|
||||
step uint32 // Size increment per subsequent shelf
|
||||
max uint32 // Largest valid shelf size
|
||||
}
|
||||
|
||||
// newSlotSizer creates a slotSizer by consuming a slotter closure once to
|
||||
// discover its base size, step size, and maximum shelf size.
|
||||
func newSlotSizer(slotter billy.SlotSizeFn) slotSizer {
|
||||
first, done := slotter()
|
||||
if done {
|
||||
return slotSizer{base: first, step: 0, max: first}
|
||||
}
|
||||
second, done := slotter()
|
||||
step := second - first
|
||||
last := second
|
||||
for !done {
|
||||
last, done = slotter()
|
||||
}
|
||||
return slotSizer{base: first, step: step, max: last}
|
||||
}
|
||||
|
||||
// getSlotSize returns the shelf size that can store a transaction of the given
|
||||
// byte size, or an error if it exceeds the largest shelf.
|
||||
func (s slotSizer) getSlotSize(size uint32) (uint32, error) {
|
||||
if size <= s.base {
|
||||
return s.base, nil
|
||||
}
|
||||
// Round up to the nearest shelf: base + ⌈(size-base)/step⌉ * step
|
||||
slot := s.base + ((size-s.base+s.step-1)/s.step)*s.step
|
||||
if slot > s.max {
|
||||
return 0, errors.New("size exceeds maximum slot size")
|
||||
}
|
||||
return slot, nil
|
||||
}
|
||||
|
||||
// tryMigrate checks if the billy needs to be migrated and migrates if needed.
|
||||
|
|
|
|||
Loading…
Reference in a new issue