Search Apps Documentation Source Content File Folder Download Copy Actions Download

msgs.gno

4.30 Kb · 175 lines
  1package types
  2
  3import (
  4	"crypto/sha256"
  5	"encoding/base64"
  6	"errors"
  7
  8	"gno.land/p/aib/ibc/host"
  9	"gno.land/p/aib/ics23"
 10	"gno.land/p/nt/ufmt/v0"
 11	"gno.land/p/onbloc/json"
 12)
 13
 14// MsgSendPacket sends an outgoing IBC packet.
 15type MsgSendPacket struct {
 16	SourceClient string
 17	// TimeoutTimestamp holds the seconds after which the packet times out.
 18	TimeoutTimestamp uint64
 19	Payloads         []Payload
 20}
 21
 22// NewMsgSendPacket creates a new MsgSendPacket instance.
 23func NewMsgSendPacket(sourceClient string, timeoutTimestamp uint64, payloads ...Payload) *MsgSendPacket {
 24	return &MsgSendPacket{
 25		SourceClient:     sourceClient,
 26		TimeoutTimestamp: timeoutTimestamp,
 27		Payloads:         payloads,
 28	}
 29}
 30
 31// ValidateBasic performs basic checks on a MsgSendPacket.
 32func (msg *MsgSendPacket) ValidateBasic() error {
 33	if err := host.ClientIdentifierValidator(msg.SourceClient); err != nil {
 34		return err
 35	}
 36
 37	if msg.TimeoutTimestamp == 0 {
 38		return ufmt.Errorf("timeout must not be 0")
 39	}
 40
 41	if len(msg.Payloads) == 0 {
 42		return ufmt.Errorf("payload length must be greater than 0")
 43	}
 44
 45	for i, pd := range msg.Payloads {
 46		if err := pd.ValidateBasic(); err != nil {
 47			return ufmt.Errorf("invalid payload #%d: %v", i, err)
 48		}
 49	}
 50	return nil
 51}
 52
 53// MsgRecvPacket receives an incoming IBC packet.
 54type MsgRecvPacket struct {
 55	Packet          Packet
 56	ProofCommitment []ics23.CommitmentProof
 57	ProofHeight     Height
 58}
 59
 60// ValidateBasic performs basic checks on a MsgRecvPacket.
 61func (msg *MsgRecvPacket) ValidateBasic() error {
 62	if len(msg.ProofCommitment) == 0 {
 63		return ufmt.Errorf("proof commitment can not be empty")
 64	}
 65	return msg.Packet.ValidateBasic()
 66}
 67
 68// MsgAcknowledgement receives incoming IBC acknowledgement.
 69type MsgAcknowledgement struct {
 70	Packet          Packet
 71	Acknowledgement Acknowledgement
 72	ProofAcked      []ics23.CommitmentProof
 73	ProofHeight     Height
 74}
 75
 76// ValidateBasic performs basic checks on a MsgAcknowledgement.
 77func (msg *MsgAcknowledgement) ValidateBasic() error {
 78	if len(msg.ProofAcked) == 0 {
 79		return errors.New("cannot submit an empty acknowledgement proof")
 80	}
 81	for i, proof := range msg.ProofAcked {
 82		if proof.GetExist() == nil {
 83			return ufmt.Errorf("invalid commitment proof #%d: proof.GetExists() is nil", i)
 84		}
 85	}
 86
 87	if err := msg.Acknowledgement.Validate(); err != nil {
 88		return err
 89	}
 90
 91	return msg.Packet.ValidateBasic()
 92}
 93
 94func UniversalErrorAcknowledgement() []byte {
 95	bz := sha256.Sum256([]byte("UNIVERSAL_ERROR_ACKNOWLEDGEMENT"))
 96	return bz[:]
 97}
 98
 99// AppAcknowledgement is the recommended acknowledgement format to be used by
100// app-specific protocols.
101type AppAcknowledgement struct {
102	Response AppAcknowledgementResponse
103}
104
105type AppAcknowledgementResponse struct {
106	Result []byte
107	Error  string
108}
109
110func NewErrorAppAcknowledgement(err error) AppAcknowledgement {
111	return AppAcknowledgement{Response: AppAcknowledgementResponse{Error: err.Error()}}
112}
113
114func NewResultAppAcknowledgement(result []byte) AppAcknowledgement {
115	return AppAcknowledgement{
116		Response: AppAcknowledgementResponse{
117			Result: result,
118		},
119	}
120}
121
122func (a AppAcknowledgement) Success() bool {
123	return a.Response.Error == ""
124}
125
126func (a *AppAcknowledgement) MarshalJSON() []byte {
127	var node *json.Node
128	if a.Response.Error != "" {
129		node = json.ObjectNode("", map[string]*json.Node{
130			"error": json.StringNode("", a.Response.Error),
131		})
132	} else {
133		node = json.ObjectNode("", map[string]*json.Node{
134			"result": json.StringNode("", base64.StdEncoding.EncodeToString(a.Response.Result)),
135		})
136	}
137	bz, _ := json.Marshal(node)
138	return bz
139}
140
141func (a *AppAcknowledgement) UnmarshalJSON(bz []byte) error {
142	root, err := json.Unmarshal(bz)
143	if err != nil {
144		return err
145	}
146	result, err := root.GetKey("result")
147	if err != nil {
148		rerror, err := root.GetKey("error")
149		if err != nil {
150			return err
151		}
152		a.Response = AppAcknowledgementResponse{Error: rerror.MustString()}
153		return nil
154	}
155	resBz, err := base64.StdEncoding.DecodeString(result.MustString())
156	if err != nil {
157		return err
158	}
159	a.Response = AppAcknowledgementResponse{Result: resBz}
160	return nil
161}
162
163// MsgTimeout receives timed-out packet
164type MsgTimeout struct {
165	Packet          Packet
166	ProofUnreceived []ics23.CommitmentProof
167	ProofHeight     Height
168}
169
170func (msg *MsgTimeout) ValidateBasic() error {
171	if len(msg.ProofUnreceived) == 0 {
172		return errors.New("cannot submit an empty timeout proof")
173	}
174	return msg.Packet.ValidateBasic()
175}