-
Notifications
You must be signed in to change notification settings - Fork 122
/
wire.go
185 lines (157 loc) · 5.76 KB
/
wire.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package types
import (
"fmt"
errorsmod "cosmossdk.io/errors"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
abci "github.com/cometbft/cometbft/abci/types"
)
func NewValidatorSetChangePacketData(valUpdates []abci.ValidatorUpdate, valUpdateID uint64, slashAcks []string) ValidatorSetChangePacketData {
return ValidatorSetChangePacketData{
ValidatorUpdates: valUpdates,
ValsetUpdateId: valUpdateID,
SlashAcks: slashAcks,
}
}
// ValidateBasic is used for validating the CCV packet data.
func (vsc ValidatorSetChangePacketData) ValidateBasic() error {
if len(vsc.ValidatorUpdates) == 0 {
return errorsmod.Wrap(ErrInvalidPacketData, "validator updates cannot be empty")
}
if vsc.ValsetUpdateId == 0 {
return errorsmod.Wrap(ErrInvalidPacketData, "valset update id cannot be equal to zero")
}
return nil
}
// GetBytes marshals the ValidatorSetChangePacketData into JSON string bytes
// to be sent over the wire with IBC.
func (vsc ValidatorSetChangePacketData) GetBytes() []byte {
valUpdateBytes := ModuleCdc.MustMarshalJSON(&vsc)
return valUpdateBytes
}
func NewVSCMaturedPacketData(valUpdateID uint64) *VSCMaturedPacketData {
return &VSCMaturedPacketData{
ValsetUpdateId: valUpdateID,
}
}
// ValidateBasic is used for validating the VSCMatured packet data.
func (mat VSCMaturedPacketData) ValidateBasic() error {
if mat.ValsetUpdateId == 0 {
return errorsmod.Wrap(ErrInvalidPacketData, "vscId cannot be equal to zero")
}
return nil
}
func NewSlashPacketData(validator abci.Validator, valUpdateId uint64, infractionType stakingtypes.Infraction) *SlashPacketData {
return &SlashPacketData{
Validator: validator,
ValsetUpdateId: valUpdateId,
Infraction: infractionType,
}
}
// NewSlashPacketDataV1 creates a new SlashPacketDataV1 that uses ccv.InfractionTypes to maintain backward compatibility.
func NewSlashPacketDataV1(validator abci.Validator, valUpdateId uint64, infractionType stakingtypes.Infraction) *SlashPacketDataV1 {
v1Type := InfractionEmpty
switch infractionType {
case stakingtypes.Infraction_INFRACTION_DOWNTIME:
v1Type = Downtime
case stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN:
v1Type = DoubleSign
}
return &SlashPacketDataV1{
Validator: validator,
ValsetUpdateId: valUpdateId,
Infraction: v1Type,
}
}
func (vdt SlashPacketData) ValidateBasic() error {
if len(vdt.Validator.Address) == 0 || vdt.Validator.Power == 0 {
return errorsmod.Wrap(ErrInvalidPacketData, "validator fields cannot be empty")
}
if vdt.Infraction == stakingtypes.Infraction_INFRACTION_UNSPECIFIED {
return errorsmod.Wrap(ErrInvalidPacketData, "invalid infraction type")
}
return nil
}
func (vdt SlashPacketData) ToV1() *SlashPacketDataV1 {
return NewSlashPacketDataV1(vdt.Validator, vdt.ValsetUpdateId, vdt.Infraction)
}
func (cp ConsumerPacketData) ValidateBasic() (err error) {
switch cp.Type {
case VscMaturedPacket:
// validate VSCMaturedPacket
vscPacket := cp.GetVscMaturedPacketData()
if vscPacket == nil {
return fmt.Errorf("invalid consumer packet data: VscMaturePacketData data cannot be empty")
}
err = vscPacket.ValidateBasic()
case SlashPacket:
// validate SlashPacket
slashPacket := cp.GetSlashPacketData()
if slashPacket == nil {
return fmt.Errorf("invalid consumer packet data: SlashPacketData data cannot be empty")
}
err = slashPacket.ValidateBasic()
default:
err = fmt.Errorf("invalid consumer packet type: %q", cp.Type)
}
return
}
// Convert to bytes while maintaining over the wire compatibility with previous versions.
func (cp ConsumerPacketData) GetBytes() []byte {
return cp.ToV1Bytes()
}
// ToV1Bytes converts the ConsumerPacketData to JSON byte array compatible
// with the format used by ICS versions using cosmos-sdk v45 (ICS v1 and ICS v2).
func (cp ConsumerPacketData) ToV1Bytes() []byte {
if cp.Type != SlashPacket {
bytes := ModuleCdc.MustMarshalJSON(&cp)
return bytes
}
sp := cp.GetSlashPacketData()
spdv1 := NewSlashPacketDataV1(sp.Validator, sp.ValsetUpdateId, sp.Infraction)
cpv1 := ConsumerPacketDataV1{
Type: cp.Type,
Data: &ConsumerPacketDataV1_SlashPacketData{
SlashPacketData: spdv1,
},
}
bytes := ModuleCdc.MustMarshalJSON(&cpv1)
return bytes
}
// FromV1 converts SlashPacketDataV1 to SlashPacketData.
// Provider must handle both V1 and later versions of the SlashPacketData.
func (vdt1 SlashPacketDataV1) FromV1() *SlashPacketData {
newType := stakingtypes.Infraction_INFRACTION_UNSPECIFIED
switch vdt1.Infraction {
case Downtime:
newType = stakingtypes.Infraction_INFRACTION_DOWNTIME
case DoubleSign:
newType = stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN
}
return &SlashPacketData{
Validator: vdt1.Validator,
ValsetUpdateId: vdt1.ValsetUpdateId,
Infraction: newType,
}
}
type PacketAckResult []byte
var ( // slice types can't be const
// The result ack that has historically been sent from the provider.
// A provider with v1 throttling sends these acks for all successfully recv packets.
V1Result = PacketAckResult([]byte{byte(1)})
// Slash packet handled result ack, sent by a throttling v2 provider to indicate that a slash packet was handled.
SlashPacketHandledResult = PacketAckResult([]byte{byte(2)})
// Slash packet bounced result ack, sent by a throttling v2 provider to indicate that a slash packet was NOT handled
// and should eventually be retried.
SlashPacketBouncedResult = PacketAckResult([]byte{byte(3)})
)
// An exported wrapper around the auto generated isConsumerPacketData_Data interface, only for
// AppendPendingPacket to accept the interface as an argument.
type ExportedIsConsumerPacketData_Data interface {
isConsumerPacketData_Data
}
func NewConsumerPacketData(cpdType ConsumerPacketDataType, data isConsumerPacketData_Data) ConsumerPacketData {
return ConsumerPacketData{
Type: cpdType,
Data: data,
}
}