Skip to content

Commit 85dceef

Browse files
txpool: move authorizations to lookup obj (#69)
Co-authored-by: lightclient <lightclient@protonmail.com>
1 parent 84593a1 commit 85dceef

File tree

1 file changed

+50
-65
lines changed

1 file changed

+50
-65
lines changed

core/txpool/legacypool/legacypool.go

Lines changed: 50 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,12 @@ type LegacyPool struct {
210210
currentState *state.StateDB // Current state in the blockchain head
211211
pendingNonces *noncer // Pending state tracking virtual nonces
212212

213-
reserve txpool.AddressReserver // Address reserver to ensure exclusivity across subpools
214-
pending map[common.Address]*list // All currently processable transactions
215-
queue map[common.Address]*list // Queued but non-processable transactions
216-
beats map[common.Address]time.Time // Last heartbeat from each known account
217-
all *lookup // All transactions to allow lookups
218-
priced *pricedList // All transactions sorted by price
219-
auths map[common.Address][]*types.Transaction // All accounts with a pooled authorization
213+
reserve txpool.AddressReserver // Address reserver to ensure exclusivity across subpools
214+
pending map[common.Address]*list // All currently processable transactions
215+
queue map[common.Address]*list // Queued but non-processable transactions
216+
beats map[common.Address]time.Time // Last heartbeat from each known account
217+
all *lookup // All transactions to allow lookups
218+
priced *pricedList // All transactions sorted by price
220219

221220
reqResetCh chan *txpoolResetRequest
222221
reqPromoteCh chan *accountSet
@@ -248,7 +247,6 @@ func New(config Config, chain BlockChain) *LegacyPool {
248247
pending: make(map[common.Address]*list),
249248
queue: make(map[common.Address]*list),
250249
beats: make(map[common.Address]time.Time),
251-
auths: make(map[common.Address][]*types.Transaction),
252250
all: newLookup(),
253251
reqResetCh: make(chan *txpoolResetRequest),
254252
reqPromoteCh: make(chan *accountSet),
@@ -592,7 +590,7 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction) error {
592590
KnownConflicts: func(from common.Address, auths []common.Address) []common.Address {
593591
var conflicts []common.Address
594592
// The transaction sender cannot have an in-flight authorization.
595-
if _, ok := pool.auths[from]; ok {
593+
if _, ok := pool.all.auths[from]; ok {
596594
conflicts = append(conflicts, from)
597595
}
598596
// Authorities cannot conflict with any pending or queued transactions.
@@ -728,13 +726,11 @@ func (pool *LegacyPool) add(tx *types.Transaction) (replaced bool, err error) {
728726
if old != nil {
729727
pool.all.Remove(old.Hash())
730728
pool.priced.Removed(1)
731-
pool.removeAuthorities(old)
732729
pendingReplaceMeter.Mark(1)
733730
}
734731
pool.all.Add(tx)
735732
pool.priced.Put(tx)
736733
pool.queueTxEvent(tx)
737-
pool.addAuthorities(tx)
738734
log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To())
739735

740736
// Successful promotion, bump the heartbeat
@@ -746,7 +742,6 @@ func (pool *LegacyPool) add(tx *types.Transaction) (replaced bool, err error) {
746742
if err != nil {
747743
return false, err
748744
}
749-
pool.addAuthorities(tx)
750745

751746
log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To())
752747
return replaced, nil
@@ -794,7 +789,6 @@ func (pool *LegacyPool) enqueueTx(hash common.Hash, tx *types.Transaction, addAl
794789
// Discard any previous transaction and mark this
795790
if old != nil {
796791
pool.all.Remove(old.Hash())
797-
pool.removeAuthorities(old)
798792
pool.priced.Removed(1)
799793
queuedReplaceMeter.Mark(1)
800794
} else {
@@ -814,7 +808,6 @@ func (pool *LegacyPool) enqueueTx(hash common.Hash, tx *types.Transaction, addAl
814808
if _, exist := pool.beats[from]; !exist {
815809
pool.beats[from] = time.Now()
816810
}
817-
pool.addAuthorities(tx)
818811
return old != nil, nil
819812
}
820813

@@ -833,15 +826,13 @@ func (pool *LegacyPool) promoteTx(addr common.Address, hash common.Hash, tx *typ
833826
if !inserted {
834827
// An older transaction was better, discard this
835828
pool.all.Remove(hash)
836-
pool.removeAuthorities(tx)
837829
pool.priced.Removed(1)
838830
pendingDiscardMeter.Mark(1)
839831
return false
840832
}
841833
// Otherwise discard any previous transaction and mark this
842834
if old != nil {
843835
pool.all.Remove(old.Hash())
844-
pool.removeAuthorities(old)
845836
pool.priced.Removed(1)
846837
pendingReplaceMeter.Mark(1)
847838
} else {
@@ -1033,9 +1024,6 @@ func (pool *LegacyPool) removeTx(hash common.Hash, outofbound bool, unreserve bo
10331024
if outofbound {
10341025
pool.priced.Removed(1)
10351026
}
1036-
// Remove any authorities the pool was tracking.
1037-
pool.removeAuthorities(tx)
1038-
10391027
// Remove the transaction from the pending lists and reset the account nonce
10401028
if pending := pool.pending[addr]; pending != nil {
10411029
if removed, invalids := pending.Remove(tx); removed {
@@ -1069,43 +1057,6 @@ func (pool *LegacyPool) removeTx(hash common.Hash, outofbound bool, unreserve bo
10691057
return 0
10701058
}
10711059

1072-
// addAuthorities tracks the supplied tx in relation to each authority it
1073-
// specifies.
1074-
func (pool *LegacyPool) addAuthorities(tx *types.Transaction) {
1075-
for _, addr := range tx.Authorities() {
1076-
list, ok := pool.auths[addr]
1077-
if !ok {
1078-
list = []*types.Transaction{}
1079-
}
1080-
if slices.Contains(list, tx) {
1081-
// Don't add duplicates.
1082-
continue
1083-
}
1084-
list = append(list, tx)
1085-
pool.auths[addr] = list
1086-
}
1087-
}
1088-
1089-
// removeAuthorities stops tracking the supplied tx in relation to its
1090-
// authorities.
1091-
func (pool *LegacyPool) removeAuthorities(tx *types.Transaction) {
1092-
for _, addr := range tx.Authorities() {
1093-
// Remove tx from tracker.
1094-
list := pool.auths[addr]
1095-
if i := slices.Index(list, tx); i >= 0 {
1096-
list = append(list[:i], list[i+1:]...)
1097-
} else {
1098-
log.Error("Authority with untracked tx", "addr", addr, "hash", tx.Hash())
1099-
}
1100-
if len(list) == 0 {
1101-
// If list is newly empty, delete it entirely.
1102-
delete(pool.auths, addr)
1103-
continue
1104-
}
1105-
pool.auths[addr] = list
1106-
}
1107-
}
1108-
11091060
// requestReset requests a pool reset to the new head block.
11101061
// The returned channel is closed when the reset has occurred.
11111062
func (pool *LegacyPool) requestReset(oldHead *types.Header, newHead *types.Header) chan struct{} {
@@ -1406,14 +1357,12 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
14061357
forwards := list.Forward(pool.currentState.GetNonce(addr))
14071358
for _, tx := range forwards {
14081359
pool.all.Remove(tx.Hash())
1409-
pool.removeAuthorities(tx)
14101360
}
14111361
log.Trace("Removed old queued transactions", "count", len(forwards))
14121362
// Drop all transactions that are too costly (low balance or out of gas)
14131363
drops, _ := list.Filter(pool.currentState.GetBalance(addr), gasLimit)
14141364
for _, tx := range drops {
14151365
pool.all.Remove(tx.Hash())
1416-
pool.removeAuthorities(tx)
14171366
}
14181367
log.Trace("Removed unpayable queued transactions", "count", len(drops))
14191368
queuedNofundsMeter.Mark(int64(len(drops)))
@@ -1434,7 +1383,6 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
14341383
for _, tx := range caps {
14351384
hash := tx.Hash()
14361385
pool.all.Remove(hash)
1437-
pool.removeAuthorities(tx)
14381386
log.Trace("Removed cap-exceeding queued transaction", "hash", hash)
14391387
}
14401388
queuedRateLimitMeter.Mark(int64(len(caps)))
@@ -1497,7 +1445,6 @@ func (pool *LegacyPool) truncatePending() {
14971445
// Drop the transaction from the global pools too
14981446
hash := tx.Hash()
14991447
pool.all.Remove(hash)
1500-
pool.removeAuthorities(tx)
15011448

15021449
// Update the account nonce to the dropped transaction
15031450
pool.pendingNonces.setIfLower(offenders[i], tx.Nonce())
@@ -1523,7 +1470,6 @@ func (pool *LegacyPool) truncatePending() {
15231470
// Drop the transaction from the global pools too
15241471
hash := tx.Hash()
15251472
pool.all.Remove(hash)
1526-
pool.removeAuthorities(tx)
15271473

15281474
// Update the account nonce to the dropped transaction
15291475
pool.pendingNonces.setIfLower(addr, tx.Nonce())
@@ -1599,15 +1545,13 @@ func (pool *LegacyPool) demoteUnexecutables() {
15991545
for _, tx := range olds {
16001546
hash := tx.Hash()
16011547
pool.all.Remove(hash)
1602-
pool.removeAuthorities(tx)
16031548
log.Trace("Removed old pending transaction", "hash", hash)
16041549
}
16051550
// Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later
16061551
drops, invalids := list.Filter(pool.currentState.GetBalance(addr), gasLimit)
16071552
for _, tx := range drops {
16081553
hash := tx.Hash()
16091554
pool.all.Remove(hash)
1610-
pool.removeAuthorities(tx)
16111555
log.Trace("Removed unpayable pending transaction", "hash", hash)
16121556
}
16131557
pendingNofundsMeter.Mark(int64(len(drops)))
@@ -1717,12 +1661,15 @@ type lookup struct {
17171661
slots int
17181662
lock sync.RWMutex
17191663
txs map[common.Hash]*types.Transaction
1664+
1665+
auths map[common.Address][]*types.Transaction // All accounts with a pooled authorization
17201666
}
17211667

17221668
// newLookup returns a new lookup structure.
17231669
func newLookup() *lookup {
17241670
return &lookup{
1725-
txs: make(map[common.Hash]*types.Transaction),
1671+
txs: make(map[common.Hash]*types.Transaction),
1672+
auths: make(map[common.Address][]*types.Transaction),
17261673
}
17271674
}
17281675

@@ -1773,6 +1720,7 @@ func (t *lookup) Add(tx *types.Transaction) {
17731720
slotsGauge.Update(int64(t.slots))
17741721

17751722
t.txs[tx.Hash()] = tx
1723+
t.addAuthorities(tx)
17761724
}
17771725

17781726
// Remove removes a transaction from the lookup.
@@ -1787,6 +1735,7 @@ func (t *lookup) Remove(hash common.Hash) {
17871735
}
17881736
t.slots -= numSlots(tx)
17891737
slotsGauge.Update(int64(t.slots))
1738+
t.removeAuthorities(tx)
17901739

17911740
delete(t.txs, hash)
17921741
}
@@ -1803,6 +1752,43 @@ func (t *lookup) TxsBelowTip(threshold *big.Int) types.Transactions {
18031752
return found
18041753
}
18051754

1755+
// addAuthorities tracks the supplied tx in relation to each authority it
1756+
// specifies.
1757+
func (t *lookup) addAuthorities(tx *types.Transaction) {
1758+
for _, addr := range tx.Authorities() {
1759+
list, ok := t.auths[addr]
1760+
if !ok {
1761+
list = []*types.Transaction{}
1762+
}
1763+
if slices.Contains(list, tx) {
1764+
// Don't add duplicates.
1765+
continue
1766+
}
1767+
list = append(list, tx)
1768+
t.auths[addr] = list
1769+
}
1770+
}
1771+
1772+
// removeAuthorities stops tracking the supplied tx in relation to its
1773+
// authorities.
1774+
func (t *lookup) removeAuthorities(tx *types.Transaction) {
1775+
for _, addr := range tx.Authorities() {
1776+
// Remove tx from tracker.
1777+
list := t.auths[addr]
1778+
if i := slices.Index(list, tx); i >= 0 {
1779+
list = append(list[:i], list[i+1:]...)
1780+
} else {
1781+
log.Error("Authority with untracked tx", "addr", addr, "hash", tx.Hash())
1782+
}
1783+
if len(list) == 0 {
1784+
// If list is newly empty, delete it entirely.
1785+
delete(t.auths, addr)
1786+
continue
1787+
}
1788+
t.auths[addr] = list
1789+
}
1790+
}
1791+
18061792
// numSlots calculates the number of slots needed for a single transaction.
18071793
func numSlots(tx *types.Transaction) int {
18081794
return int((tx.Size() + txSlotSize - 1) / txSlotSize)
@@ -1837,5 +1823,4 @@ func (pool *LegacyPool) Clear() {
18371823
pool.pending = make(map[common.Address]*list)
18381824
pool.queue = make(map[common.Address]*list)
18391825
pool.pendingNonces = newNoncer(pool.currentState)
1840-
pool.auths = make(map[common.Address][]*types.Transaction)
18411826
}

0 commit comments

Comments
 (0)