@@ -31,6 +31,7 @@ import (
3131 "time"
3232
3333 "github.com/ethereum/go-ethereum/common"
34+ "github.com/ethereum/go-ethereum/common/lru"
3435 "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
3536 "github.com/ethereum/go-ethereum/consensus/misc/eip4844"
3637 "github.com/ethereum/go-ethereum/core"
@@ -83,6 +84,11 @@ const (
8384 // so pushing it down too aggressively might make resurrections non-functional.
8485 maxTxsPerAccount = 16
8586
87+ // getRLPCacheSize is the byte budget of the cache of encoded
88+ // GetPooledTransactions responses. It bounds the memory spent on serving
89+ // the same blob transactions to multiple (legacy) peers.
90+ getRLPCacheSize = 16 * 1024 * 1024
91+
8692 // pendingTransactionStore is the subfolder containing the currently queued
8793 // blob transactions.
8894 pendingTransactionStore = "queue"
@@ -575,9 +581,22 @@ type BlobPool struct {
575581 discoverFeed event.Feed // Event feed to send out new tx events on pool discovery (reorg excluded)
576582 insertFeed event.Feed // Event feed to send out new tx events on pool inclusion (reorg included)
577583
584+ // rlpCache memoizes encoded GetPooledTransactions responses, keyed by
585+ // (tx hash, whether full blobs are needed). It is content-addressed: a
586+ // pooled tx's encoding is stable, so a cached entry is valid as long as the
587+ // tx is still in the pool (checked on lookup before serving a hit).
588+ rlpCache * lru.SizeConstrainedCache [rlpCacheKey , []byte ]
589+
578590 lock sync.RWMutex // Mutex protecting the pool during reorg handling
579591}
580592
593+ // rlpCacheKey keys the encoded-response cache. full is true for pre eth/72
594+ // requests (which carry full blobs) and false for eth/72+ (blob payload elided).
595+ type rlpCacheKey struct {
596+ hash common.Hash
597+ full bool
598+ }
599+
581600// New creates a new blob transaction pool to gather, sort and filter inbound
582601// blob transactions from the network.
583602func New (config Config , chain BlockChain , hasPendingAuth func (common.Address ) bool ) * BlobPool {
@@ -595,6 +614,7 @@ func New(config Config, chain BlockChain, hasPendingAuth func(common.Address) bo
595614 spent : make (map [common.Address ]* uint256.Int ),
596615 gapped : make (map [common.Address ][]* BlobTxForPool ),
597616 gappedSource : make (map [common.Hash ]common.Address ),
617+ rlpCache : lru.NewSizeConstrainedCache [rlpCacheKey , []byte ](getRLPCacheSize ),
598618 }
599619}
600620
@@ -1753,17 +1773,39 @@ func (p *BlobPool) Get(hash common.Hash) *types.Transaction {
17531773}
17541774
17551775// GetRLP returns an RLP-encoded transaction if it is contained in the pool.
1776+ //
1777+ // The encoded response is memoized: legacy (pre eth/72) peers fetch full blobs
1778+ // via GetPooledTransactions, and the same transaction is typically requested
1779+ // by multiple peers. Without the cache, each request re-reads the tx from disk
1780+ // and re-encodes it, recovering the blobs from the stored cells.
17561781func (p * BlobPool ) GetRLP (hash common.Hash , version uint ) []byte {
1782+ key := rlpCacheKey {hash : hash , full : version < 72 }
1783+ if enc , ok := p .rlpCache .Get (key ); ok {
1784+ // The encoding is content-addressed, but only serve it while the tx is
1785+ // still pooled so a hit cannot resurrect a dropped transaction.
1786+ p .lock .RLock ()
1787+ _ , pooled := p .lookup .storeidOfTx (hash )
1788+ p .lock .RUnlock ()
1789+ if pooled {
1790+ getRLPCacheHitMeter .Mark (1 )
1791+ return enc
1792+ }
1793+ }
17571794 data := p .getRLP (hash )
17581795 if len (data ) == 0 {
17591796 // Not in this pool, do not log.
17601797 return nil
17611798 }
1799+ // Count misses only for transactions the pool actually holds, so the
1800+ // hit/miss ratio reflects cache effectiveness rather than unknown-tx
1801+ // requests.
1802+ getRLPCacheMissMeter .Mark (1 )
17621803 rlp , err := encodeForNetwork (data , version )
17631804 if err != nil {
17641805 log .Error ("Failed to encode pooled tx into the network type" , "hash" , hash , "err" , err )
17651806 return nil
17661807 }
1808+ p .rlpCache .Add (key , rlp )
17671809 return rlp
17681810}
17691811
0 commit comments