FastRawTransactionManager's resetNonce() will bring its nonce field out of sync
IvanovVenko opened this issue · 1 comments
FastRawTransactionManager's function resetNonce() will bring its nonce field out of sync
Steps To Reproduce
-
Using FastRawTransactionManager to instantiate a web3j contract instance.
MyContract myContractInstance = MyContract.load(myContractAddress, myWeb3jInstance, myFastRawTxManager, myGasProvider); -
Call resetNonce on the FastRawTransactionManager instance:
myFastRawTxManager.resetNonce(); -
Send a contract transaction:
RemoteFunctionCall rfc = myContractInstance.myMethod().send(); -
The result is that the transaction times out:
"Transaction receipt was not generated after 40 seconds for transaction: 0x21d063bb9057abc172bb7b590a3ea03d3a76eabc5409675fed961269a9d3f1e7"
Expected behavior
The expectation is that the transaction will succeed.
Actual behavior
Originally:
- the FastRawTransactionManager's nonce is "-1"
- the network's TransactionCount for the current user is "n".
Calling resetNonce() will result in:
- the FastRawTransactionManager's nonce is "n"
- the network's TransactionCount for the current user is "n".
Creating the TX will perform a call to:
protected synchronized BigInteger getNonce() throws IOException {
if (nonce.signum() == -1) {
// obtain lock
nonce = super.getNonce();
} else {
nonce = nonce.add(BigInteger.ONE);
}
return nonce;
}
that will return an incremented nonce (one with value "n+1"), so the transaction will remain in the node's Transaction Pool until another transaction with a nonce with value "n" is sent.
In the most scenario's this will occur only after:
- restarting the application containing the web3j instance;
or - calling FastRawTransactionManager's setNonce (-1); // of course with casting to BigInteger
or - calling FastRawTransactionManager's setNonce (n-1); // of course with casting to BigInteger
Environment
Describe the environment in which the issue occurs
- Web3j 4.10.3
- Java 17
- ubuntu 22.04
Additional context
Add any other context about the problem here.
- Logs
- Sample code and/or code snippets
- Unit/integration tests to highlight the issue
- etherscan references
I had the same problem. As a workaround I solved it by using the setNonce(BigInteger.valueOf(-1L))
instead of resetNonce().
This will trigger the super.getNonce() in the next call to getNonce(), which makes the call to the blockchain, when the next transaction is processed.