aeternity
aeternity copied to clipboard
Allow mining more than 5 transactions by a single account in a microblock
Expected Behavior
PostTransaction should accept a valid transaction.
Actual Behavior
It rejects a valid transaction saying tx_nonce_too_high_for_account
in the local node logs.
Steps to Reproduce the Problem
Run this script with sdk@10:
const { Node, Universal, MemoryAccount, Crypto } = require('@aeternity/aepp-sdk');
(async () => {
const node = await Node({ url: 'https://testnet.aeternity.io' })
const sdk = await Universal({
nodes: [{ name: 'testnet', instance: node }],
compilerUrl: 'https://compiler.aepps.com',
accounts: [MemoryAccount({
keypair: {
publicKey: 'ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR',
secretKey: 'bf66e1c256931870908a649572ed0257876bb84e3cdf71efb12f56c7335fad54d5cf08400e988222f26eb4b02c8f89077457467211a6e6d955edb70749c6a33b'
}
})]
})
const addresses = new Array(10).fill().map(() => Crypto.generateKeyPair().publicKey)
let nonce = (await sdk.api.getAccountNextNonce(await sdk.address())).nextNonce
for (const address of addresses) {
console.log('spend to', address)
await sdk.spend(100, address, { nonce, verify: false, waitMined: false })
nonce += 1
}
})()
it should fail with "Error: v3/transactions error: Invalid tx" on the 6th iteration or so.
Configuration, logs, error output, etc.
Here is how this looks in logs of a local node:
17:46:48.208 [debug] [5649] Msg = #{'EncodedTx' => #{<<"tx">> => <<"tx_+KILAfhCuECM+o0B7epxAPmEwOw9Oj7NpkTxMEX8ylWzdcLVBl7w82y7wRr64TojJWakym0KtxM3s2yjDlrAoxQ4s4Z0Qu0DuFr4WAwBoQFKgXx9/9S41N/H5yCdFts7PFL9iEFEhHhEc9eeBFP7k6EBA8NlT/iK2MLWiC5IP1KIaXtgcFE5wVFefRADPA+2sCaHI4byb8ECyIYPR44IQAAABoBBToO/">>},'int-as-string' => false}
2021-12-26T17:46:48.218056300Z 17:46:48.212 [debug] Tx {aetx,spend_tx,aec_spend_tx,90,{spend_tx,{id,account,<<74,129,124,125,255,212,184,212,223,199,231,32,157,22,219,59,60,82,253,136,65,68,132,120,68,115,215,158,4,83,251,147>>},{id,account,<<3,195,101,79,248,138,216,194,214,136,46,72,63,82,136,105,123,96,112,81,57,193,81,94,125,16,3,60,15,182,176,38>>},10000000000000712,16800000000000,0,6,<<>>}} cannot be applied due to an error tx_nonce_too_high_for_account
2021-12-26T17:46:48.220696800Z 17:46:48.212 [debug] Candidate worker <0.3446.0> failed no_update_to_block_candidate
2021-12-26T17:46:48.233068000Z 17:46:48.231 [debug] Validation error for tx <<227,11,83,28,3,218,1,3,176,6,193,103,20,227,240,142,217,72,78,32,3,30,13,50,222,142,1,53,86,113,48,78>>: {error,nonce_too_high}
2021-12-26T17:46:48.234671700Z 17:46:48.232 [debug] Transaciton {signed_tx,{aetx,spend_tx,aec_spend_tx,90,{spend_tx,{id,account,<<74,129,124,125,255,212,184,212,223,199,231,32,157,22,219,59,60,82,253,136,65,68,132,120,68,115,215,158,4,83,251,147>>},{id,account,<<74,51,133,202,111,183,245,206,221,197,112,107,242,107,110,135,37,218,143,230,92,182,76,41,51,24,144,227,57,111,75,126>>},10000000000000518,16800000000000,0,7,<<>>}},[<<222,79,18,236,217,130,53,70,208,34,84,246,200,55,210,128,164,88,202,110,222,45,28,109,223,195,156,23,46,184,122,130,191,80,19,42,114,96,184,79,163,27,212,84,186,74,112,2,111,23,144,223,119,218,197,57,154,142,83,85,120,22,179,12>>]} failed to be pushed to pool because: nonce_too_high
It's configuration: https://github.com/aeternity/aepp-sdk-js/blob/72907f351579444ebd269668f254d4956657e38b/docker/aeternity_node_mean16.yaml
update: necessary to add micro_block_cycle: 300
Specifications
- Node Version: 6.3.0
This issue looks similar to https://github.com/aeternity/aeternity/issues/3516
The posted log has two transactions, one with nonce 6 and one with nonce 7, not sure what is expected. The one with nonce 6 can't be applied and the one with 7 can't be pushed to the tx-pool if the nonce of that account is say 1 or 2 that would be the correct behavior - can't really tell from this subset of the log.
@hanssv I guess the "nonce too high" error can bit improved a bit by saying what's the current/expected nonce
Sure, but an improved error messge does not make the Tx any more valid the issue is literally: "PostTransaction return Invalid tx for correct transactions"
I find out that it wasn't reproducible with the provided node configuration. micro_block_cycle
should be set to 300, if it is 20 then all transactions are accepted.
here is the complete log: https://gist.github.com/davidyuk/2fbfb8cdb1d93028204f8cdf8966ecab
do I understand correctly that transactions that include a too high nonce are rejected by the node? why is that? was this always like that or was this implemented in some of the latest node updates?
I guess @velzevur might be good to be involved here
we were talking about DEX user experience and this is currently a problem. for sure we will find other solutions, but I am just wondering about this in general
Ok, so there are a couple of things here. There is a build protection for suspicious transactions - ones with unexpectedly high nonces. The node simply rejects those if they are sent to it. They are not allowed in the pool. If a miner node later on includes this transaction in a micro block - all nodes would agree and accept it. For this to happen all txs with subsequent nonces till this point shall be included in blocks as well.
I am saying this to stress out that this is not a protocol restriction but a transaction pool setting. There are 2 possibilities here:
- a brand new account without any txs in the pool sends a transaction with an unexpectedly high nonce. By default anything above 1 would be rejected
- an account with expected nonce greater than 1 sends a transaction with an unexpectedly high nonce. This is
latest_included_tx_nonce + < nonce_offset >
wherenonce_offset
is by default 5
You can set locally this to whatever numbers you feel like in your local config but sending bursts of txs would likely fail to propagate to the miner as most of the nodes use default configs.
You can see the configs here.
This question had been raised more than once now and this seems to be something unexpected for users. Maybe it is worth discussing if we shall make the default a big bigger number. Again, please note that this is not a part of the consensus and modifying it does not require a HF
additional comment from @velzevur in private chat:
"even if our nodes accept a tx with a nonce too high according to the default config, this will not be enough. They would gossip it to other nodes and the receivers would decide for themselves if they want to keep those txs or drop them. If the miner is using the default config - they will reject txs
it is decentralised by default and each node is free deciding it's own policies. I am afraid it could be too restrictive"
@kenodressel @bogdan-manole @CedrikNikita @davidyuk when does this happen? according to Dimitar I guess we should not experience this if the nonce_offset
is <= 5 (at least if nodes are running the default config)
This is not related to our DEX issue with the SDK, at least as far as I know. We had the issue that our nonce was already used when doing a mix of dry runs and stateful calls in parallel: https://github.com/aeternity/aepp-sdk-js/issues/1405
so the other issue is about dry-runs. ok I see, should have read it more detailed. thanks @kenodressel
You can set locally this to whatever numbers you feel like in your local config but sending bursts of txs would likely fail to propagate to the miner as most of the nodes use default configs
Won't extra transactions from my node propagate to the miner's node after the previous got mined? In case I set nonce_offset
to 1000 and miner have the default value.
In general, how would you suggest making a burst of transactions?
Sorry for confusing the DEX team 🙃
Sorry for confusing the DEX team 🙃
I think nobody was confused except me 😅 but generally it's an important topic to discuss
Remeber that there are different checks in the TX-pool. A new transaction (pushed from the outside to the node via HTTP for example) is checked in more detail compared to a gossiped tx (where it is assumed that the gossiping node has already done checks). I don't think gossiped TXs are checked for nonce_offset
right @velzevur?
Currently, because of the default nonce_offset
value, I can't mine more than 5 transactions made by a single account in a microblock. While I can potentially make about 360 transactions (6_000_000 / 16660, gas of spend tx). I propose to increase the default value of nonce_offset
to 100 or so.
This doesn't decrease protection for suspicious transactions significantly. Currently, I can produce the same amount of transactions in mempool (100) by splitting coins over 20 accounts which is not expensive.
Perhaps the nonce_offset should be set to at least the expected number of TXs that can fit in a single MB? 🤔
Perhaps the nonce_offset should be set to at least the expected number of TXs that can fit in a single MB? 🤔
A reasonable check could be to do the nonce check against the mempool first, and against the on-chain account second. Thus, if the new nonce is within range of the highest nonce from the account of a tx already in the mempool, it's fine.