Skip to content

Commit 26a8d81

Browse files
authored
fix: disallow the creation of chains that use chain ids of existing running chains (#2244)
init commit
1 parent f03d537 commit 26a8d81

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

x/ccv/provider/types/msg.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,16 @@ func (msg MsgCreateConsumer) ValidateBasic() error {
297297
return errorsmod.Wrapf(ErrInvalidMsgCreateConsumer, "ChainId: %s", err.Error())
298298
}
299299

300+
// With permissionless ICS, we can have multiple consumer chains with the exact same chain id.
301+
// However, as we already have the Neutron and Stride Top N chains running, as a first step we would like to
302+
// prevent permissionless chains from re-using the chain ids of Neutron and Stride. Note that this is just a
303+
// preliminary measure that will be removed later on as part of:
304+
// TODO (#2242): find a better way of ignoring past misbehaviors
305+
if msg.ChainId == "neutron-1" || msg.ChainId == "stride-1" {
306+
return errorsmod.Wrapf(ErrInvalidMsgCreateConsumer,
307+
"cannot reuse chain ids of existing Neutron and Stride Top N consumer chains")
308+
}
309+
300310
if err := ValidateConsumerMetadata(msg.Metadata); err != nil {
301311
return errorsmod.Wrapf(ErrInvalidMsgCreateConsumer, "Metadata: %s", err.Error())
302312
}

x/ccv/provider/types/msg_test.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,77 @@ func TestTruncateString(t *testing.T) {
8585
}
8686
}
8787

88+
func TestValidateConsumerMetadata(t *testing.T) {
89+
generateLongString := func(length int) string {
90+
result := make([]byte, length)
91+
for i := range result {
92+
result[i] = byte('a')
93+
}
94+
return string(result)
95+
}
96+
97+
testCases := []struct {
98+
name string
99+
metadata types.ConsumerMetadata
100+
valid bool
101+
}{
102+
{
103+
name: "valid",
104+
metadata: types.ConsumerMetadata{
105+
Name: "name",
106+
Description: "description",
107+
Metadata: "metadata",
108+
},
109+
valid: true,
110+
},
111+
{
112+
name: "valid with long strings",
113+
metadata: types.ConsumerMetadata{
114+
Name: generateLongString(types.MaxNameLength),
115+
Description: generateLongString(types.MaxDescriptionLength),
116+
Metadata: generateLongString(types.MaxMetadataLength),
117+
},
118+
valid: true,
119+
},
120+
{
121+
name: "invalid name",
122+
metadata: types.ConsumerMetadata{
123+
Name: generateLongString(types.MaxNameLength + 1),
124+
Description: "description",
125+
Metadata: "metadata",
126+
},
127+
valid: false,
128+
},
129+
{
130+
name: "invalid description",
131+
metadata: types.ConsumerMetadata{
132+
Name: "name",
133+
Description: generateLongString(types.MaxDescriptionLength + 1),
134+
Metadata: "metadata",
135+
},
136+
valid: false,
137+
},
138+
{
139+
name: "invalid metadata",
140+
metadata: types.ConsumerMetadata{
141+
Name: "name",
142+
Description: "description",
143+
Metadata: generateLongString(types.MaxMetadataLength + 1),
144+
},
145+
valid: false,
146+
},
147+
}
148+
149+
for _, tc := range testCases {
150+
err := types.ValidateConsumerMetadata(tc.metadata)
151+
if tc.valid {
152+
require.NoError(t, err, tc.name)
153+
} else {
154+
require.Error(t, err, tc.name)
155+
}
156+
}
157+
}
158+
88159
func TestValidateInitializationParameters(t *testing.T) {
89160
now := time.Now().UTC()
90161
coolStr := "Cosmos Hub is the best place to launch a chain. Interchain Security is awesome."
@@ -367,6 +438,64 @@ func TestValidateByteSlice(t *testing.T) {
367438
}
368439
}
369440

441+
func TestMsgCreateConsumerValidateBasic(t *testing.T) {
442+
testCases := []struct {
443+
name string
444+
chainId string
445+
powerShapingParameters *types.PowerShapingParameters
446+
expPass bool
447+
}{
448+
{
449+
"empty chain id",
450+
"",
451+
nil, // no power-shaping parameters
452+
false,
453+
},
454+
{
455+
"empty chain id after trimming",
456+
" ",
457+
nil, // no power-shaping parameters
458+
false,
459+
},
460+
{
461+
"neutron chain id that cannot be reused",
462+
"neutron-1",
463+
nil, // no power-shaping parameters
464+
false,
465+
},
466+
{
467+
"stride chain id that cannot be reused",
468+
"stride-1",
469+
nil, // no power-shaping parameters
470+
false,
471+
},
472+
{
473+
"valid chain id",
474+
"somechain-1",
475+
nil, // no power-shaping parameters
476+
true,
477+
},
478+
{
479+
"valid chain id and invalid power-shaping parameters",
480+
"somechain-1",
481+
&types.PowerShapingParameters{Top_N: 51}, // TopN cannot be > 0 in MsgCreateConsumer
482+
false,
483+
},
484+
}
485+
486+
for _, tc := range testCases {
487+
validConsumerMetadata := types.ConsumerMetadata{Name: "name", Description: "description", Metadata: "metadata"}
488+
msg, err := types.NewMsgCreateConsumer("submitter", tc.chainId, validConsumerMetadata, nil, tc.powerShapingParameters)
489+
require.NoError(t, err)
490+
err = msg.ValidateBasic()
491+
if tc.expPass {
492+
require.NoError(t, err, "valid case: %s should not return error. got %w", tc.name, err)
493+
} else {
494+
require.Error(t, err, "invalid case: '%s' must return error but got none", tc.name)
495+
}
496+
}
497+
}
498+
370499
func TestMsgUpdateConsumerValidateBasic(t *testing.T) {
371500
consAddr1 := "cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq"
372501
consAddr2 := "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39"

0 commit comments

Comments
 (0)