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

forge create, cast call/send returns an error message saying transaction did not go through, even though it did #1362

Closed
2 tasks done
holma91 opened this issue Apr 19, 2022 · 9 comments
Labels
C-forge Command: forge Cmd-forge-create Command: forge create D-easy Difficulty: easy good first issue Good for newcomers P-normal Priority: normal T-bug Type: bug

Comments

@holma91
Copy link

holma91 commented Apr 19, 2022

Component

Forge, Cast

Have you ensured that all of these are up to date?

  • Foundry
  • Foundryup

What version of Foundry are you on?

forge 0.2.0 (90617a5 2022-04-12T00:13:04.257461+00:00)

What command(s) is the bug in?

forge create, cast call, cast send

Operating System

macOS (M1)

Describe the bug

running forge create --rpc-url $my_rpc --private-key $my_pk src/Contract.sol:Contract

with this contract:

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.13;

contract Contract {
    uint256 public a;

    constructor() {
        a = 1 + 2;
    }
}

gives me this error message:

[⠆] Compiling...
Compiler run successful
Error: 
   0: Contract was not deployed

Location:
   cli/src/cmd/forge/create.rs:194

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.

However if I go to my address on etherscan, the contract was deployed. I get this output from forge create around 80% of the time, and the expected "successful deployment" message 20% of the time.

If I instead run like this

RUST_LOG=ethers_providers=trace forge create --rpc-url $rpc_rinkeby --private-key $pk src/Contract.sol:Contract

this line stands out to me:

2022-04-19T15:40:36.326634Z DEBUG ethers_providers::pending_transaction: Dropped from mempool, pending tx 0xe1856bc98482d2d60b6e2def894d2241dc1314e28746662399157454437506fe

Essentially the same happens if I use cast call or cast send, for example this command:

cast call <address> "a()(uint)" --rpc-url $my_rpc

results in:

receipt not found when polling pending tx. was the transaction dropped from the mempool?

even though the message call went through. (exactly the same issue with cast send)

@holma91 holma91 added the T-bug Type: bug label Apr 19, 2022
@onbjerg onbjerg added this to Foundry Apr 19, 2022
@onbjerg onbjerg moved this to Todo in Foundry Apr 19, 2022
@onbjerg
Copy link
Member

onbjerg commented Apr 21, 2022

This is more of an ethers-rs issue since that is where we get the provider from. Out of curiosity, what RPC do you use (alchemy, infura etc), and is your internet connection spotty?

For a fix in Forge, we should consider doing what casts does and emit a warning when we think the transaction has been dropped, so the user can check for themselves:

None => return Ok("receipt not found when polling pending tx. was the transaction dropped from the mempool?".to_string())

Also looping in @mattsse, maybe he has some ideas for fixing this in ethers

Edit: Ah, I see some of these are cast commands. If cast returns that message, then it basically just means that the node you are talking to has no knowledge of the transaction. This can happen if the node is out of sync, but sometimes it's just because the node has not received the transaction yet.

We should make the ContractError::ContractNotDeployed variant a bit more robust - currently, if we think the transaction was dropped from the mempool then we just assume the contract was not deployed, which might not be the case

@onbjerg onbjerg added good first issue Good for newcomers C-forge Command: forge P-normal Priority: normal D-easy Difficulty: easy Cmd-forge-create Command: forge create labels Apr 21, 2022
@mattsse
Copy link
Member

mattsse commented Apr 22, 2022

yeh this mempool related,
the core problem is that PendingTransaction can't distinguish between a tx that's temporarily unavailable or actually dropped from the mempool, depending on the node you're connecting to. But I think we made some improvements on that front some time ago, but rinkeby was always not really reliable

this is rather an issue in ether's PendingTransaction impl I believe

cc @prestwich

@prestwich
Copy link
Contributor

yeah, I'm somewhat at a loss as to how to improve it. Maybe a grace period of n attempts before it assumes the tx was dropped?

@holma91
Copy link
Author

holma91 commented Apr 23, 2022

This is more of an ethers-rs issue since that is where we get the provider from. Out of curiosity, what RPC do you use (alchemy, infura etc), and is your internet connection spotty?

For a fix in Forge, we should consider doing what casts does and emit a warning when we think the transaction has been dropped, so the user can check for themselves:

None => return Ok("receipt not found when polling pending tx. was the transaction dropped from the mempool?".to_string())

Also looping in @mattsse, maybe he has some ideas for fixing this in ethers

Edit: Ah, I see some of these are cast commands. If cast returns that message, then it basically just means that the node you are talking to has no knowledge of the transaction. This can happen if the node is out of sync, but sometimes it's just because the node has not received the transaction yet.

We should make the ContractError::ContractNotDeployed variant a bit more robust - currently, if we think the transaction was dropped from the mempool then we just assume the contract was not deployed, which might not be the case

good internet connection, and have tested with different rpcs (alchemy, infura and quicknode) with the same results. Mainly on rinkeby!

@prestwich
Copy link
Contributor

@mattsse @onbjerg I'm doing some research. ethers.js uses this code to wait for a transaction

https://github.com/ethers-io/ethers.js/blob/bc400c7b87b03438abb2f9874ec136dbf7b6437c/packages/providers/src.ts/base-provider.ts#L1273-L1405

I'm traveling and it might take me a bit to parse the promise spaghetti. Generally the flow of the logic looks to be scanning each incoming block for the tx or its replacement. which is just... great 😅

@mattsse
Copy link
Member

mattsse commented Apr 23, 2022

-.-
that's one way to do it, they also check for replacements.

Maybe a grace period of n attempts before it assumes the tx was dropped?

that's probably an easier fix for us, maybe with a retry counter or something

@prestwich
Copy link
Contributor

could do something like a loop querying get_transaction_count for both latest and pending? compare those numbers to see if any txns have confirmed with the expected nonce?

@onbjerg
Copy link
Member

onbjerg commented Apr 23, 2022

I think a grace period makes more sense. FWIW I've heard of multiple people having this issue on some testnets, in particular Rinkeby, so perhaps it's just a Rinkeby thing

@onbjerg
Copy link
Member

onbjerg commented Jul 1, 2022

This should have been fixed in gakonst/ethers-rs#1221, let us know if it is not!

@onbjerg onbjerg closed this as completed Jul 1, 2022
Repository owner moved this from Todo to Done in Foundry Jul 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-forge Command: forge Cmd-forge-create Command: forge create D-easy Difficulty: easy good first issue Good for newcomers P-normal Priority: normal T-bug Type: bug
Projects
Archived in project
Development

No branches or pull requests

4 participants