Skip to content
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

Don't be notified about account nonces, don't store them; get them at selection-time #57

Merged
merged 36 commits into from
Nov 27, 2024

Conversation

andreibancioiu
Copy link
Contributor

@andreibancioiu andreibancioiu commented Nov 13, 2024

Improvement upon #55.

In the mempool, do not receive notifications about current account nonces, do not be asked to forget known nonces.

Instead, receive an account nonce provider in the constructor of TxCache, and use it when selecting transactions.

This way, we improve the robustness of:

  • initial gaps
  • transactions with lower nonces
  • other not executable transactions

Other notes:

@andreibancioiu andreibancioiu self-assigned this Nov 13, 2024
@andreibancioiu andreibancioiu changed the title Don't be notified about and store account nonces; get them at selection-time Don't be notified about account nonces, don't store them; get them at selection-time Nov 13, 2024
@andreibancioiu andreibancioiu marked this pull request as ready for review November 14, 2024 07:46
}

// Item was popped from the heap, but not used downstream.
// Therefore, the sender is completely ignored in the current selection session.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to not select any transaction of a given sender, if we've detected an initial gap.

@@ -69,3 +104,22 @@ func selectTransactionsFromBunches(bunches []bunchOfTransactions, gasRequested u

return selectedTransactions, accumulatedGas
}

func (cache *TxCache) askAboutAccountNonceIfNecessary(item *transactionsHeapItem) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

requestAccountNonceIfNecessary ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, renamed.

@raduchis raduchis self-requested a review November 14, 2024 14:39
raduchis
raduchis previously approved these changes Nov 14, 2024
@andreibancioiu andreibancioiu marked this pull request as draft November 19, 2024 13:07
@@ -99,7 +99,12 @@ func (cache *TxCache) GetByTxHash(txHash []byte) (*WrappedTransaction, bool) {

// SelectTransactions selects the best transactions to be included in the next miniblock.
// It returns up to "maxNum" transactions, with total gas <= "gasRequested".
func (cache *TxCache) SelectTransactions(gasRequested uint64, maxNum int) ([]*WrappedTransaction, uint64) {
func (cache *TxCache) SelectTransactions(accountStateProvider AccountStateProvider, gasRequested uint64, maxNum int, selectionLoopMaximumDuration time.Duration) ([]*WrappedTransaction, uint64) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now, we also pass a wrapped accounts adapter, so that we can learn the nonce, balance etc. of a sender with pending transactions. This allows us to perform a much more informed selection.

Additionally, we parametrize the selection with selectionLoopMaximumDuration (safety mechanism).

wrappedTx.Fee.Store(fee)
wrappedTx.PricePerUnit.Store(fee.Uint64() / gasLimit)

txAsGuardedTransaction, ok := wrappedTx.Tx.(data.GuardedTransactionHandler)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See MX-16157.

@@ -41,8 +41,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiversx/concurrent-map v0.1.4 h1:hdnbM8VE4b0KYJaGY5yJS2aNIW9TFFsUYwbO0993uPI=
github.com/multiversx/concurrent-map v0.1.4/go.mod h1:8cWFRJDOrWHOTNSqgYCUvwT7c7eFQ4U2vKMOp4A/9+o=
github.com/multiversx/mx-chain-core-go v1.2.21 h1:+XVKznPTlUU5EFS1A8chtS8fStW60upRIyF4Pgml19I=
github.com/multiversx/mx-chain-core-go v1.2.21/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE=
github.com/multiversx/mx-chain-core-go v1.2.23 h1:8WlCGqJHR2HQ0vN4feJwb7W4VrCwBGIzPPHunOOg5Wc=
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to update before.

heap.Push(transactionsHeap, item)
}
}

return selectedTransactions, accumulatedGas
}

func detectSkippableSender(item *transactionsHeapItem) bool {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skippable from now on, within the current selection session.

for i := 0; i < 100; i++ {
fmt.Println("Add / remove", i)
cache.Remove([]byte("alice-x-1"))
cache.AddTx(expensiveTransaction)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same objects aren't re-added to the pool (ever).

@andreibancioiu andreibancioiu marked this pull request as ready for review November 21, 2024 07:17
return
}

item.accumulatedFee.Add(item.accumulatedFee, fee)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MX-16160.

return hasMiddleGap
}

func (item *transactionsHeapItem) detectWillFeeExceedBalance() bool {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MX-16160.

@andreibancioiu andreibancioiu changed the base branch from selection-by-ppu to feat/mempool November 21, 2024 07:38
@andreibancioiu andreibancioiu dismissed raduchis’s stale review November 21, 2024 07:38

The base branch was changed.

PricePerUnit atomic.Uint64
// These fields are only set within "precomputeFields".
// We don't need to protect them with a mutex, since "precomputeFields" is called only once for each transaction.
// Additional note: "WrappedTransaction" objects are created by the Node, in dataRetriever/txpool/shardedTxPool.go.
Copy link
Contributor Author

@andreibancioiu andreibancioiu Nov 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some (older) technical debt around this matter, we can improve the design in the future.

txcache/README.md Outdated Show resolved Hide resolved
txcache/constants.go Outdated Show resolved Hide resolved
txcache/selection.go Show resolved Hide resolved
txcache/README.md Outdated Show resolved Hide resolved
txcache/selection.go Show resolved Hide resolved
txcache/selection_test.go Show resolved Hide resolved
txcache/transactionsHeap.go Outdated Show resolved Hide resolved
txcache/transactionsHeapItem.go Show resolved Hide resolved
if item.latestSelectedTransaction != nil {
return false
}
if item.senderState == nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this for optimistic reasons? if senderState is not loaded, it has no initialGap?

Copy link
Contributor Author

@andreibancioiu andreibancioiu Nov 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In practice, the body of that check is dead code.

The if item.senderState == nil is more like a "defensive programming" artifact (pessimistic).

There shouldn't be any case where account state is not retrievable. If that happens, the error is logged and the sender is skipped. Thus, for senders that we handle, sender state is never nil. requestAccountStateIfNecessary always precedes calls of detect*().

Do you recommend to drop these superfluous checks about senderState?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, they can remain like this because of the "defensive programming" checks

txcache/wrappedTransaction.go Show resolved Hide resolved
@andreibancioiu andreibancioiu merged commit 37ace93 into feat/mempool Nov 27, 2024
2 checks passed
@andreibancioiu andreibancioiu deleted the MX-16107-no-more-notify branch November 27, 2024 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants