-
Couldn't load subscription status.
- Fork 88
Description
Background
Hedera has no mempool, and our Mirror Node (MN) has a slight delay in the information it imports from the state, in this case, the nonce of a user. Currently, in our relay for the eth_getTransactionCount endpoint, we rely on the MN only. This allows race conditions to happen, leading to failed transactions on the Consensus level.
Goals
- Store per-address tx_list via a configurable storage backend
- Implement eth_getTransactionCount with block tag = pending
- Support operators’ choice of storage backends by using a Storage interface
Non-goals
- Guaranteeing execution ordering when users send transactions out of order (that behaviour is out of scope on Hedera due to no active mempool).
Use cases
In scope
- A user should be able to send multiple transactions with manually calculated nonces
- If I submit nonces N, N+1, N+2, the relay reserves these atomically and lets them through (subject to CN validation). This currently works because our precheck checks only for lower nonces passed in the transaction compared to account info from the MN
- A user should be able to calculate nonces through eth_getTransactionCount with the pending tag and be able to get the “latest info” of the account, not the one from MN, which won’t be updated if multiple transactions are sent
- If MN is behind, local reservations ensure “pending” points to the next usable nonce.
Out of scope (documented limitation)
- A user should be able to send more than 1 transaction not ordered by nonce and expect later ones to eventually execute without resubmitting
- Works on Ethereum due to mempool ordering. On Hedera, there’s no active mempool; services do not buffer by nonce. A high nonce will be rejected with
WRONG_NONCEeven if the gap is later filled, unless the user resubmits.
- Works on Ethereum due to mempool ordering. On Hedera, there’s no active mempool; services do not buffer by nonce. A high nonce will be rejected with
Requirements
Functional Requirements
- The system must enforce nonce rules only if the
ENABLE_TX_POOLflag is set to true - the default is false - The system must retrieve the account nonce from the Mirror Node and compute the expected nonce as “Mirror Node nonce + number of pending transactions” for that signer, if they have pending transaction list in storage
- The system must fail on nonce precheck if the txNonce < MN nonce when there is no pending transaciton list saved for the user
- The system must fail on nonce precheck if the txNonce < MN nonce + pending transaction list count, when the user has a list in the storage
- The system must record each transaction in the pending-transaction list before submitting it to the consensus node.
- The system must remove a transaction from the pending-transaction list once the consensus node has finished processing it, regardless of success or failure.
- The system must return only the Mirror Node’s nonce when handling eth_getTransactionCount(address, "latest").
- The system must return the Mirror Node’s nonce plus the current pending-transaction list length when handling eth_getTransactionCount(address, "pending"), if the
ENABLE_TX_POOLflag is set to true
Non-functional requirements
- The system shall clear the pending-transaction list on startup (after a restart).
- The system shall return a JSON-RPC error for eth_getTransactionCount("pending") if the Redis storage is unavailable.
- The system shall fall back to Mirror Node–only nonce precheck in eth_sendRawTransaction when Redis is unavailable, preserving existing behavior.
- The system shall enforce atomic updates per address in multi-instance deployments to prevent race conditions.