-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
How do I manage nonces? #363
Comments
(You can also make it pass by adding a delay before the second |
Is this using the JsonRpcSigner from a JsonRpcProvider? Are you making many requests to your node in a very short time? Keep in mind that a TCP connection is not instantaneous, so if you make 2 TCP connects at the same time, the order may not be retained. There is a change coming in a few minutes (just waiting for the test cases to complete) which may address this for JsonRpcSigners by not calling populateTransaction, so it will be up to the node to assign nonces. |
Just published; please try |
It still seems to fail on 4.0.16: magmo/test-contract@f5291c3 What actually seems to happen is that https://gist.github.com/andrewgordstewart/5186dd8731e3f218746592bb6efc53be I'm sure it has to do with the behaviour of |
That is part of Ethereum though, so not really an issue that ethers can address directly in the way it is being used. The getTransactionCount returns the number of transactions that have been mined, so two quick back-to-back transactions, will get the same nonce. If you are not using a system which manages nonces for you (such as a JsonRpcSigner), you will need to manually manage that. I am working on a cookbook entry to demonstrate a Signer that will manage the nonce for you. What |
It's a |
Yeah, a If you instead use: let signer = provider.getSigner(); you will find this does not happen (probably) because the node will manage the nonce for you. |
That makes sense. However, the signer's account wouldn't have any eth in that case. How would I set up the provider so that its signer corresponds to a given private key? |
The NonceManager will have a Signer it wraps, so it can work with a private key, or a Ledger Nano, or Firefly Hardware Wallet, or anything else. :) |
Ok, great. I assume by this, you mean that the
For the moment, I'll deal with this issue by adding a small delay between transactions as needed 🐷 |
Until we can use the NonceManager to manage nonces, we ensure some time separation between our contract calls to ensure that nonces increment. See ethers-io/ethers.js#363 for discussion.
See discussion here: ethers-io/ethers.js#363 `await provider.getSigner().getAddress()` seems to have ether, though it's not clear why?
See discussion here: ethers-io/ethers.js#363 `await provider.getSigner().getAddress()` seems to have ether, though it's not clear why?
See discussion here: ethers-io/ethers.js#363 `await provider.getSigner().getAddress()` seems to have ether, though it's not clear why?
It turns out that the way we set up our ganache server, the account So, I switched to using this technique in our code However, I now have seen a flickering test failure with the same error. Here's an example: Test runs #178, #180 and #182 are all running off of commit magmo/force-move-protocol@ad4468d, and #182 experiences
(The commit introducing the |
I'm experiencing this issue on random test cases, so it's hard to see whether the tests are actually passing. ethers-io/ethers.js#363 (comment)
@ricmoo do you have any insight into the flickering test above? The |
`it("reverts for no reason", async () => { add the nonce parameter will work |
If you use I think that may be the problem you are concerned with? If not, let me know more about what you are expecting. :) |
hi,thx for your reply^_^ my problem maybe related to this MetaMask/web3-provider-engine#300,i think it maybe the reason of this topic。 it cause when test the code with ganache and use truffle-hdwallet-provider lib, truffle-hdwallet-provider rely web3-provider-engine lib. when a transaction revert,every transaction after the revert fail with error "Error: the tx doesn't have the correct nonce. account has nonce of: (n) tx has nonce of: (n-1)" i don't kwon how to fixed the problem with comprehensible way, but it will work add parameter "nonce: await web3.eth.getTransactionCount(account[0])" on transaction, i think this way will keep away from same bug with related lib related problem i found |
+1. Facing this issue as well and not sure what's going on |
Caught the issue here. Turns out I was using Jest without the --runInBand flag which caused the tests to run in parallel instead of sequentially. If anyone else comes across this I hope this saves you lost time lol. |
See discussion here: ethers-io/ethers.js#363 `await provider.getSigner().getAddress()` seems to have ether, though it's not clear why?
Is it possible to prevent wallet.sendTransaction from setting nonce now? I guess that should make geth/parity choose the nonce correctly? Because from what I can tell right now there's not really a way to send multiple transactions one after another via wallet, and wallet always sets nonce: Line 97 in b1c6575
|
Ok I guess what I'm saying doesn't make sense since wallet signs the transaction to it has to know the nonce before sending it to the node. |
If you are using v5, there is a |
Is this resolved? I think the NonceManager should take care of what is needed by most people? I'm going to close this now, but feel free to re-open. Thanks! :) |
Apologies for re-opening this, but I am having a hell-of-a-time getting the Existing code:
How do I adapt the |
After a lot of reading and experimentation, I have some insight. My issue is caused because I'm signing a bunch of transactions on the code-side, all at once. They don't hit the pool fast enough for the NonceManager to even know they exist, and by the time the first one ends up in "pending", the rest have no hope of catching up. Exactly what you've mentioned before about pending becoming "overloaded." Where I think this could be solved is by having a NonceHolder completely outside of the Maybe that's naive thinking, but it's where I've ended up at the moment. |
@EvilJordan the NonceManager will increment the nonce synchronously, so for sending it doesn’t matter how fast you call it, the nonce will be incremented. But for signing-only, you should call |
Hi @ricmoo . I have a question which matches this issue's title. So I will post it here. However, it is pretty much asking the opposite of what the discussion has been about. In my new design I want to make sure that the default Therefore, if I previously sent a transaction, and that transaction still has not been mined, and I now send a new transaction, I automatically want the new transaction to use the same nonce as the unmined previous transaction, so that only one of them makes it through. Is this the default behavior that ethers uses under the hood, or do I need to somehow implement custom nonce management for this? How does ethers.js get the default nonce value under the hood anyway? Say I use an Infura Provider connected to my Wallet. How do you fill the default nonce value there? Say my script does this:
What default nonce would be used for sendTx1 and sendTx2 ? Does ethers just get the value to use from the connected Infura Provider and rely on that? I want to determine whether, if Tx1 was never mined for whatever reason, ethers.js built-in default nonce selection would be so that my Intervals could keep sending transactions, basically cancelling the TX sent during the previous Interval, if it was not mined within 60 seconds (since the Intervals are every 60 seconds). |
At some point, everyone is responsible for managing their pending transactions. Some of what I've read in this discussion should be handled by bespoke code, e.g., local storage in the browser or a DB to track script based txns. Even @ricmoo 's suggestion of using |
What if I'm signing transactions with the same private key (ie. for the same account), from different instances of |
I had the same issue. |
I've come across this "incorrect nonce" error while trying to write a kind of
assertRevert
function to assert that a particular revert occurred.magmo/test-contract@392f4b3
The
assertRevert
as written isn't quite robust yet, but it seems to have highlighted a bug in ethers, where raw transactions are created with an incorrect nonce:Removing the
gasLimit
override causes the test to pass:magmo/test-contract@2d31c71
Reproduction instructions are in the readme.
The text was updated successfully, but these errors were encountered: