Skip to content

Commit

Permalink
x/evidence genesis protobuf migration (#6864)
Browse files Browse the repository at this point in the history
* Migrate evidence genesis state to proto

* Fix lint error

* Remove commented code

* Clean up

* Add UnpackInterfaces to evidence GenesisState

* Add cosmos_proto.accepts_interface to evidence any and fix lint error

* Add test for x/evidence ExportGenesis and use table tests

* Update x/evidence/types/genesis.go

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* Update proto/cosmos/evidence/evidence.proto

Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com>

* Keep []Evidence as return type in GenEvidences

* Add GenesisState Validate tests

* Add test case for NewGenesisState

* Add tests for GenesisState UnpackInterfaces

Co-authored-by: SaReN <sahithnarahari@gmail.com>
Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com>
  • Loading branch information
4 people authored Jul 29, 2020
1 parent bc7e943 commit 2da954f
Show file tree
Hide file tree
Showing 11 changed files with 708 additions and 127 deletions.
3 changes: 2 additions & 1 deletion proto/cosmos/evidence/evidence.proto
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ option (gogoproto.equal_all) = true;
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/any.proto";
import "cosmos_proto/cosmos.proto";

// MsgSubmitEvidence defines an sdk.Msg type that supports submitting arbitrary
// Evidence.
message MsgSubmitEvidence {
option (gogoproto.goproto_getters) = false;
bytes submitter = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
google.protobuf.Any evidence = 2;
google.protobuf.Any evidence = 2 [(cosmos_proto.accepts_interface) = "Evidence"];
}

// Equivocation implements the Evidence interface and defines evidence of double
Expand Down
11 changes: 11 additions & 0 deletions proto/cosmos/evidence/genesis.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
syntax = "proto3";
package cosmos.evidence;

option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types";

import "google/protobuf/any.proto";

// GenesisState defines the evidence module's genesis state.
message GenesisState {
repeated google.protobuf.Any evidence = 1;
}
28 changes: 24 additions & 4 deletions x/evidence/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package evidence
import (
"fmt"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/evidence/exported"
"github.com/cosmos/cosmos-sdk/x/evidence/keeper"
"github.com/cosmos/cosmos-sdk/x/evidence/types"
"github.com/gogo/protobuf/proto"
)

// InitGenesis initializes the evidence module's state from a provided genesis
Expand All @@ -16,17 +19,34 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) {
}

for _, e := range gs.Evidence {
if _, ok := k.GetEvidence(ctx, e.Hash()); ok {
panic(fmt.Sprintf("evidence with hash %s already exists", e.Hash()))
evi, ok := e.GetCachedValue().(exported.Evidence)
if !ok {
panic("expected evidence")
}
if _, ok := k.GetEvidence(ctx, evi.Hash()); ok {
panic(fmt.Sprintf("evidence with hash %s already exists", evi.Hash()))
}

k.SetEvidence(ctx, e)
k.SetEvidence(ctx, evi)
}
}

// ExportGenesis returns the evidence module's exported genesis.
func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState {
e := k.GetAllEvidence(ctx)
evidence := make([]*codectypes.Any, len(e))
for i, evi := range e {
msg, ok := evi.(proto.Message)
if !ok {
panic(fmt.Errorf("cannot proto marshal %T", evi))
}
any, err := codectypes.NewAnyWithValue(msg)
if err != nil {
panic(err)
}
evidence[i] = any
}
return types.GenesisState{
Evidence: k.GetAllEvidence(ctx),
Evidence: evidence,
}
}
138 changes: 109 additions & 29 deletions x/evidence/genesis_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package evidence_test

import (
"fmt"
"testing"

"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -31,46 +32,125 @@ func (suite *GenesisTestSuite) SetupTest() {
suite.keeper = app.EvidenceKeeper
}

