diff --git a/x/lightclient/types/genesis.go b/x/lightclient/types/genesis.go index d12d11eae..e2560484e 100644 --- a/x/lightclient/types/genesis.go +++ b/x/lightclient/types/genesis.go @@ -9,13 +9,37 @@ func DefaultGenesisState() GenesisState { } func (g GenesisState) Validate() error { + + clientSet := make(map[string]struct{}) for _, client := range g.CanonicalClients { if client.RollappId == "" { - return fmt.Errorf("invalid rollapp id: %v", client) + return fmt.Errorf("invalid rollapp_id: %v", client) } if client.IbcClientId == "" { - return fmt.Errorf("invalid ibc client id: %v", client) + return fmt.Errorf("invalid ibc_client_id: %v", client) + } + + clientKey := client.RollappId + ":" + client.IbcClientId + if _, exists := clientSet[clientKey]; exists { + return fmt.Errorf("duplicate canonical client found: %v", client) + } + clientSet[clientKey] = struct{}{} + } + + signerSet := make(map[string]struct{}) + for _, signer := range g.HeaderSigners { + if signer.SequencerAddress == "" { + return fmt.Errorf("invalid sequencer address: %v", signer) + } + if signer.ClientId == "" { + return fmt.Errorf("invalid client id: %v", signer) + } + + signerKey := signer.SequencerAddress + ":" + fmt.Sprint(signer.Height) + if _, exists := signerSet[signerKey]; exists { + return fmt.Errorf("duplicate signer entry found: %v", signer) } + signerSet[signerKey] = struct{}{} } return nil diff --git a/x/lightclient/types/genesis_test.go b/x/lightclient/types/genesis_test.go index e5711c968..1c8fafa66 100644 --- a/x/lightclient/types/genesis_test.go +++ b/x/lightclient/types/genesis_test.go @@ -52,6 +52,44 @@ func TestGenesisValidate(t *testing.T) { g: types.DefaultGenesisState(), valid: true, }, + { + name: "duplicate canonical client", + g: types.GenesisState{ + CanonicalClients: []types.CanonicalClient{ + {RollappId: "rollapp-1", IbcClientId: "client-1"}, + {RollappId: "rollapp-1", IbcClientId: "client-1"}, + }, + }, + valid: false, + }, + { + name: "duplicate header signer", + g: types.GenesisState{ + HeaderSigners: []types.HeaderSignerEntry{ + {SequencerAddress: "sequencer1", ClientId: "client1", Height: 100}, + {SequencerAddress: "sequencer1", ClientId: "client1", Height: 100}, + }, + }, + valid: false, + }, + { + name: "empty sequencer address in header signer", + g: types.GenesisState{ + HeaderSigners: []types.HeaderSignerEntry{ + {SequencerAddress: "", ClientId: "client1", Height: 100}, + }, + }, + valid: false, + }, + { + name: "empty client id in header signer", + g: types.GenesisState{ + HeaderSigners: []types.HeaderSignerEntry{ + {SequencerAddress: "sequencer1", ClientId: "", Height: 100}, + }, + }, + valid: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {