diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 5cf1218b7590..722c176bb1c2 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -92,6 +92,7 @@ const ( type blobTxMeta struct { hash common.Hash // Transaction hash to maintain the lookup table vhashes []common.Hash // Blob versioned hashes to maintain the lookup table + version byte // Blob transaction version to determine proof type id uint64 // Storage ID in the pool's persistent store storageSize uint32 // Byte size in the pool's persistent store @@ -115,10 +116,16 @@ type blobTxMeta struct { // newBlobTxMeta retrieves the indexed metadata fields from a blob transaction // and assembles a helper struct to track in memory. +// Requires the transaction to have a sidecar (or that we introduce a special version tag for no-sidecar). func newBlobTxMeta(id uint64, size uint64, storageSize uint32, tx *types.Transaction) *blobTxMeta { + if tx.BlobTxSidecar() == nil { + // This should never happen, as the pool only admits blob transactions with a sidecar + panic("missing blob tx sidecar") + } meta := &blobTxMeta{ hash: tx.Hash(), vhashes: tx.BlobHashes(), + version: tx.BlobTxSidecar().Version, id: id, storageSize: storageSize, size: size, @@ -1660,7 +1667,7 @@ func (p *BlobPool) drop() { func (p *BlobPool) Pending(filter txpool.PendingFilter) map[common.Address][]*txpool.LazyTransaction { // If only plain transactions are requested, this pool is unsuitable as it // contains none, don't even bother. - if filter.OnlyPlainTxs { + if !filter.BlobTxs { return nil } // Track the amount of time waiting to retrieve the list of pending blob txs @@ -1681,6 +1688,11 @@ func (p *BlobPool) Pending(filter txpool.PendingFilter) map[common.Address][]*tx for addr, txs := range p.index { lazies := make([]*txpool.LazyTransaction, 0, len(txs)) for _, tx := range txs { + // Skip v0 or v1 blob transactions depending on the filter + if tx.version != filter.BlobVersion { + break // skip the rest because of nonce ordering + } + // If transaction filtering was requested, discard badly priced ones if filter.MinTip != nil && filter.BaseFee != nil { if tx.execFeeCap.Lt(filter.BaseFee) { diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 425def170b49..80a9faf23f63 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -508,7 +508,7 @@ func (pool *LegacyPool) ContentFrom(addr common.Address) ([]*types.Transaction, func (pool *LegacyPool) Pending(filter txpool.PendingFilter) map[common.Address][]*txpool.LazyTransaction { // If only blob transactions are requested, this pool is unsuitable as it // contains none, don't even bother. - if filter.OnlyBlobTxs { + if filter.BlobTxs { return nil } pool.mu.Lock() diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go index f1f605668697..519ae7b989f5 100644 --- a/core/txpool/subpool.go +++ b/core/txpool/subpool.go @@ -78,8 +78,10 @@ type PendingFilter struct { BlobFee *uint256.Int // Minimum 4844 blobfee needed to include a blob transaction GasLimitCap uint64 // Maximum gas can be used for a single transaction execution (0 means no limit) - OnlyPlainTxs bool // Return only plain EVM transactions (peer-join announces, block space filling) - OnlyBlobTxs bool // Return only blob transactions (block blob-space filling) + // When BlobTxs true, return only blob transactions (block blob-space filling) + // when false, return only non-blob txs (peer-join announces, block space filling) + BlobTxs bool + BlobVersion byte // Blob tx version to include. 0 means pre-Osaka, 1 means Osaka and later } // TxMetadata denotes the metadata of a transaction. diff --git a/eth/sync.go b/eth/sync.go index 61f2b2b376cd..ddae8443a321 100644 --- a/eth/sync.go +++ b/eth/sync.go @@ -25,7 +25,7 @@ import ( // syncTransactions starts sending all currently pending transactions to the given peer. func (h *handler) syncTransactions(p *eth.Peer) { var hashes []common.Hash - for _, batch := range h.txpool.Pending(txpool.PendingFilter{OnlyPlainTxs: true}) { + for _, batch := range h.txpool.Pending(txpool.PendingFilter{BlobTxs: false}) { for _, tx := range batch { hashes = append(hashes, tx.Hash) } diff --git a/miner/worker.go b/miner/worker.go index 6baec5e36515..c0574eac2380 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -481,10 +481,15 @@ func (miner *Miner) fillTransactions(interrupt *atomic.Int32, env *environment) if miner.chainConfig.IsOsaka(env.header.Number, env.header.Time) { filter.GasLimitCap = params.MaxTxGas } - filter.OnlyPlainTxs, filter.OnlyBlobTxs = true, false + filter.BlobTxs = false pendingPlainTxs := miner.txpool.Pending(filter) - filter.OnlyPlainTxs, filter.OnlyBlobTxs = false, true + filter.BlobTxs = true + if miner.chainConfig.IsOsaka(env.header.Number, env.header.Time) { + filter.BlobVersion = types.BlobSidecarVersion1 + } else { + filter.BlobVersion = types.BlobSidecarVersion0 + } pendingBlobTxs := miner.txpool.Pending(filter) // Split the pending transactions into locals and remotes.