diff --git a/x/ccv/consumer/keeper/relay_test.go b/x/ccv/consumer/keeper/relay_test.go index 6dbebe273f..ed6771900e 100644 --- a/x/ccv/consumer/keeper/relay_test.go +++ b/x/ccv/consumer/keeper/relay_test.go @@ -234,13 +234,21 @@ func TestOnAcknowledgementPacket(t *testing.T) { // Set an established provider channel for later in test consumerKeeper.SetProviderChannel(ctx, channelIDToProvider) - packetData := types.NewSlashPacketData( + slashPacketData := types.NewSlashPacketData( abci.Validator{Address: bytes.HexBytes{}, Power: int64(1)}, uint64(1), stakingtypes.Infraction_INFRACTION_DOWNTIME, ) + // The type that'd be JSON marshaled and sent over the wire + consumerPacketData := types.NewConsumerPacketData( + types.SlashPacket, + &types.ConsumerPacketData_SlashPacketData{ + SlashPacketData: slashPacketData, + }, + ) + // AcknowledgePacket is in reference to a packet originally sent from this (consumer) module. packet := channeltypes.NewPacket( - packetData.GetBytes(), + consumerPacketData.GetBytes(), 1, types.ConsumerPortID, // Source port channelIDToDestChain, // Source channel diff --git a/x/ccv/types/ccv.go b/x/ccv/types/ccv.go index 91175eab5d..70921704f7 100644 --- a/x/ccv/types/ccv.go +++ b/x/ccv/types/ccv.go @@ -29,6 +29,8 @@ func (vsc ValidatorSetChangePacketData) ValidateBasic() error { 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 @@ -48,11 +50,6 @@ func (mat VSCMaturedPacketData) ValidateBasic() error { return nil } -func (mat VSCMaturedPacketData) GetBytes() []byte { - bytes := ModuleCdc.MustMarshalJSON(&mat) - return bytes -} - func NewSlashPacketData(validator abci.Validator, valUpdateId uint64, infractionType stakingtypes.Infraction) *SlashPacketData { return &SlashPacketData{ Validator: validator, @@ -90,11 +87,6 @@ func (vdt SlashPacketData) ValidateBasic() error { return nil } -func (vdt SlashPacketData) GetBytes() []byte { - valDowntimeBytes := ModuleCdc.MustMarshalJSON(&vdt) - return valDowntimeBytes -} - func (vdt SlashPacketData) ToV1() *SlashPacketDataV1 { return NewSlashPacketDataV1(vdt.Validator, vdt.ValsetUpdateId, vdt.Infraction) } diff --git a/x/ccv/types/ccv_test.go b/x/ccv/types/ccv_test.go index 596967b199..dd57b0513c 100644 --- a/x/ccv/types/ccv_test.go +++ b/x/ccv/types/ccv_test.go @@ -1,15 +1,17 @@ package types_test import ( + "strings" "testing" + abci "github.com/cometbft/cometbft/abci/types" "github.com/stretchr/testify/require" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - abci "github.com/cometbft/cometbft/abci/types" - + "github.com/cosmos/interchain-security/v3/testutil/crypto" "github.com/cosmos/interchain-security/v3/x/ccv/types" ) @@ -93,3 +95,132 @@ func TestMarshalPacketData(t *testing.T) { require.Nil(t, err) require.Equal(t, vpd, recovered, "unmarshaled packet data does not equal original value") } + +// TestVSCPacketDataWireBytes is a regression test that the JSON schema +// for ValidatorSetChangePacketData (sent over the wire) does not change. +func TestVSCPacketDataWireBytes(t *testing.T) { + + cId1 := crypto.NewCryptoIdentityFromIntSeed(4732894) + cId2 := crypto.NewCryptoIdentityFromIntSeed(4732895) + + pd := types.NewValidatorSetChangePacketData( + []abci.ValidatorUpdate{ + { + PubKey: cId1.TMProtoCryptoPublicKey(), + Power: 30, + }, + { + PubKey: cId2.TMProtoCryptoPublicKey(), + Power: 20, + }, + }, + 73, + []string{"slash", "acks", "example"}, + ) + + jsonBz := pd.GetBytes() + str := string(jsonBz) + + // Expected string formatted for human readability + expectedStr := `{ + "validator_updates": [ + { + "pub_key": { + "ed25519": "SMxP2pXAuxQC7FmBn4dh4Kt5eYdQFWC/wN7oWobZKds=" + }, + "power": "30" + }, + { + "pub_key": { + "ed25519": "J/nGy0vCXhgVbr8S71B4ZgHi4fsMqtDxDlERZ+gG238=" + }, + "power": "20" + } + ], + "valset_update_id": "73", + "slash_acks": ["slash", "acks", "example"] + }` + + // Remove newlines, tabs, and spaces for comparison + expectedStr = strings.ReplaceAll(expectedStr, "\n", "") + expectedStr = strings.ReplaceAll(expectedStr, "\t", "") + expectedStr = strings.ReplaceAll(expectedStr, " ", "") + + require.Equal(t, expectedStr, str) +} + +// TestSlashPacketDataWireBytes is a regression test that the JSON schema +// for SlashPacketData (sent over the wire) does not change. +func TestSlashPacketDataWireBytes(t *testing.T) { + + // Construct consumer packet data wrapping slash packet data + cId := crypto.NewCryptoIdentityFromIntSeed(4732894342) + slashPacketData := types.NewSlashPacketData( + abci.Validator{Address: cId.SDKValConsAddress(), + Power: int64(4328)}, + uint64(894732), + stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN, + ) + + // The type that'd be JSON marshaled and sent over the wire + cpd := types.NewConsumerPacketData( + types.SlashPacket, + &types.ConsumerPacketData_SlashPacketData{ + SlashPacketData: slashPacketData, + }, + ) + + jsonBz := cpd.GetBytes() + str := string(jsonBz) + + // Expected string formatted for human readability + expectedStr := `{ + "type": "CONSUMER_PACKET_TYPE_SLASH", + "slashPacketData": { + "validator": { + "address": "BP9q4oXCgubvoujOKyxIxd+3IwM=", + "power": "4328" + }, + "valset_update_id": "894732", + "infraction": "INFRACTION_TYPE_DOUBLE_SIGN" + } + }` + + // Remove newlines, tabs, and spaces for comparison + expectedStr = strings.ReplaceAll(expectedStr, "\n", "") + expectedStr = strings.ReplaceAll(expectedStr, "\t", "") + expectedStr = strings.ReplaceAll(expectedStr, " ", "") + + require.Equal(t, expectedStr, str) +} + +// TestVSCMaturedPacketDataWireBytes is a regression test that the JSON schema +// for VSCMaturedPacketData (sent over the wire) does not change. +func TestVSCMaturedPacketDataWireBytes(t *testing.T) { + + // Construct consumer packet data wrapping vsc matured packet data + cpd := types.ConsumerPacketData{ + Type: types.VscMaturedPacket, + Data: &types.ConsumerPacketData_VscMaturedPacketData{ + VscMaturedPacketData: types.NewVSCMaturedPacketData(84923), + }, + } + + jsonBz := cpd.GetBytes() + str := string(jsonBz) + + // Expected string formatted for human readability + expectedStr := `{ + "type": "CONSUMER_PACKET_TYPE_VSCM", + "vscMaturedPacketData": { + "valset_update_id": "84923" + } + }` + + // Remove newlines, tabs, and spaces for comparison + expectedStr = strings.ReplaceAll(expectedStr, "\n", "") + expectedStr = strings.ReplaceAll(expectedStr, "\t", "") + expectedStr = strings.ReplaceAll(expectedStr, " ", "") + + require.Equal(t, expectedStr, str) +}