Skip to content

Commit 4a9cc3e

Browse files
committed
Add docs on Error handling for ibc_packet_receive
1 parent 9a23983 commit 4a9cc3e

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

docs/ERROR_HANDLING.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Error handling for various entry points
2+
3+
In this document we discuss how different types of errors during contract
4+
execution are handled by wasmd and the blockchain.
5+
6+
## Two levels of errors
7+
8+
When cosmwasm-vm executes a contract, the caller receives a nested result type:
9+
`VmResult<ContractResult<R>>` with some success response `R`. The outer
10+
`VmResult` is created by the host environment and the inner `ContractResult` is
11+
created inside of the contract. Most application specific error should go into
12+
`ContractResult` errors. This is what happens when you use `?` inside of your
13+
contract implementations. The `VmResult`
14+
[error cases](https://github.com/CosmWasm/cosmwasm/blob/v1.2.3/packages/vm/src/errors/vm_error.rs#L11-L148)
15+
include e.g.
16+
17+
- Caching errors such as a missing Wasm file or corrupted module
18+
- Serialization problems in the contract-host communication
19+
- Panics from panic handler in contract
20+
- Errors in crypto API calls
21+
- Out of gas
22+
- Unreachable statements in the Wasm bytecode
23+
24+
## Error handling
25+
26+
In wasmvm those two error types are merged into one and handled as one thing in
27+
the caller (wasmd):
28+
29+
- [Instantiate](https://github.com/CosmWasm/wasmvm/blob/v1.2.0/lib.go#L144-L151)
30+
- [Execute](https://github.com/CosmWasm/wasmvm/blob/v1.2.0/lib.go#L192-L199)
31+
- [Migtate](https://github.com/CosmWasm/wasmvm/blob/v1.2.0/lib.go#L275-L282)
32+
- [Sudo](https://github.com/CosmWasm/wasmvm/blob/v1.2.0/lib.go#L318-L325)
33+
- [Reply](https://github.com/CosmWasm/wasmvm/blob/v1.2.0/lib.go#L363-L370)
34+
- [IBCChannelOpen](https://github.com/CosmWasm/wasmvm/blob/v1.2.0/lib.go#L406-L413)
35+
- [IBCChannelConnect](https://github.com/CosmWasm/wasmvm/blob/v1.2.0/lib.go#L449-L456)
36+
- [IBCChannelClose](https://github.com/CosmWasm/wasmvm/blob/v1.2.0/lib.go#L492-L499)
37+
- [IBCPacketAck](https://github.com/CosmWasm/wasmvm/blob/v1.2.0/lib.go#L576-L583)
38+
- [IBCPacketTimeout](https://github.com/CosmWasm/wasmvm/blob/v1.2.0/lib.go#L620-L627)
39+
40+
However, there is one exception:
41+
42+
- [IBCPacketReceive](https://github.com/CosmWasm/wasmvm/blob/v1.2.0/lib.go#L535-L539)
43+
44+
Instead of returning only the contents of the `Ok` case, the whole
45+
`IBCReceiveResult` is returned. This allows the caller to handle the two layers
46+
of errors differently.
47+
48+
As pointed out by our auditors from Oak Security, this
49+
[is inconsistent](https://github.com/CosmWasm/wasmvm/issues/398). Historically
50+
merging the two error types was the desired behaviour. When `IBCPacketReceive`
51+
came in, we needed the differentiation to be available in wasmd, which is why
52+
the API is different than the others. Ideally we always return the contract
53+
Result and let wasmd handle it.
54+
55+
## Handing ibc_packet_receive errors
56+
57+
For wasmd before 0.32, contract errors and VM errors were handled the same. They
58+
got the special treatment of reverting state changes, writing an error
59+
acknowledgement but don't let the transaction fail.
60+
61+
For wasmd >= 0.32, the special treatment only applies to contract errors. VM
62+
errors in `IBCPacketReceive` let the transaction fail just like the `Execute`
63+
case would. This has two major implications:
64+
65+
1. Application specific errors (especially those which can be triggered by
66+
untrusted users) should create contract errors and no panics. This ensures
67+
that error acknowledgements are written and relayer transactions don't fail.
68+
2. Using panics allow the contract developer to make the transaction fail
69+
without writing an acknowledgement. This can be handy e.g. for allowlisting
70+
relayer addresses.
71+
72+
The following table shows the new handling logic.
73+
74+
| Entry point | Contract error | VM error |
75+
| --------------------- | --------------------------------------------- | --------------------------------------------- |
76+
| `instantiate` | ⏮️ state reverted<br>❌ tx fails | ⏮️ state reverted<br>❌ tx fails |
77+
| `execute` | ⏮️ state reverted<br>❌ tx fails | ⏮️ state reverted<br>❌ tx fails |
78+
| `migrate` | ⏮️ state reverted<br>❌ tx fails | ⏮️ state reverted<br>❌ tx fails |
79+
| `sudo` | ⏮️ state reverted<br>❌ tx fails | ⏮️ state reverted<br>❌ tx fails |
80+
| `reply` | ⏮️ state reverted<br>❔ depends on `reply_on` | ⏮️ state reverted<br>❔ depends on `reply_on` |
81+
| `ibc_channel_open` | ⏮️ state reverted<br>❌ tx fails | ⏮️ state reverted<br>❌ tx fails |
82+
| `ibc_channel_connect` | ⏮️ state reverted<br>❌ tx fails | ⏮️ state reverted<br>❌ tx fails |
83+
| `ibc_channel_close` | ⏮️ state reverted<br>❌ tx fails | ⏮️ state reverted<br>❌ tx fails |
84+
| `ibc_packet_receive` | ⏮️ state reverted<br>✅ tx succeeds | ⏮️ state reverted<br>❌ tx fails |
85+
| `ibc_packet_ack` | ⏮️ state reverted<br>❌ tx fails | ⏮️ state reverted<br>❌ tx fails |
86+
| `ibc_packet_timeout` | ⏮️ state reverted<br>❌ tx fails | ⏮️ state reverted<br>❌ tx fails |

0 commit comments

Comments
 (0)