Skip to content

Commit

Permalink
fix(proto): dependency cycle between rdk, dymint, and rollapp repos (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
keruch authored Oct 31, 2024
1 parent 346edea commit efbf726
Show file tree
Hide file tree
Showing 6 changed files with 2,879 additions and 52 deletions.
12 changes: 10 additions & 2 deletions proto/types/rollapp/sequencers/types/tx.proto
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// This file is a partial copy of https://github.com/dymensionxyz/dymension-rdk/blob/545051749bc0fcd9f8d8f27c2bb4d582e960f1e2/proto/sequencers/tx.proto.
// The package name is changed to avoid dependency cycles when importing both RDK and Dymint in RollApp-WASM and RollApp-EVM repos.
// Be careful with google.protobuf.Any as using any types under google.protobuf.Any from the current package (dymension_rdk.sequencers.types)
// leads to proto-wiring errors.
// References: https://github.com/golang/protobuf/issues/924, https://stackoverflow.com/a/47654538.

syntax = "proto3";
package rollapp.sequencers.types;
package dymension_rdk.sequencers.types;

import "gogoproto/gogo.proto";
import "types/cosmos/msg/v1/msg.proto";
Expand Down Expand Up @@ -36,7 +42,9 @@ message ConsensusMsgUpsertSequencer {
string signer = 1;
// Operator is the bech32-encoded address of the sequencer
string operator = 2;
// ConsPubKey is a tendermint consensus pub key of the sequencer
// ConsPubKey is a tendermint consensus pub key of the sequencer.
// NB! google.protobuf.Any MUST NOT hold any values from the current
// package (dymension_rdk.sequencers.types). Otherwise, it will lead to proto wiring error.
google.protobuf.Any cons_pub_key = 3;
// RewardAddr is the bech32-encoded sequencer's reward address
string reward_addr = 4;
Expand Down
72 changes: 37 additions & 35 deletions types/pb/rollapp/sequencers/types/tx.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 33 additions & 15 deletions utils/proto/converters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (

"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
cosmos "github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/gogo/protobuf/proto"
gogo "github.com/gogo/protobuf/types"
"github.com/stretchr/testify/require"

protoutils "github.com/dymensionxyz/dymint/utils/proto"
Expand All @@ -19,15 +21,7 @@ import (
func TestConvertCosmosToGogo(t *testing.T) {
setup()

// generate the expected pubkey
expectedPK := ed25519.GenPrivKey().PubKey()

// convert it to cosmos any
cosmosProtoPK, err := cdctypes.NewAnyWithValue(expectedPK)
require.NoError(t, err)

// convert cosmos to gogo any
gogoProtoPK := protoutils.CosmosToGogo(cosmosProtoPK)
expectedPK, gogoProtoPK := GenerateGogoProtoPK(t)

// create a sequencer with gogo any
gogoSeq := &gogoseq.Sequencer{
Expand Down Expand Up @@ -55,12 +49,7 @@ func TestConvertCosmosToGogo(t *testing.T) {
func TestConvertGogoToCosmos(t *testing.T) {
setup()

// generate the expected pubkey
expectedPK := ed25519.GenPrivKey().PubKey()

// convert it to cosmos any
cosmosProtoPK, err := cdctypes.NewAnyWithValue(expectedPK)
require.NoError(t, err)
expectedPK, cosmosProtoPK := GenerateCosmosProtoPK(t)

// create a sequencer with cosmos any
cosmosSeq := &cosmosseq.Sequencer{
Expand Down Expand Up @@ -88,6 +77,35 @@ func TestConvertGogoToCosmos(t *testing.T) {
require.Equal(t, expectedPK, actualPK)
}

func GenerateGogoProtoPK(t *testing.T) (cryptotypes.PubKey, *gogo.Any) {
t.Helper()

// generate the expected pubkey
expectedPK := ed25519.GenPrivKey().PubKey()

// convert it to cosmos any
cosmosProtoPK, err := cdctypes.NewAnyWithValue(expectedPK)
require.NoError(t, err)

// convert cosmos to gogo any
gogoProtoPK := protoutils.CosmosToGogo(cosmosProtoPK)

return expectedPK, gogoProtoPK
}

func GenerateCosmosProtoPK(t *testing.T) (cryptotypes.PubKey, *cosmos.Any) {
t.Helper()

// generate the expected pubkey
expectedPK := ed25519.GenPrivKey().PubKey()

// convert it to cosmos any
cosmosProtoPK, err := cdctypes.NewAnyWithValue(expectedPK)
require.NoError(t, err)

return expectedPK, cosmosProtoPK
}

var cdc *codec.ProtoCodec

func setup() {
Expand Down
63 changes: 63 additions & 0 deletions utils/proto/prefixes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package proto_test

import (
"testing"

"github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/require"

prefix1 "github.com/dymensionxyz/dymint/utils/proto/test_data/prefix_1"
prefix2 "github.com/dymensionxyz/dymint/utils/proto/test_data/prefix_2"
)

// TestDifferentPrefixes ensures that using different package prefixes for the same
// type doesn't affect binary serialization/deserialization.
func TestDifferentPrefixes(t *testing.T) {
_, cosmosProtoPK := GenerateGogoProtoPK(t)

// Create two fully equal messages:
// - the first has 'dymension_rdk' prefix
// - the second has 'rollapp' prefix
msgPrefix1 := &prefix1.ConsensusMsgUpsertSequencer{
Signer: "1234567890",
Operator: "1234567890",
ConsPubKey: cosmosProtoPK,
RewardAddr: "1234567890",
Relayers: []string{"1234567890", "1234567890"},
}
msgPrefix2 := &prefix2.ConsensusMsgUpsertSequencer{
Signer: "1234567890",
Operator: "1234567890",
ConsPubKey: cosmosProtoPK,
RewardAddr: "1234567890",
Relayers: []string{"1234567890", "1234567890"},
}

// Serialize both messages to bytes
bytesMsg1, err := proto.Marshal(msgPrefix1)
require.NoError(t, err)
bytesMsg2, err := proto.Marshal(msgPrefix2)
require.NoError(t, err)

// Ensure that the bytes representation is the same
require.Equal(t, bytesMsg1, bytesMsg2)

// Try to deserialize the second bytes into the first message
actualMsgPrefix1 := new(prefix1.ConsensusMsgUpsertSequencer)
err = proto.Unmarshal(bytesMsg2, actualMsgPrefix1)

// Try to deserialize the first bytes into the second message
actualMsgPrefix2 := new(prefix2.ConsensusMsgUpsertSequencer)
err = proto.Unmarshal(bytesMsg1, actualMsgPrefix2)

// Verify that the messages are the same as the initial
require.Equal(t, msgPrefix1, actualMsgPrefix1)
require.Equal(t, msgPrefix2, actualMsgPrefix2)

// Verify that all fields match
require.Equal(t, actualMsgPrefix1.Signer, actualMsgPrefix2.Signer)
require.Equal(t, actualMsgPrefix1.Operator, actualMsgPrefix2.Operator)
require.Equal(t, actualMsgPrefix1.ConsPubKey, actualMsgPrefix2.ConsPubKey)
require.Equal(t, actualMsgPrefix1.RewardAddr, actualMsgPrefix2.RewardAddr)
require.Equal(t, actualMsgPrefix1.Relayers, actualMsgPrefix2.Relayers)
}
Loading

0 comments on commit efbf726

Please sign in to comment.