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

FastRawTransactionManager's resetNonce() will bring its nonce field out of sync #2002

Open
IvanovVenko opened this issue Feb 9, 2024 · 1 comment
Labels
bug A bug in behaviour or functionality

Comments

@IvanovVenko
Copy link

IvanovVenko commented Feb 9, 2024

FastRawTransactionManager's function resetNonce() will bring its nonce field out of sync

Steps To Reproduce

  1. Using FastRawTransactionManager to instantiate a web3j contract instance.
    MyContract myContractInstance = MyContract.load(myContractAddress, myWeb3jInstance, myFastRawTxManager, myGasProvider);

  2. Call resetNonce on the FastRawTransactionManager instance:
    myFastRawTxManager.resetNonce();

  3. Send a contract transaction:
    RemoteFunctionCall rfc = myContractInstance.myMethod().send();

  4. 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
@IvanovVenko IvanovVenko added the bug A bug in behaviour or functionality label Feb 9, 2024
@gabsnichtmehr
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug in behaviour or functionality
Projects
None yet
Development

No branches or pull requests

2 participants