-
Notifications
You must be signed in to change notification settings - Fork 170
/
ibc.go
72 lines (60 loc) · 2.6 KB
/
ibc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package osmoutils
import (
"encoding/json"
transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// NewEmitErrorAcknowledgement creates a new error acknowledgement after having emitted an event with the
// details of the error.
func NewEmitErrorAcknowledgement(ctx sdk.Context, err error, errorContexts ...string) channeltypes.Acknowledgement {
attributes := make([]sdk.Attribute, len(errorContexts)+1)
attributes[0] = sdk.NewAttribute("error", err.Error())
for i, s := range errorContexts {
attributes[i+1] = sdk.NewAttribute("error-context", s)
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
"ibc-acknowledgement-error",
attributes...,
),
})
return channeltypes.NewErrorAcknowledgement(err)
}
// MustExtractDenomFromPacketOnRecv takes a packet with a valid ICS20 token data in the Data field and returns the
// denom as represented in the local chain.
// If the data cannot be unmarshalled this function will panic
func MustExtractDenomFromPacketOnRecv(packet ibcexported.PacketI) string {
var data transfertypes.FungibleTokenPacketData
if err := json.Unmarshal(packet.GetData(), &data); err != nil {
panic("unable to unmarshal ICS20 packet data")
}
var denom string
if transfertypes.ReceiverChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), data.Denom) {
// remove prefix added by sender chain
voucherPrefix := transfertypes.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel())
unprefixedDenom := data.Denom[len(voucherPrefix):]
// coin denomination used in sending from the escrow address
denom = unprefixedDenom
// The denomination used to send the coins is either the native denom or the hash of the path
// if the denomination is not native.
denomTrace := transfertypes.ParseDenomTrace(unprefixedDenom)
if denomTrace.Path != "" {
denom = denomTrace.IBCDenom()
}
} else {
prefixedDenom := transfertypes.GetDenomPrefix(packet.GetDestPort(), packet.GetDestChannel()) + data.Denom
denom = transfertypes.ParseDenomTrace(prefixedDenom).IBCDenom()
}
return denom
}
// IsAckError checks an IBC acknowledgement to see if it's an error.
// This is a replacement for ack.Success() which is currently not working on some circumstances
func IsAckError(acknowledgement []byte) bool {
var ackErr channeltypes.Acknowledgement_Error
if err := json.Unmarshal(acknowledgement, &ackErr); err == nil && len(ackErr.Error) > 0 {
return true
}
return false
}