-
Notifications
You must be signed in to change notification settings - Fork 17
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
Add support for parsing custom errors & fixing revert error propagation #42
Conversation
Signed-off-by: Jim Zhang <[email protected]>
Signed-off-by: Jim Zhang <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One request for clarification on the estimate-gas flow and testing @jimthematrix
internal/ethereum/exec_query.go
Outdated
idBytes := e.FunctionSelectorBytes() | ||
if bytes.Equal(signature, idBytes) { | ||
errorInfo, err := e.DecodeCallDataCtx(ctx, outputData) | ||
if err == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we've got too deep nesting here - could we split out this section for formatting the error for a given match into a separate function?
// Build the base transaction object | ||
tx, err := c.buildTx(ctx, txTypeQuery, req.From, req.To, req.Nonce, req.Gas, req.Value, callData) | ||
if err != nil { | ||
return nil, ffcapi.ErrorReasonInvalidInputs, err | ||
} | ||
|
||
// Do the call, with processing of revert reasons | ||
outputs, reason, err := c.callTransaction(ctx, tx, method) | ||
outputs, reason, err := c.callTransaction(ctx, tx, method, errors) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think it's really important to make sure this gets called for the estimate gas path - wasn't immediately obvious to me that it is.
We should test this for both the send-transaction, and the deploy-contract, flows to make sure the error comes out successfully against Geth 1.10 and Besu if that's ok.
Signed-off-by: Jim Zhang <[email protected]>
Signed-off-by: Jim Zhang <[email protected]>
Test with Geth 1.10Geth 1.10 returns the error details in the Deploy contract
Resultfor
for
for
Send transaction
Result:for
for
for
|
Test with Besu v22.7.5besu returns the error details in the eth_estimateGas response. Deploy contractfor
for
Send transactionfor
for
using transaction payload without the
|
Signed-off-by: Jim Zhang <[email protected]>
go.mod
Outdated
github.com/hyperledger/firefly-transaction-manager v1.1.2 | ||
github.com/sirupsen/logrus v1.8.1 | ||
github.com/hyperledger/firefly-common v1.1.4 | ||
github.com/hyperledger/firefly-signer v1.1.3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
internal/ethereum/exec_query.go
Outdated
} | ||
} | ||
} | ||
return outputData.String(), fmt.Errorf("raw data returned") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't have any fmt.Errorf()
- instead adding to the translated error file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a "transient" error as it simply signals to the caller that the string was going to be the raw data, then it gets thrown away. as such it doesn't need to be translated. but if the coding style requires translation, I'd be happy to add it. please let me know.
Details are in the comment of the method processRevertReason()
:
// processRevertReason returns under 3 different circumstances:
// 1. non-empty string with nil error: valid reason has been successfully parsed
// 2. non-empty string with non-nil error: error detail was present but failed to parse, string was raw data
// 3. empty string with nil error: outputData is NOT an error detail data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A sentinel error would be a better pattern than a string constant, if you wouldn't mind.
Or simply a boolean ok
return would be clearer in the case there's not an error for the caller to process, simply an indication that the data couldn't be extracted?
I would like us to have a linter that checks for Errorf
anywhere in the code at some point.
Also reading the code caught me out because above err != nil
didn't mean there was an error to process, but instead it meant that the function didn't complete its task.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for suggesting that. went with the boolean return value pattern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great, thanks for working through the 1.10 change too.
Couple of very simple requests (along with pulling the new dependency releases in) before merg.
Signed-off-by: Jim Zhang <[email protected]>
Signed-off-by: Jim Zhang <[email protected]>
Signed-off-by: Jim Zhang <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @jimthematrix 🙇
Thanks @jimthematrix. With this, callers will be able to distinguish custom errors from regular reverts, but they'll have to parse the error string for details. It would be nice if the error signature, error name, and param values could be provided as separate fields in the result so that the client can dispatch according to which error was thrown without having to parse. |
Depends on:
This allows the transaction payload to include an optional
errors
section that specifies the FFI for custom error definitions:for a test solidity contract that declares custom errors like the following :
fixes #41