-
Notifications
You must be signed in to change notification settings - Fork 111
/
utils.go
107 lines (92 loc) · 3.15 KB
/
utils.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package types
import (
"reflect"
"sort"
"time"
errorsmod "cosmossdk.io/errors"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
host "github.com/cosmos/ibc-go/v4/modules/core/24-host"
abci "github.com/tendermint/tendermint/abci/types"
tmprotocrypto "github.com/tendermint/tendermint/proto/tendermint/crypto"
)
func AccumulateChanges(currentChanges, newChanges []abci.ValidatorUpdate) []abci.ValidatorUpdate {
m := make(map[string]abci.ValidatorUpdate)
for i := 0; i < len(currentChanges); i++ {
m[currentChanges[i].PubKey.String()] = currentChanges[i]
}
for i := 0; i < len(newChanges); i++ {
m[newChanges[i].PubKey.String()] = newChanges[i]
}
var out []abci.ValidatorUpdate
for _, update := range m {
out = append(out, update)
}
// The list of tendermint updates should hash the same across all consensus nodes
// that means it is necessary to sort for determinism.
sort.Slice(out, func(i, j int) bool {
if out[i].Power != out[j].Power {
return out[i].Power > out[j].Power
}
return out[i].PubKey.String() > out[j].PubKey.String()
})
return out
}
// TMCryptoPublicKeyToConsAddr converts a TM public key to an SDK public key
// and returns the associated consensus address
func TMCryptoPublicKeyToConsAddr(k tmprotocrypto.PublicKey) (sdk.ConsAddress, error) {
sdkK, err := cryptocodec.FromTmProtoPublicKey(k)
if err != nil {
return nil, err
}
return sdk.GetConsAddress(sdkK), nil
}
// SendIBCPacket sends an IBC packet with packetData
// over the source channelID and portID
func SendIBCPacket(
ctx sdk.Context,
scopedKeeper ScopedKeeper,
channelKeeper ChannelKeeper,
channelID string,
portID string,
packetData []byte,
timeoutPeriod time.Duration,
) error {
channel, ok := channelKeeper.GetChannel(ctx, portID, channelID)
if !ok {
return errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "channel not found for channel ID: %s", channelID)
}
channelCap, ok := scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(portID, channelID))
if !ok {
return errorsmod.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability")
}
// get the next sequence
sequence, found := channelKeeper.GetNextSequenceSend(ctx, portID, channelID)
if !found {
return errorsmod.Wrapf(
channeltypes.ErrSequenceSendNotFound,
"source port: %s, source channel: %s", portID, channelID,
)
}
packet := channeltypes.NewPacket(
packetData, sequence,
portID, channelID,
channel.Counterparty.PortId, channel.Counterparty.ChannelId,
clienttypes.Height{}, uint64(ctx.BlockTime().Add(timeoutPeriod).UnixNano()),
)
return channelKeeper.SendPacket(ctx, channelCap, packet)
}
// AppendMany appends a variable number of byte slices together
func AppendMany(byteses ...[]byte) (out []byte) {
for _, bytes := range byteses {
out = append(out, bytes...)
}
return out
}
func PanicIfZeroOrNil(x interface{}, nameForPanicMsg string) {
if x == nil || reflect.ValueOf(x).IsZero() {
panic("zero or nil value for " + nameForPanicMsg)
}
}