@@ -123,9 +123,10 @@ type blockChain interface {
123
123
124
124
// TxPoolConfig are the configuration parameters of the transaction pool.
125
125
type TxPoolConfig struct {
126
- NoLocals bool // Whether local transaction handling should be disabled
127
- Journal string // Journal of local transactions to survive node restarts
128
- Rejournal time.Duration // Time interval to regenerate the local transaction journal
126
+ Locals []common.Address // Addresses that should be treated by default as local
127
+ NoLocals bool // Whether local transaction handling should be disabled
128
+ Journal string // Journal of local transactions to survive node restarts
129
+ Rejournal time.Duration // Time interval to regenerate the local transaction journal
129
130
130
131
PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool
131
132
PriceBump uint64 // Minimum price bump percentage to replace an already existing transaction (nonce)
@@ -231,6 +232,10 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block
231
232
gasPrice : new (big.Int ).SetUint64 (config .PriceLimit ),
232
233
}
233
234
pool .locals = newAccountSet (pool .signer )
235
+ for _ , addr := range config .Locals {
236
+ log .Info ("Setting new local account" , "address" , addr )
237
+ pool .locals .add (addr )
238
+ }
234
239
pool .priced = newTxPricedList (pool .all )
235
240
pool .reset (nil , chain .CurrentBlock ().Header ())
236
241
@@ -534,6 +539,14 @@ func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error) {
534
539
return pending , nil
535
540
}
536
541
542
+ // Locals retrieves the accounts currently considered local by the pool.
543
+ func (pool * TxPool ) Locals () []common.Address {
544
+ pool .mu .Lock ()
545
+ defer pool .mu .Unlock ()
546
+
547
+ return pool .locals .flatten ()
548
+ }
549
+
537
550
// local retrieves all currently known local transactions, groupped by origin
538
551
// account and sorted by nonce. The returned transaction set is a copy and can be
539
552
// freely modified by calling code.
@@ -665,7 +678,10 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) {
665
678
}
666
679
// Mark local addresses and journal local transactions
667
680
if local {
668
- pool .locals .add (from )
681
+ if ! pool .locals .contains (from ) {
682
+ log .Info ("Setting new local account" , "address" , from )
683
+ pool .locals .add (from )
684
+ }
669
685
}
670
686
pool .journalTx (from , tx )
671
687
@@ -1138,6 +1154,7 @@ func (a addressesByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
1138
1154
type accountSet struct {
1139
1155
accounts map [common.Address ]struct {}
1140
1156
signer types.Signer
1157
+ cache * []common.Address
1141
1158
}
1142
1159
1143
1160
// newAccountSet creates a new address set with an associated signer for sender
@@ -1167,6 +1184,20 @@ func (as *accountSet) containsTx(tx *types.Transaction) bool {
1167
1184
// add inserts a new address into the set to track.
1168
1185
func (as * accountSet ) add (addr common.Address ) {
1169
1186
as .accounts [addr ] = struct {}{}
1187
+ as .cache = nil
1188
+ }
1189
+
1190
+ // flatten returns the list of addresses within this set, also caching it for later
1191
+ // reuse. The returned slice should not be changed!
1192
+ func (as * accountSet ) flatten () []common.Address {
1193
+ if as .cache == nil {
1194
+ accounts := make ([]common.Address , 0 , len (as .accounts ))
1195
+ for account := range as .accounts {
1196
+ accounts = append (accounts , account )
1197
+ }
1198
+ as .cache = & accounts
1199
+ }
1200
+ return * as .cache
1170
1201
}
1171
1202
1172
1203
// txLookup is used internally by TxPool to track transactions while allowing lookup without
0 commit comments