@@ -29,6 +29,9 @@ import (
2929 "sync"
3030 "time"
3131
32+ "github.com/holiman/billy"
33+ "github.com/holiman/uint256"
34+
3235 "github.com/ethereum/go-ethereum/common"
3336 "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
3437 "github.com/ethereum/go-ethereum/consensus/misc/eip4844"
@@ -41,8 +44,6 @@ import (
4144 "github.com/ethereum/go-ethereum/metrics"
4245 "github.com/ethereum/go-ethereum/params"
4346 "github.com/ethereum/go-ethereum/rlp"
44- "github.com/holiman/billy"
45- "github.com/holiman/uint256"
4647)
4748
4849const (
@@ -97,6 +98,8 @@ type blobTxMeta struct {
9798 execTipCap * uint256.Int // Needed to prioritize inclusion order across accounts and validate replacement price bump
9899 execFeeCap * uint256.Int // Needed to validate replacement price bump
99100 blobFeeCap * uint256.Int // Needed to validate replacement price bump
101+ execGas uint64 // Needed to check inclusion validity before reading the blob
102+ blobGas uint64 // Needed to check inclusion validity before reading the blob
100103
101104 basefeeJumps float64 // Absolute number of 1559 fee adjustments needed to reach the tx's fee cap
102105 blobfeeJumps float64 // Absolute number of 4844 fee adjustments needed to reach the tx's blob fee cap
@@ -118,6 +121,8 @@ func newBlobTxMeta(id uint64, size uint32, tx *types.Transaction) *blobTxMeta {
118121 execTipCap : uint256 .MustFromBig (tx .GasTipCap ()),
119122 execFeeCap : uint256 .MustFromBig (tx .GasFeeCap ()),
120123 blobFeeCap : uint256 .MustFromBig (tx .BlobGasFeeCap ()),
124+ execGas : tx .Gas (),
125+ blobGas : tx .BlobGas (),
121126 }
122127 meta .basefeeJumps = dynamicFeeJumps (meta .execFeeCap )
123128 meta .blobfeeJumps = dynamicFeeJumps (meta .blobFeeCap )
@@ -307,10 +312,12 @@ type BlobPool struct {
307312 spent map [common.Address ]* uint256.Int // Expenditure tracking for individual accounts
308313 evict * evictHeap // Heap of cheapest accounts for eviction when full
309314
310- eventFeed event.Feed // Event feed to send out new tx events on pool inclusion
315+ eventFeed event.Feed // Event feed to send out new tx events on pool inclusion
311316 dropTxFeed event.Feed
312317 rejectTxFeed event.Feed
313- eventScope event.SubscriptionScope // Event scope to track and mass unsubscribe on termination
318+ eventScope event.SubscriptionScope // Event scope to track and mass unsubscribe on termination
319+ discoverFeed event.Feed // Event feed to send out new tx events on pool discovery (reorg excluded)
320+ insertFeed event.Feed // Event feed to send out new tx events on pool inclusion (reorg included)
314321
315322 lock sync.RWMutex // Mutex protecting the pool during reorg handling
316323}
@@ -438,8 +445,6 @@ func (p *BlobPool) Close() error {
438445 if err := p .store .Close (); err != nil {
439446 errs = append (errs , err )
440447 }
441- p .eventScope .Close ()
442-
443448 switch {
444449 case errs == nil :
445450 return nil
@@ -760,15 +765,21 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
760765 // Run the reorg between the old and new head and figure out which accounts
761766 // need to be rechecked and which transactions need to be readded
762767 if reinject , inclusions := p .reorg (oldHead , newHead ); reinject != nil {
768+ var adds []* types.Transaction
763769 for addr , txs := range reinject {
764770 // Blindly push all the lost transactions back into the pool
765771 for _ , tx := range txs {
766- p .reinject (addr , tx .Hash ())
772+ if err := p .reinject (addr , tx .Hash ()); err == nil {
773+ adds = append (adds , tx .WithoutBlobTxSidecar ())
774+ }
767775 }
768776 // Recheck the account's pooled transactions to drop included and
769777 // invalidated one
770778 p .recheck (addr , inclusions )
771779 }
780+ if len (adds ) > 0 {
781+ p .insertFeed .Send (core.NewTxsEvent {Txs : adds })
782+ }
772783 }
773784 // Flush out any blobs from limbo that are older than the latest finality
774785 if p .chain .Config ().IsCancun (p .head .Number , p .head .Time ) {
@@ -923,13 +934,13 @@ func (p *BlobPool) reorg(oldHead, newHead *types.Header) (map[common.Address][]*
923934// Note, the method will not initialize the eviction cache values as those will
924935// be done once for all transactions belonging to an account after all individual
925936// transactions are injected back into the pool.
926- func (p * BlobPool ) reinject (addr common.Address , txhash common.Hash ) {
937+ func (p * BlobPool ) reinject (addr common.Address , txhash common.Hash ) error {
927938 // Retrieve the associated blob from the limbo. Without the blobs, we cannot
928939 // add the transaction back into the pool as it is not mineable.
929940 tx , err := p .limbo .pull (txhash )
930941 if err != nil {
931942 log .Error ("Blobs unavailable, dropping reorged tx" , "err" , err )
932- return
943+ return err
933944 }
934945 // TODO: seems like an easy optimization here would be getting the serialized tx
935946 // from limbo instead of re-serializing it here.
@@ -938,20 +949,20 @@ func (p *BlobPool) reinject(addr common.Address, txhash common.Hash) {
938949 blob , err := rlp .EncodeToBytes (tx )
939950 if err != nil {
940951 log .Error ("Failed to encode transaction for storage" , "hash" , tx .Hash (), "err" , err )
941- return
952+ return err
942953 }
943954 id , err := p .store .Put (blob )
944955 if err != nil {
945956 log .Error ("Failed to write transaction into storage" , "hash" , tx .Hash (), "err" , err )
946- return
957+ return err
947958 }
948959
949960 // Update the indixes and metrics
950961 meta := newBlobTxMeta (id , p .store .Size (id ), tx )
951962 if _ , ok := p .index [addr ]; ! ok {
952963 if err := p .reserve (addr , true ); err != nil {
953964 log .Warn ("Failed to reserve account for blob pool" , "tx" , tx .Hash (), "from" , addr , "err" , err )
954- return
965+ return err
955966 }
956967 p .index [addr ] = []* blobTxMeta {meta }
957968 p .spent [addr ] = meta .costCap
@@ -962,6 +973,7 @@ func (p *BlobPool) reinject(addr common.Address, txhash common.Hash) {
962973 }
963974 p .lookup [meta .hash ] = meta .id
964975 p .stored += uint64 (meta .size )
976+ return nil
965977}
966978
967979// SetGasTip implements txpool.SubPool, allowing the blob pool's gas requirements
@@ -1156,9 +1168,19 @@ func (p *BlobPool) Get(hash common.Hash) *types.Transaction {
11561168// Add inserts a set of blob transactions into the pool if they pass validation (both
11571169// consensus validity and pool restictions).
11581170func (p * BlobPool ) Add (txs []* types.Transaction , local bool , sync bool ) []error {
1159- errs := make ([]error , len (txs ))
1171+ var (
1172+ adds = make ([]* types.Transaction , 0 , len (txs ))
1173+ errs = make ([]error , len (txs ))
1174+ )
11601175 for i , tx := range txs {
11611176 errs [i ] = p .add (tx )
1177+ if errs [i ] == nil {
1178+ adds = append (adds , tx .WithoutBlobTxSidecar ())
1179+ }
1180+ }
1181+ if len (adds ) > 0 {
1182+ p .discoverFeed .Send (core.NewTxsEvent {Txs : adds })
1183+ p .insertFeed .Send (core.NewTxsEvent {Txs : adds })
11621184 }
11631185 return errs
11641186}
@@ -1386,6 +1408,8 @@ func (p *BlobPool) Pending(enforceTips bool) map[common.Address][]*txpool.LazyTr
13861408 Time : time .Now (), // TODO(karalabe): Maybe save these and use that?
13871409 GasFeeCap : tx .execFeeCap .ToBig (),
13881410 GasTipCap : tx .execTipCap .ToBig (),
1411+ Gas : tx .execGas ,
1412+ BlobGas : tx .blobGas ,
13891413 })
13901414 }
13911415 if len (lazies ) > 0 {
@@ -1470,10 +1494,14 @@ func (p *BlobPool) updateLimboMetrics() {
14701494 limboSlotusedGauge .Update (int64 (slotused ))
14711495}
14721496
1473- // SubscribeTransactions registers a subscription of NewTxsEvent and
1474- // starts sending event to the given channel.
1475- func (p * BlobPool ) SubscribeTransactions (ch chan <- core.NewTxsEvent ) event.Subscription {
1476- return p .eventScope .Track (p .eventFeed .Subscribe (ch ))
1497+ // SubscribeTransactions registers a subscription for new transaction events,
1498+ // supporting feeding only newly seen or also resurrected transactions.
1499+ func (p * BlobPool ) SubscribeTransactions (ch chan <- core.NewTxsEvent , reorgs bool ) event.Subscription {
1500+ if reorgs {
1501+ return p .insertFeed .Subscribe (ch )
1502+ } else {
1503+ return p .discoverFeed .Subscribe (ch )
1504+ }
14771505}
14781506
14791507// Nonce returns the next nonce of an account, with all transactions executable
@@ -1535,7 +1563,6 @@ func (p *BlobPool) Status(hash common.Hash) txpool.TxStatus {
15351563 return txpool .TxStatusUnknown
15361564}
15371565
1538-
15391566// SubscribeDropTxsEvent registers a subscription of core.DropTxsEvent and
15401567// starts sending event to the given channel.
15411568func (pool * BlobPool ) SubscribeDropTxsEvent (ch chan <- core.DropTxsEvent ) event.Subscription {
0 commit comments