diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 8aa92f851d..7328eba460 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -1573,7 +1573,16 @@ func (p *BlobPool) getRLP(hash common.Hash) []byte { } // Get returns a transaction if it is contained in the pool, or nil otherwise. -func (p *BlobPool) Get(hash common.Hash) *types.Transaction { +// TODO: We could do the following (especially beneficial for GetRLP): +// 1) Make Get and GetRLP return blob transactions without blobs (not without sidecars). +// 2) Store transactions (without blobs) and cells separately: +// - (1) Store them separately on disk, tracking both IDs. +// - (2) Keep transactions in memory and store cells on disk. +// +// However, this approach does not fit well with eth71 peers, since blobs +// must be included in that case. It may require decoding and re-encoding, +// as well as double disk I/O each time. +func (p *BlobPool) Get(hash common.Hash, includeBlob bool) *types.Transaction { data := p.getRLP(hash) if len(data) == 0 { return nil @@ -1583,6 +1592,9 @@ func (p *BlobPool) Get(hash common.Hash) *types.Transaction { log.Error("Blobs corrupted for traced transaction", "hash", hash, "err", err) return nil } + if !includeBlob { + return pooledTx.Transaction + } tx, err := pooledTx.convert() if err != nil { log.Error("Failed to convert transaction in blobpool", "hash", hash, "err", err) diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 41d1bbe383..98abd96bc4 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -1158,10 +1158,10 @@ func TestChangingSlotterSize(t *testing.T) { } // Verify the regular two txs are always available. - if got := pool.Get(tx1.Hash()); got == nil { + if got := pool.Get(tx1.Hash(), true); got == nil { t.Errorf("expected tx %s from %s in pool", tx1.Hash(), addr1) } - if got := pool.Get(tx2.Hash()); got == nil { + if got := pool.Get(tx2.Hash(), true); got == nil { t.Errorf("expected tx %s from %s in pool", tx2.Hash(), addr2) } @@ -1267,10 +1267,10 @@ func TestBillyMigration(t *testing.T) { } // Verify the regular two txs are always available. - if got := pool.Get(tx1.Hash()); got == nil { + if got := pool.Get(tx1.Hash(), true); got == nil { t.Errorf("expected tx %s from %s in pool", tx1.Hash(), addr1) } - if got := pool.Get(tx2.Hash()); got == nil { + if got := pool.Get(tx2.Hash(), true); got == nil { t.Errorf("expected tx %s from %s in pool", tx2.Hash(), addr2) } @@ -1905,13 +1905,13 @@ func TestGetBlobs(t *testing.T) { } // Verify the regular three txs are always available. - if got := pool.Get(tx1.Hash()); got == nil { + if got := pool.Get(tx1.Hash(), true); got == nil { t.Errorf("expected tx %s from %s in pool", tx1.Hash(), addr1) } - if got := pool.Get(tx2.Hash()); got == nil { + if got := pool.Get(tx2.Hash(), true); got == nil { t.Errorf("expected tx %s from %s in pool", tx2.Hash(), addr2) } - if got := pool.Get(tx3.Hash()); got == nil { + if got := pool.Get(tx3.Hash(), true); got == nil { t.Errorf("expected tx %s from %s in pool", tx3.Hash(), addr3) } diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index dd6c539ec6..7b31dad202 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -997,7 +997,7 @@ func (pool *LegacyPool) Status(hash common.Hash) txpool.TxStatus { } // Get returns a transaction if it is contained in the pool and nil otherwise. -func (pool *LegacyPool) Get(hash common.Hash) *types.Transaction { +func (pool *LegacyPool) Get(hash common.Hash, _ bool) *types.Transaction { tx := pool.get(hash) if tx == nil { return nil diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go index 59d60cb651..5f35f0a44a 100644 --- a/core/txpool/subpool.go +++ b/core/txpool/subpool.go @@ -55,7 +55,7 @@ func (ltx *LazyTransaction) Resolve() *types.Transaction { if ltx.Tx != nil { return ltx.Tx } - return ltx.Pool.Get(ltx.Hash) + return ltx.Pool.Get(ltx.Hash, true) } // LazyResolver is a minimal interface needed for a transaction pool to satisfy @@ -63,7 +63,7 @@ func (ltx *LazyTransaction) Resolve() *types.Transaction { // pool being injected into the lazy transaction. type LazyResolver interface { // Get returns a transaction if it is contained in the pool, or nil otherwise. - Get(hash common.Hash) *types.Transaction + Get(hash common.Hash, includeBlob bool) *types.Transaction } // PendingFilter is a collection of filter rules to allow retrieving a subset @@ -130,7 +130,7 @@ type SubPool interface { Has(hash common.Hash) bool // Get returns a transaction if it is contained in the pool, or nil otherwise. - Get(hash common.Hash) *types.Transaction + Get(hash common.Hash, includeBlob bool) *types.Transaction // GetRLP returns a RLP-encoded transaction if it is contained in the pool. // If includeBlob is false, blob data is stripped from blob transactions (ETH/71). diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index a9075cfd91..5e42dfa0d0 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -274,9 +274,9 @@ func (p *TxPool) Has(hash common.Hash) bool { } // Get returns a transaction if it is contained in the pool, or nil otherwise. -func (p *TxPool) Get(hash common.Hash) *types.Transaction { +func (p *TxPool) Get(hash common.Hash, includeBlob bool) *types.Transaction { for _, subpool := range p.subpools { - if tx := subpool.Get(hash); tx != nil { + if tx := subpool.Get(hash, includeBlob); tx != nil { return tx } } diff --git a/eth/api_backend.go b/eth/api_backend.go index 726d8316a0..1630fc9f6c 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -360,7 +360,7 @@ func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) { } func (b *EthAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction { - return b.eth.txPool.Get(hash) + return b.eth.txPool.Get(hash, true) } // GetCanonicalTransaction retrieves the lookup along with the transaction itself diff --git a/eth/handler.go b/eth/handler.go index 4ece05d013..c584e7a78b 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -72,7 +72,7 @@ type txPool interface { // Get retrieves the transaction from local txpool with given // tx hash. - Get(hash common.Hash) *types.Transaction + Get(hash common.Hash, includeBlob bool) *types.Transaction // GetRLP retrieves the RLP-encoded transaction from local txpool // with given tx hash. diff --git a/eth/handler_test.go b/eth/handler_test.go index 384acffb61..0bb994cb13 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -94,7 +94,7 @@ func (p *testTxPool) HasPayload(hash common.Hash) bool { // Get retrieves the transaction from local txpool with given // tx hash. -func (p *testTxPool) Get(hash common.Hash) *types.Transaction { +func (p *testTxPool) Get(hash common.Hash, includeBlob bool) *types.Transaction { p.lock.Lock() defer p.lock.Unlock() return p.txPool[hash] diff --git a/eth/protocols/eth/broadcast.go b/eth/protocols/eth/broadcast.go index 0ecee5d2ba..a1fa419f40 100644 --- a/eth/protocols/eth/broadcast.go +++ b/eth/protocols/eth/broadcast.go @@ -47,7 +47,7 @@ func (p *Peer) broadcastTransactions() { size common.StorageSize ) for i := 0; i < len(queue) && size < maxTxPacketSize; i++ { - if tx := p.txpool.Get(queue[i]); tx != nil { + if tx := p.txpool.Get(queue[i], false); tx != nil { txs = append(txs, tx) size += common.StorageSize(tx.Size()) } diff --git a/eth/protocols/eth/handler.go b/eth/protocols/eth/handler.go index f5f4cfb34c..41a58abc08 100644 --- a/eth/protocols/eth/handler.go +++ b/eth/protocols/eth/handler.go @@ -100,7 +100,7 @@ type BlobPool interface { // TxPool defines the methods needed by the protocol handler to serve transactions. type TxPool interface { // Get retrieves the transaction from the local txpool with the given hash. - Get(hash common.Hash) *types.Transaction + Get(hash common.Hash, includeBlob bool) *types.Transaction // GetRLP retrieves the RLP-encoded transaction from the local txpool with // the given hash.