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

ipc-cli: on transaction/call failure, print out the revert reason and attempt to match it against known ABI errors #944

Open
maciejwitowski opened this issue May 22, 2024 · 1 comment
Labels

Comments

@maciejwitowski
Copy link
Contributor

From @raulk

I would approach it this way:
First, I would focus on printing the JSON-RPC error as it comes through.
Right now we're swalling the JSON-RPC error string, and just printing "Contract call reverted with data". Instead, if we dump the error string the user would see the same thing that cast prints out [1].

Whatever you do here must be deep enough that it automatically applies to all JSON-RPC calls we make.

This would be a first PR.
Next, I would attempt to extract the revert reason from the error string and match it against all ABIs we have.
Unfortunately, the errors are split across a number of contract bindings.

For example, errors for the GatewayManagerFacet are in this generated file: ipc/contracts/binding/src/gateway_manager_facet.rs:754, under enum GatewayManagerFacetErrors.

You can use the decode() method to decode from bytes into a higher type.

It's extremely impractical to check against all error structs of all contracts, so I think this will require some codegen logic in ipc/contracts/binding/build.rs + some macros.

I think this is too complex (especially because you're only getting started with the Rust side of things) and it'll probably be a timesink at the moment.

Let's punt it to later.

[1]:

⟩ cast call 0x6d25fbfac9e6215e03c687e54f7c74f489949eaf 0x0517e1aa000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000004563918244f40000000000000000000000000000000000000000000000000000000000000004cb2f0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000011877f702a73aa7c5c9391aeb450f3c69ea4db7c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000014021cff4f552a9a57bb040b723b53aa257f9b231a000000000000000000000000 --rpc-url https://api.calibration.node.glif.io --from 0xbe492100ab71e51e99a80ae5adc0e00f7e2e256c
Error:
(code: 1, message: message execution failed: exit 33, revert reason: 0xe991abd0, vm error: message failed with backtrace:
00: f088265 (method 3844450837) -- contract reverted (33)
01: f088265 (method 6) -- contract reverted (33)
 (RetCode=33), data: None)
@maciejwitowski
Copy link
Contributor Author

maciejwitowski commented May 22, 2024

Notes from @snissn

Part One

According to this open ticket on the javascript (not rust) ethers repo there is a long standing issue wth error messages not properly propagating: ethers-io/ethers.js#2849

I've sanity checked that the rust ethers ipc code is doing a reasonable job at using the ethers library to reproduce error messages. Here is a code snippet I added to the subnet join command that still only prints out Simulation failed, transaction would fail with error: Revert(Bytes(0x))

let result = txn.call().await;
match result {
        Ok(response) => {
                println!("Simulation succeeded, transaction would succeed with output: {:?}", response);
        },
        Err(e) => {
                println!("Simulation failed, transaction would fail with error: {:?}", e);
        }
}

ethers rust has a deprecation warning that indicates to use alloy or foundry: gakonst/ethers-rs#2667

Part Two
When we call

ipc-cli subnet join --subnet /r314159/t410f3kfub4nv2n6ixbwo37t523upt77l4ezy2altnpy  --collateral 1 --public-key b210a01080a99b57fb3ce1a9c028de45aa5685e8 

and there is a transaction failure the ethers-rs error handling library ends up losing track of the error message when it calls error.into() in this line:

https://github.com/gakonst/ethers-rs/blob/0644a651fa9d099a39269195b2572a049c65f190/ethers-providers/src/rpc/transports/http.rs#L101C1-L101C75

if i make the following diff on the line that loses the error message I correctly get the error message we are expecting:

-            Ok(Response::Error { error, .. }) => return Err(error.into()),
+            Ok(Response::Error { error, .. }) =>{
+                return Err(ClientError::SerdeJson {
+                    err: serde::de::Error::custom("provider error"),
+                    text: error.to_string()
+                })
+            } 

outputs the following:

[2024-05-02T23:51:38Z ERROR ipc_cli] main process failed: error processing command Some(Subnet(SubnetCommandsArgs { 
    command: Join(
        JoinSubnetArgs { 
            from: None, 
            subnet: "/r314159/t410f3kfub4nv2n6ixbwo37t523upt77l4ezy2altnpy", 
            collateral: 1.0, 
            public_key: "b210a01080a99b57fb3ce1a9c028de45aa5685e8", 
            initial_balance: None 
        }
    ) 
})): Failed to send transaction: MiddlewareError { 
    e: MiddlewareError(
        JsonRpcClientError(
            SerdeJson { 
                err: Error("provider error", line: 0, column: 0), 
                text: "(code: 1, message: failed to estimate gas: message execution failed: exit 33, revert reason: 0x015538b1000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000324d6574686f64206e6f7420616c6c6f7765642069662076616c696461746f722068617320616c7265616479206a6c77656420696e206d657373616765206661696c65642077697468206261636b74726163653a5c6e30303a20666d7468657265642077697468206261636b74726163653a5c6e30303a5c6e20696e206865786564203333290a30303a20663130313534353720286d6574686f64203338343434353038333729202d2d20636f6e747261637420726576657274656420283333290a2028292c20766d206572726f723a206d657373616765206661696c65642077697468206261636b74726163653a5c6e30303a2920290a", 
                vm error: message failed with backtrace:\n00: f0105457 (method 3844450837) -- contract reverted (33)\n01: f0105457 (method 6) -- contract reverted (33)\n (RetCode=33), data: None)" 
            }
        )
    ) 
}

@raulk raulk added the cli label May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Backlog
Development

No branches or pull requests

2 participants