-
-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core: TxPool simplifications and improvements #46
Conversation
for _, tx := range pool.queue[addr].Flatten() { | ||
list := pool.queue[addr] | ||
list.txs.ensureCache() | ||
for _, tx := range list.txs.cache { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't alloc a slice just to iterate.
core/tx_pool.go
Outdated
@@ -544,10 +540,12 @@ func (pool *TxPool) local() map[common.Address]types.Transactions { | |||
txs := make(map[common.Address]types.Transactions) | |||
for addr := range pool.locals.accounts { | |||
if pending := pool.pending[addr]; pending != nil { | |||
txs[addr] = append(txs[addr], pending.Flatten()...) | |||
pending.txs.ensureCache() | |||
txs[addr] = append(txs[addr], pending.txs.cache...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't alloc a slice just to copy.
from, _ := types.Sender(pool.signer, tx) // already validated | ||
dirty[from] = struct{}{} | ||
} | ||
var errs []error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't alloc. Errors should be rare.
pool.promoteExecutable(addr, list) | ||
} | ||
pool.finishPromotion() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separate method to directly iterate, rather than a nil special case below which allocs a slice to iterate over.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The diff below looks messy, but it was just broken into two helper methods.
@@ -1054,7 +1063,8 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { | |||
|
|||
// Drop all transactions if they are less than the overflow | |||
if size := uint64(list.Len()); size <= drop { | |||
for _, tx := range list.Flatten() { | |||
list.txs.ensureCache() | |||
for _, tx := range list.txs.cache { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't alloc a slice just to iterate.
@@ -341,15 +341,6 @@ func (pool *TxPool) loop() { | |||
} | |||
} | |||
|
|||
// lockedReset is a wrapper around reset to allow calling it in a thread safe | |||
// manner. This method is only ever used in the tester! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to test file.
defer pool.mu.RUnlock() | ||
|
||
return new(big.Int).Set(pool.gasPrice) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused.
Pending() map[common.Address]types.Transactions | ||
|
||
// PendingList is like Pending, but only txs. | ||
PendingList() types.Transactions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some callers were just copying map values from Pending into their own slices. This helper does it directly, to avoid extra copying into an intermediate map.
@@ -101,7 +101,10 @@ type txPool interface { | |||
|
|||
// Pending should return pending transactions. | |||
// The slice should be modifiable by the caller. | |||
Pending() (map[common.Address]types.Transactions, error) | |||
Pending() map[common.Address]types.Transactions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both impls always returned nil error.
With this branch I was able to do ~400tps smoothly for 5 minutes:
|
Attempted 500 tps for 5 minutes. Ingestion rate was ~472tps, but processing was a bit slower, at 419tps. CPU nearly maxed as well. Blocks are larger, but also slower.
|
@@ -112,7 +111,7 @@ func (journal *txJournal) insert(tx *types.Transaction) error { | |||
|
|||
// rotate regenerates the transaction journal based on the current contents of | |||
// the transaction pool. | |||
func (journal *txJournal) rotate(all map[common.Address]types.Transactions) error { | |||
func (journal *txJournal) rotate(acts int, all types.Transactions) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did they have the map in the first place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't see an obvious reason. May have just wound up that way from incremental changes, or maybe it was meant to be more readable
By freeing up some more resources, I was able to do 5m@500tps:
|
Aiming for 5m@550 - Ingested at 534, processed at 455. Big slow blocks.
|
if err := pool.journal.load(pool.AddLocal); err != nil { | ||
if err := pool.journal.load(func(txs types.Transactions) []error { | ||
// No need to lock since we're still setting up. | ||
return pool.addTxsLocked(txs, !pool.config.NoLocals) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't lock during setup. Add batches instead of one at a time and promoting executables on each one.
This change simplifies and improves some things surrounding
core.TxPool