Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 docs on Error handling for ibc_packet_receive #1646
Add docs on Error handling for ibc_packet_receive #1646
Changes from all commits
4a9cc3e
fc80b08
89f20e2
85dc17e
0508f1c
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
Error handling for various entry points
In this document we discuss how different types of errors during contract execution are handled by wasmd and the blockchain.
Two levels of errors
When cosmwasm-vm executes a contract, the caller receives a nested result type:
VmResult<ContractResult<R>>
with some success responseR
. The outerVmResult
is created by the host environment and the innerContractResult
is created inside of the contract. Most application specific error should go intoContractResult
errors. This is what happens when you use?
inside of your contract implementations. TheVmResult
error cases include e.g.Error handling
Before version 2.0 those two error types were merged into one in wasmvm and handled as one thing in the caller (wasmd). See for example Instantiate. However, there was one exception to this: IBCPacketReceive. Instead of returning only the contents of the
Ok
case, the wholeIBCReceiveResult
is returned. This allows the caller to handle the two layers of errors differently.As pointed out by our auditors from Oak Security, this was inconsistent. Historically merging the two error types was the desired behaviour. When
IBCPacketReceive
came in, we needed the differentiation to be available in wasmd, which is why the API was different than the others.In wasmvm >= 2.0 (wasmd >= 0.51), we always return the contract result and let wasmd handle it. Apart from making everything more consistent, this also allows wasmd to handle contract errors differently from VM errors.
Most errors returned by sub-messages are redacted by wasmd before passing them back into the contract. The reason for this is the possible non-determinism of error messages. However, as contract errors come from the contract, they have to be deterministic. With the new separation, wasmd now passes the full contract error message back into the calling contract, massively improving the debugging experience.
Handing ibc_packet_receive errors
From wasmd 0.22 to 0.31 (inclusive), contract errors and VM errors were handled the same. They got the special treatment of reverting state changes, writing an error acknowledgement but don't let the transaction fail.
For wasmd >= 0.32, the special treatment only applies to contract errors. VM errors in
IBCPacketReceive
let the transaction fail just like theExecute
case would. This has two major implications:The following table shows the new handling logic.
instantiate
❌ tx fails
❌ tx fails
execute
❌ tx fails
❌ tx fails
migrate
❌ tx fails
❌ tx fails
sudo
❌ tx fails
❌ tx fails
reply
❔ depends on
reply_on
❔ depends on
reply_on
ibc_channel_open
❌ tx fails
❌ tx fails
ibc_channel_connect
❌ tx fails
❌ tx fails
ibc_channel_close
❌ tx fails
❌ tx fails
ibc_packet_receive
✅ tx succeeds with error ack
❌ tx fails
ibc_packet_ack
❌ tx fails
❌ tx fails
ibc_packet_timeout
❌ tx fails
❌ tx fails
Error acknowledgement formatting
In case of a contract error in
ibc_packet_receive
, wasmd creates an error acknowledgement. The format used is a JSON object with a single top levelerror
string such as{"error":"some error text"}
. This format is the JSON serialization of the ibc-go Acknowledgement type and compatible with ICS-20.If you are using the acknowledgement types shipped with cosmwasm-std (#1512), your protocol's acknowledgement is compatible with that.
If you are using a customized acknowledgement type, you need to convert contract errors to error acks yourself in
ibc_packet_receive
. TheNever
type provides type-safety for that. See: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 don't fully understand how the
StdAck
is handled downstream. It is important to consider the state commit/rollback for "errors" scenario 2 and 3Scenario 3:
If the "error" is returned to wasmd as IBCReceiveResult.Err, then the state is rolled back and the error text redacted (currently) and serialized into the json format above.
Scenario 2:
If the "error" is returned to wasmd as IBCReceiveResult.Ok.Acknowledgement then the data is returned as it is with the state committed. I assume
StdAck
is doing this but I may got it wrong