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

ContractTransactionResponse.wait() hangs when the transaction is replaced #4875

Open
PierreJeanjacquot opened this issue Oct 30, 2024 · 1 comment
Assignees
Labels
investigate Under investigation and may be a bug. v6 Issues regarding v6

Comments

@PierreJeanjacquot
Copy link

Ethers Version

6.13.4

Search Terms

wait

Describe the Problem

ContractTransactionResponse.wait() does not reject when the transaction is replaced, the promise hangs forever.

The attached snippet sends 2 approve(randomAddress,0) tx using the same wallet and same nonce, one is confirmed, the other is dropped but the wait() method does not detect it.

NB:

Code Snippet

import { Contract, Wallet, JsonRpcProvider } from "ethers";

const provider = new JsonRpcProvider("https://bellecour.iex.ec");
const wallet = Wallet.createRandom(provider);

const contract = new Contract(
  "0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f",
  [
    {
      inputs: [
        { internalType: "address", name: "", type: "address" },
        { internalType: "uint256", name: "", type: "uint256" },
      ],
      name: "approve",
      outputs: [{ internalType: "bool", name: "", type: "bool" }],
      stateMutability: "nonpayable",
      type: "function",
    },
  ],
  wallet
);

// send 2 concurrent tx (same nonce) to a contract (here approve 0 for the sake of the demo)
await Promise.all([
  contract
    .approve(Wallet.createRandom().address, 0, { gasPrice: 0 })
    .then((tx) => {
      console.log("A sent", tx.hash);
      return tx.wait();
    })
    .then((tx) => console.log("A confirmed", tx.hash))
    .catch((e) => console.log("A error", e)),
  contract
    .approve(Wallet.createRandom().address, 0, { gasPrice: 0 })
    .then((tx) => {
      console.log("B sent", tx.hash);
      return tx.wait();
    })
    .then((tx) => console.log("B confirmed", tx.hash))
    .catch((e) => console.log("B error", e)),
]);

// Example of logs:
//
// A sent 0x90f90e7460aaac44b1e9ca06ea2c7311341a64b685d0ed46c55f590ce9429ccb
// B sent 0x04268b427facd3de304f5fad4e8bce692c6b7eef2ecfe0dfc26d26a70c5dce2b
// B confirmed 0x04268b427facd3de304f5fad4e8bce692c6b7eef2ecfe0dfc26d26a70c5dce2b
//

// one of the 2 tx will be replaced but ethers fails to detect it
// the process hangs forever waiting for the `tx.wait()` promise to resolve or reject

console.log("DONE"); // never reached

Contract ABI

No response

Errors

No response

Environment

node.js (v12 or newer)

Environment (Other)

No response

@PierreJeanjacquot PierreJeanjacquot added investigate Under investigation and may be a bug. v6 Issues regarding v6 labels Oct 30, 2024
@PierreJeanjacquot
Copy link
Author

it seems the #startBlock is lost when the TransactionResponse is wrapped into a ContractTransactionResponse in Contract send methods

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
investigate Under investigation and may be a bug. v6 Issues regarding v6
Projects
None yet
Development

No branches or pull requests

2 participants