diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 685c017cbd..2457e0378f 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -1208,6 +1208,26 @@ func (p *BlobPool) Get(hash common.Hash) *types.Transaction { return item } +// GetBySenderAndNonce returns a transaction of a sender and its corresponding nonce. +func (p *BlobPool) GetBySenderAndNonce(sender common.Address, nonce uint64) *types.Transaction { + p.lock.RLock() + defer p.lock.RUnlock() + + txs, ok := p.index[sender] + if !ok { + return nil + } + + next := p.state.GetNonce(sender) + offset := int(nonce - next) + + if offset < 0 || offset >= len(txs) { + return nil + } + + return p.Get(txs[offset].hash) +} + // Add inserts a set of blob transactions into the pool if they pass validation (both // consensus validity and pool restrictions). func (p *BlobPool) Add(txs []*types.Transaction, local bool, sync bool) []error { diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 5506ecc31f..ec84b47c62 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1072,6 +1072,25 @@ func (pool *LegacyPool) Get(hash common.Hash) *types.Transaction { return tx } +// GetBySenderAndNonce returns a transaction of a sender and it's corresponding nonce. +func (pool *LegacyPool) GetBySenderAndNonce(sender common.Address, nonce uint64) *types.Transaction { + // Check if the transaction is in the pending pool + if txList := pool.pending[sender]; txList != nil { + if tx := txList.txs.items[nonce]; tx != nil { + return tx + } + } + + // Check if the transaction is in the queue pool + if txList := pool.queue[sender]; txList != nil { + if tx := txList.txs.items[nonce]; tx != nil { + return tx + } + } + + return nil +} + // get returns a transaction if it is contained in the pool and nil otherwise. func (pool *LegacyPool) get(hash common.Hash) *types.Transaction { return pool.all.Get(hash) diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go index 9881ed1b8f..c81421c60f 100644 --- a/core/txpool/subpool.go +++ b/core/txpool/subpool.go @@ -123,6 +123,9 @@ type SubPool interface { // Get returns a transaction if it is contained in the pool, or nil otherwise. Get(hash common.Hash) *types.Transaction + // GetBySenderAndNonce returns a transaction of a sender and it's corresponding nonce. + GetBySenderAndNonce(sender common.Address, nonce uint64) *types.Transaction + // Add enqueues a batch of transactions into the pool if they are valid. Due // to the large transaction churn, add may postpone fully integrating the tx // to a later point to batch multiple ones together. diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index be7435247d..98ced2542d 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -305,6 +305,16 @@ func (p *TxPool) Get(hash common.Hash) *types.Transaction { return nil } +// GetBySenderAndNonce returns a transaction of a sender and it's corresponding nonce. +func (p *TxPool) GetBySenderAndNonce(sender common.Address, nonce uint64) *types.Transaction { + for _, subpool := range p.subpools { + if tx := subpool.GetBySenderAndNonce(sender, nonce); tx != nil { + return tx + } + } + return nil +} + // Add enqueues a batch of transactions into the pool if they are valid. Due // to the large transaction churn, add may postpone fully integrating the tx // to a later point to batch multiple ones together.