func (suite *GenesisTestSuite) TestInitGenesis_Valid() {
pk := ed25519.GenPrivKey()

testEvidence := make([]exported.Evidence, 100)
for i := 0; i < 100; i++ {
testEvidence[i] = &types.Equivocation{
Height: int64(i + 1),
Power: 100,
Time: time.Now().UTC(),
ConsensusAddress: pk.PubKey().Address().Bytes(),
}
func (suite *GenesisTestSuite) TestInitGenesis() {
var (
genesisState types.GenesisState
testEvidence []exported.Evidence
pk = ed25519.GenPrivKey()
)

testCases := []struct {
msg string
malleate func()
expPass bool
posttests func()
}{
{
"valid",
func() {
testEvidence = make([]exported.Evidence, 100)
for i := 0; i < 100; i++ {
testEvidence[i] = &types.Equivocation{
Height: int64(i + 1),
Power: 100,
Time: time.Now().UTC(),
ConsensusAddress: pk.PubKey().Address().Bytes(),
}
}
genesisState = types.NewGenesisState(testEvidence)
},
true,
func() {
for _, e := range testEvidence {
_, ok := suite.keeper.GetEvidence(suite.ctx, e.Hash())
suite.True(ok)
}
},
},
{
"invalid",
func() {
testEvidence = make([]exported.Evidence, 100)
for i := 0; i < 100; i++ {
testEvidence[i] = &types.Equivocation{
Power: 100,
Time: time.Now().UTC(),
ConsensusAddress: pk.PubKey().Address().Bytes(),
}
}
genesisState = types.NewGenesisState(testEvidence)
},
false,
func() {
suite.Empty(suite.keeper.GetAllEvidence(suite.ctx))
},
},
}

suite.NotPanics(func() {
evidence.InitGenesis(suite.ctx, suite.keeper, types.NewGenesisState(testEvidence))
})
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest()

tc.malleate()

if tc.expPass {
suite.NotPanics(func() {
evidence.InitGenesis(suite.ctx, suite.keeper, genesisState)
})
} else {
suite.Panics(func() {
evidence.InitGenesis(suite.ctx, suite.keeper, genesisState)
})
}

for _, e := range testEvidence {
_, ok := suite.keeper.GetEvidence(suite.ctx, e.Hash())
suite.True(ok)
tc.posttests()
})
}
}

func (suite *GenesisTestSuite) TestInitGenesis_Invalid() {
func (suite *GenesisTestSuite) TestExportGenesis() {
pk := ed25519.GenPrivKey()

testEvidence := make([]exported.Evidence, 100)
for i := 0; i < 100; i++ {
testEvidence[i] = &types.Equivocation{
Power: 100,
Time: time.Now().UTC(),
ConsensusAddress: pk.PubKey().Address().Bytes(),
}
testCases := []struct {
msg string
malleate func()
expPass bool
posttests func()
}{
{
"success",
func() {
suite.keeper.SetEvidence(suite.ctx, &types.Equivocation{
Height: 1,
Power: 100,
Time: time.Now().UTC(),
ConsensusAddress: pk.PubKey().Address().Bytes(),
})
},
true,
func() {},
},
}

suite.Panics(func() {
evidence.InitGenesis(suite.ctx, suite.keeper, types.NewGenesisState(testEvidence))
})
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest()

suite.Empty(suite.keeper.GetAllEvidence(suite.ctx))
tc.malleate()

if tc.expPass {
suite.NotPanics(func() {
evidence.ExportGenesis(suite.ctx, suite.keeper)
})
} else {
suite.Panics(func() {
evidence.ExportGenesis(suite.ctx, suite.keeper)
})
}

tc.posttests()
})
}
}

func TestGenesisTestSuite(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion x/evidence/simulation/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func RandomizedGenState(simState *module.SimulationState) {
func(r *rand.Rand) { ev = GenEvidences(r, simState.Accounts) },
)

evidenceGenesis := types.GenesisState{Evidence: ev}
evidenceGenesis := types.NewGenesisState(ev)

fmt.Printf("Selected randomly generated %s parameters:\n%s\n", types.ModuleName, codec.MustMarshalJSONIndent(simState.Cdc, evidenceGenesis))
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(evidenceGenesis)
Expand Down
25 changes: 0 additions & 25 deletions x/evidence/simulation/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ import (
// Abonormal scenarios are not tested here.
func TestRandomizedGenState(t *testing.T) {
cdc := codec.New()
// Make sure to register cdc.
// Otherwise RandomizedGenState will panic!
types.RegisterCodec(cdc)

s := rand.NewSource(1)
r := rand.New(s)
Expand All @@ -42,25 +39,3 @@ func TestRandomizedGenState(t *testing.T) {

require.Len(t, evidenceGenesis.Evidence, 0)
}

// TestRandomizedGenState tests the execution of RandomizedGenState
// without registering the evidence interfaces.
// We expect the test to panic.
func TestRandomizedGenState1(t *testing.T) {
cdc := codec.New()

s := rand.NewSource(1)
r := rand.New(s)

simState := module.SimulationState{
AppParams: make(simtypes.AppParams),
Cdc: cdc,
Rand: r,
NumBonded: 3,
Accounts: simtypes.RandomAccounts(r, 3),
InitialStake: 1000,
GenState: make(map[string]json.RawMessage),
}

require.Panicsf(t, func() { simulation.RandomizedGenState(&simState) }, "failed to marshal JSON: Unregistered interface exported.Evidence")
}
54 changes: 28 additions & 26 deletions x/evidence/types/evidence.pb.go

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

Loading

0 comments on commit 2da954f

Please sign in to comment.