@@ -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