Skip to content

Commit

Permalink
fix: use v1 slash types on consumer side
Browse files Browse the repository at this point in the history
  • Loading branch information
MSalopek committed Jun 28, 2023
1 parent e88e2b2 commit f6a0285
Show file tree
Hide file tree
Showing 4 changed files with 787 additions and 52 deletions.
40 changes: 39 additions & 1 deletion proto/interchain_security/ccv/v1/ccv.proto
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,42 @@ enum ConsumerPacketDataType {
// VSCMatured packet
CONSUMER_PACKET_TYPE_VSCM = 2
[ (gogoproto.enumvalue_customname) = "VscMaturedPacket" ];
}
}

// ConsumerPacketData contains a consumer packet data and a type tag
// that is compatible with ICS v1 and v2 over the wire. It is not used for internal storage.
message ConsumerPacketDataV1 {
ConsumerPacketDataType type = 1;

oneof data {
SlashPacketDataV1 slashPacketData = 2;
VSCMaturedPacketData vscMaturedPacketData = 3;
}
}

// This packet is sent from the consumer chain to the provider chain
// It is backward compatible with the ICS v1 and v2 version of the packet.
message SlashPacketDataV1 {
tendermint.abci.Validator validator = 1 [
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"validator\""
];
// map to the infraction block height on the provider
uint64 valset_update_id = 2;
// tell if the slashing is for a downtime or a double-signing infraction
InfractionType infraction = 3;
}

// InfractionType indicates the infraction type a validator commited.
// NOTE: ccv.InfractionType to maintain compatibility between ICS versions
// using different versions of the cosmos-sdk and ibc-go modules.
enum InfractionType {
option (gogoproto.goproto_enum_prefix) = false;

// UNSPECIFIED defines an empty infraction type.
INFRACTION_TYPE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "InfractionEmpty"];
// DOUBLE_SIGN defines a validator that double-signs a block.
INFRACTION_TYPE_DOUBLE_SIGN = 1 [(gogoproto.enumvalue_customname) = "DoubleSign"];
// DOWNTIME defines a validator that missed signing too many blocks.
INFRACTION_TYPE_DOWNTIME = 2 [(gogoproto.enumvalue_customname) = "Downtime"];
}
17 changes: 17 additions & 0 deletions x/ccv/consumer/keeper/relay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
testkeeper "github.com/cosmos/interchain-security/v3/testutil/keeper"
consumertypes "github.com/cosmos/interchain-security/v3/x/ccv/consumer/types"
"github.com/cosmos/interchain-security/v3/x/ccv/types"

Check failure on line 23 in x/ccv/consumer/keeper/relay_test.go

View workflow job for this annotation

GitHub Actions / lint

ST1019: package "github.com/cosmos/interchain-security/v3/x/ccv/types" is being imported more than once (stylecheck)
ccv "github.com/cosmos/interchain-security/v3/x/ccv/types"

Check failure on line 24 in x/ccv/consumer/keeper/relay_test.go

View workflow job for this annotation

GitHub Actions / lint

ST1019(related information): other import of "github.com/cosmos/interchain-security/v3/x/ccv/types" (stylecheck)

"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -307,3 +308,19 @@ func TestSendPacketsFailure(t *testing.T) {
consumerKeeper.SendPackets(ctx)
require.Equal(t, 3, len(consumerKeeper.GetPendingPackets(ctx).List))
}

Check failure on line 310 in x/ccv/consumer/keeper/relay_test.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed with `-extra` (gofumpt)
func TestSlashPacketDataJSON(t *testing.T) {
spd := types.NewSlashPacketData(
abci.Validator{Address: bytes.HexBytes{}, Power: int64(1)},
uint64(1),
stakingtypes.Infraction_INFRACTION_DOWNTIME,
)
cpd := ccv.ConsumerPacketData{
Type: ccv.SlashPacket,
Data: &ccv.ConsumerPacketData_SlashPacketData{
SlashPacketData: spd,
},
}
bz := cpd.GetBytes()
str := string(bz)
fmt.Println(str)
}
39 changes: 38 additions & 1 deletion x/ccv/types/ccv.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,23 @@ func NewSlashPacketData(validator abci.Validator, valUpdateId uint64, infraction
}
}

// 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")
Expand Down Expand Up @@ -99,7 +116,27 @@ func (cp ConsumerPacketData) ValidateBasic() (err error) {
return
}

// Convert to bytes while maintaining over the wire compatibility with previous versions.
func (cp ConsumerPacketData) GetBytes() []byte {
bytes := ModuleCdc.MustMarshalJSON(&cp)
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
}
Loading

0 comments on commit f6a0285

Please sign in to comment.