@@ -84,3 +84,48 @@ The following table shows the new handling logic.
84
84
| ` ibc_packet_receive ` | ⏮️ state reverted<br >✅ tx succeeds with error ack | ⏮️ state reverted<br >❌ tx fails |
85
85
| ` ibc_packet_ack ` | ⏮️ state reverted<br >❌ tx fails | ⏮️ state reverted<br >❌ tx fails |
86
86
| ` 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