Closed aeryz closed 3 months ago
Which version of wasmd and wasmvm do you use? Optional acks are a feature only supported in CosmWasm 2 chains.
In general this is a two step process:
// You can edit this code!
// Click here and start typing.
package main
import "fmt"
type Ack interface {
Value() []byte
}
type ContractAck []byte
var _ Ack = ContractAck{}
func (ack ContractAck) Value() []byte {
return ack
}
func main() {
var x []byte
y := ContractAck(x)
var z Ack
z = y
var b Ack
b = nil
var c Ack
c = ContractAck(nil)
if x == nil {
fmt.Println("nil x")
}
if y == nil {
fmt.Println("nil y")
}
if z == nil {
fmt.Println("nil z")
}
if z.Value() == nil {
fmt.Println("nil z.value")
}
if b == nil {
fmt.Println("nil b")
} else if b.Value() == nil {
fmt.Println("nil b.value")
}
if c == nil {
fmt.Println("nil c")
} else if c.Value() == nil {
fmt.Println("nil c.value")
}
}
nil x
nil y
nil z.value
nil b
nil c.value
WTF – so there is a Go type system bug in wasmd?
We had it working by changing the ibc-go code to this:
// Set packet acknowledgement only if the acknowledgement is not nil.
// NOTE: IBC applications modules may call the WriteAcknowledgement asynchronously if the
// acknowledgement is nil.
if ack != nil && ack.Acknowledgement() != nil {
if err := k.ChannelKeeper.WriteAcknowledgement(ctx, capability, msg.Packet, ack); err != nil {
return nil, err
}
}
So it seems like although the wrapped bytes is nil, the interface is not nil
So, the issue is that interfaces in Go are a bit weird:
Hence, there is an implicit newtype wrapping (extra pointer indirection) when casting, even if the value you cast is nil (so the value isn't directly used as the interface, but a new pointer is created)
I think I already stumbled upon this while implementing WriteAcknowledgement for 2.1: https://github.com/CosmWasm/wasmd/pull/1876/files#diff-8eeb0bf4af45c3a552b61aed85469953f39a51bb5a534c0f4d52256bbfce37eb
In the PR, you can see I had to make some changes in OnRecvPacket
to catch this special case.
As this is clearly a bug in wasmd, I am moving it over there
Hello, we are using
IbcReceiveResponse::without_ack
to return anil
ack. But we are hitting this error. Our initial investigation shows us thatnil
ack returns non-nil ack with empty data. That's why we are hitting this error.As far as I understand, this feature is meant to return a
nil
ack and causeWriteAcknowledgement
to be deferred. Is there something that we are missing or is this a bug?