forked from cosmos/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ibc/02-client: import export GenesisState (cosmos#6073)
* ibc/02-client: import export GenesisState * client validation * genesis validation * ibc genesis tests * GetAllConsensusStates test * fix non-determinism * lint * fix test
- Loading branch information
Showing
18 changed files
with
616 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package client | ||
|
||
import ( | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
// InitGenesis initializes the ibc client submodule's state from a provided genesis | ||
// state. | ||
func InitGenesis(ctx sdk.Context, k Keeper, gs GenesisState) { | ||
for _, client := range gs.Clients { | ||
k.SetClientState(ctx, client) | ||
k.SetClientType(ctx, client.GetID(), client.ClientType()) | ||
} | ||
for _, cs := range gs.ClientsConsensus { | ||
for _, consState := range cs.ConsensusStates { | ||
k.SetClientConsensusState(ctx, cs.ClientID, consState.GetHeight(), consState) | ||
} | ||
} | ||
} | ||
|
||
// ExportGenesis returns the ibc client submodule's exported genesis. | ||
func ExportGenesis(ctx sdk.Context, k Keeper) GenesisState { | ||
return GenesisState{ | ||
Clients: k.GetAllClients(ctx), | ||
ClientsConsensus: k.GetAllConsensusStates(ctx), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package types | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" | ||
host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" | ||
) | ||
|
||
// ClientConsensusStates defines all the stored consensus states for a given client. | ||
type ClientConsensusStates struct { | ||
ClientID string `json:"client_id" yaml:"client_id"` | ||
ConsensusStates []exported.ConsensusState `json:"consensus_states" yaml:"consensus_states"` | ||
} | ||
|
||
// NewClientConsensusStates creates a new ClientConsensusStates instance. | ||
func NewClientConsensusStates(id string, states []exported.ConsensusState) ClientConsensusStates { | ||
return ClientConsensusStates{ | ||
ClientID: id, | ||
ConsensusStates: states, | ||
} | ||
} | ||
|
||
// GenesisState defines the ibc client submodule's genesis state. | ||
type GenesisState struct { | ||
Clients []exported.ClientState `json:"clients" yaml:"clients"` | ||
ClientsConsensus []ClientConsensusStates `json:"clients_consensus" yaml:"clients_consensus"` | ||
} | ||
|
||
// NewGenesisState creates a GenesisState instance. | ||
func NewGenesisState( | ||
clients []exported.ClientState, clientsConsensus []ClientConsensusStates, | ||
) GenesisState { | ||
return GenesisState{ | ||
Clients: clients, | ||
ClientsConsensus: clientsConsensus, | ||
} | ||
} | ||
|
||
// DefaultGenesisState returns the ibc client submodule's default genesis state. | ||
func DefaultGenesisState() GenesisState { | ||
return GenesisState{ | ||
Clients: []exported.ClientState{}, | ||
ClientsConsensus: []ClientConsensusStates{}, | ||
} | ||
} | ||
|
||
// Validate performs basic genesis state validation returning an error upon any | ||
// failure. | ||
func (gs GenesisState) Validate() error { | ||
for i, client := range gs.Clients { | ||
if err := client.Validate(); err != nil { | ||
return fmt.Errorf("invalid client %d: %w", i, err) | ||
} | ||
} | ||
|
||
for i, cs := range gs.ClientsConsensus { | ||
if err := host.DefaultClientIdentifierValidator(cs.ClientID); err != nil { | ||
return fmt.Errorf("invalid client consensus state %d: %w", i, err) | ||
} | ||
for _, consensusState := range cs.ConsensusStates { | ||
if err := consensusState.ValidateBasic(); err != nil { | ||
return fmt.Errorf("invalid client consensus state %d: %w", i, err) | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package types_test | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
tmtypes "github.com/tendermint/tendermint/types" | ||
dbm "github.com/tendermint/tm-db" | ||
|
||
"github.com/cosmos/cosmos-sdk/store/cachekv" | ||
"github.com/cosmos/cosmos-sdk/store/dbadapter" | ||
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" | ||
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" | ||
ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" | ||
localhosttypes "github.com/cosmos/cosmos-sdk/x/ibc/09-localhost/types" | ||
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" | ||
) | ||
|
||
const ( | ||
clientID = "ethbridge" | ||
|
||
trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 | ||
ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 | ||
maxClockDrift time.Duration = time.Second * 10 | ||
) | ||
|
||
func TestValidateGenesis(t *testing.T) { | ||
privVal := tmtypes.NewMockPV() | ||
pubKey, err := privVal.GetPubKey() | ||
require.NoError(t, err) | ||
|
||
now := time.Now().UTC() | ||
|
||
val := tmtypes.NewValidator(pubKey, 10) | ||
valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) | ||
|
||
mem := dbadapter.Store{DB: dbm.NewMemDB()} | ||
store := cachekv.NewStore(mem) | ||
header := ibctmtypes.CreateTestHeader("chainID", 10, now, valSet, []tmtypes.PrivValidator{privVal}) | ||
|
||
testCases := []struct { | ||
name string | ||
genState types.GenesisState | ||
expPass bool | ||
}{ | ||
{ | ||
name: "default", | ||
genState: types.DefaultGenesisState(), | ||
expPass: true, | ||
}, | ||
{ | ||
name: "valid genesis", | ||
genState: types.NewGenesisState( | ||
[]exported.ClientState{ | ||
ibctmtypes.NewClientState(clientID, trustingPeriod, ubdPeriod, maxClockDrift, header), | ||
localhosttypes.NewClientState(store, "chaindID", 10), | ||
}, | ||
[]types.ClientConsensusStates{ | ||
{ | ||
clientID, | ||
[]exported.ConsensusState{ | ||
ibctmtypes.NewConsensusState( | ||
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), header.GetHeight(), header.ValidatorSet, | ||
), | ||
}, | ||
}, | ||
}, | ||
), | ||
expPass: true, | ||
}, | ||
{ | ||
name: "invalid client", | ||
genState: types.NewGenesisState( | ||
[]exported.ClientState{ | ||
ibctmtypes.NewClientState(clientID, trustingPeriod, ubdPeriod, maxClockDrift, header), | ||
localhosttypes.NewClientState(store, "chaindID", 0), | ||
}, | ||
nil, | ||
), | ||
expPass: false, | ||
}, | ||
{ | ||
name: "invalid consensus state", | ||
genState: types.NewGenesisState( | ||
[]exported.ClientState{ | ||
ibctmtypes.NewClientState(clientID, trustingPeriod, ubdPeriod, maxClockDrift, header), | ||
localhosttypes.NewClientState(store, "chaindID", 10), | ||
}, | ||
[]types.ClientConsensusStates{ | ||
{ | ||
"CLIENTID2", | ||
[]exported.ConsensusState{ | ||
ibctmtypes.NewConsensusState( | ||
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), 0, header.ValidatorSet, | ||
), | ||
}, | ||
}, | ||
}, | ||
), | ||
expPass: false, | ||
}, | ||
{ | ||
name: "invalid consensus state", | ||
genState: types.NewGenesisState( | ||
[]exported.ClientState{ | ||
ibctmtypes.NewClientState(clientID, trustingPeriod, ubdPeriod, maxClockDrift, header), | ||
localhosttypes.NewClientState(store, "chaindID", 10), | ||
}, | ||
[]types.ClientConsensusStates{ | ||
types.NewClientConsensusStates( | ||
clientID, | ||
[]exported.ConsensusState{ | ||
ibctmtypes.NewConsensusState( | ||
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), 0, header.ValidatorSet, | ||
), | ||
}, | ||
), | ||
}, | ||
), | ||
expPass: false, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
tc := tc | ||
err := tc.genState.Validate() | ||
if tc.expPass { | ||
require.NoError(t, err, tc.name) | ||
} else { | ||
require.Error(t, err, tc.name) | ||
} | ||
} | ||
} |
Oops, something went wrong.