Skip to content

Commit 89f20e2

Browse files
committed
Add section on Error acknowledgement formatting
1 parent fc80b08 commit 89f20e2

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

docs/ERROR_HANDLING.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,48 @@ The following table shows the new handling logic.
8484
| `ibc_packet_receive` | ⏮️ state reverted<br>✅ tx succeeds with error ack | ⏮️ state reverted<br>❌ tx fails |
8585
| `ibc_packet_ack` | ⏮️ state reverted<br>❌ tx fails | ⏮️ state reverted<br>❌ tx fails |
8686
| `ibc_packet_timeout` | ⏮️ state reverted<br>❌ tx fails | ⏮️ state reverted<br>❌ tx fails |
87+
88+
## Error acknowledgement formatting
89+
90+
In case of a contract error in `ibc_packet_receive`, wasmd creates an error
91+
acknowledgement. The format used is a JSON object with a single top level
92+
`error` string such as `{"error":"some error text"}`. This format is the JSON
93+
serialization of the ibc-go
94+
[Acknowledgement](https://github.com/cosmos/ibc-go/blob/v7.0.0/proto/ibc/core/channel/v1/channel.proto#L156-L162)
95+
type and compatible with ICS-20.
96+
97+
If you are using the acknowledgement types shipped with cosmwasm-std
98+
([#1512](https://github.com/CosmWasm/cosmwasm/issues/1512)), your protocol's
99+
acknowledgement is compatible with that.
100+
101+
If you are using a customized acknowledgement type, you need to convert contract
102+
errors to error acks yourself in `ibc_packet_receive`. The `Never` type provides
103+
type-safety for that. See:
104+
105+
```rust
106+
// The error type Never ensures you handle all contract errors inside the function body
107+
pub fn ibc_packet_receive(
108+
deps: DepsMut,
109+
_env: Env,
110+
msg: IbcPacketReceiveMsg,
111+
) -> Result<IbcReceiveResponse, Never> {
112+
// put this in a closure so we can convert all error responses into acknowledgements
113+
(|| {
114+
let packet = msg.packet;
115+
let caller = packet.dest.channel_id;
116+
let msg: PacketMsg = from_slice(&packet.data)?;
117+
match msg {
118+
// Some packet receive implementations which return results
119+
PacketMsg::Dispatch { msgs } => receive_dispatch(deps, caller, msgs),
120+
PacketMsg::WhoAmI {} => receive_who_am_i(deps, caller),
121+
PacketMsg::Balances {} => receive_balances(deps, caller),
122+
}
123+
})()
124+
.or_else(|e| {
125+
// Here we encode the error to our own fancy ack type
126+
let acknowledgement: Binary = make_my_ack(e);
127+
Ok(IbcReceiveResponse::new()
128+
.set_ack(acknowledgement))
129+
})
130+
}
131+
```

0 commit comments

Comments
 (0)