Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: genesis import/export for CSR module #51

Merged
merged 4 commits into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func TestAppImportExport(t *testing.T) {
},
{app.keys[distrtypes.StoreKey], newApp.keys[distrtypes.StoreKey], [][]byte{}},
{app.keys[paramstypes.StoreKey], newApp.keys[paramstypes.StoreKey], [][]byte{
[]byte("evm/EnableExtraEIPs"),
[]byte("evm/EnableExtraEIPs"), []byte("bank/SendEnabled"),
}},
{app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}},
{app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}},
Expand Down
3 changes: 3 additions & 0 deletions proto/canto/csr/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ package canto.csr.v1;

import "gogoproto/gogo.proto";
import "canto/csr/v1/params.proto";
import "canto/csr/v1/csr.proto";

option go_package = "github.com/Canto-Network/Canto/v7/x/csr/types";

// GenesisState defines the csr module's genesis state.
message GenesisState {
// params defines all of the parameters of the module
Params params = 1 [ (gogoproto.nullable) = false ];
repeated CSR csrs = 2 [ (gogoproto.nullable) = false ];
bytes turnstile_address = 3;
}
21 changes: 21 additions & 0 deletions x/csr/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@ import (
"github.com/Canto-Network/Canto/v7/x/csr/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
"github.com/ethereum/go-ethereum/common"
)

// InitGenesis initializes the capability module's state from a provided genesis
// state.
func InitGenesis(ctx sdk.Context, k keeper.Keeper, accountKeeper authkeeper.AccountKeeper, genState types.GenesisState) {
// this line is used by starport scaffolding # genesis/module/init
k.SetParams(ctx, genState.Params)
for _, csr := range genState.Csrs {
k.SetCSR(ctx, csr)
}
if genState.TurnstileAddress != nil {
k.SetTurnstile(ctx, common.BytesToAddress(genState.TurnstileAddress))
}
// make sure that the csr module account is set on genesis
if acc := accountKeeper.GetModuleAccount(ctx, types.ModuleName); acc == nil {
// NOTE: shouldn't occur
Expand All @@ -23,6 +30,20 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, accountKeeper authkeeper.Acco
func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState {
genesis := types.DefaultGenesis()
genesis.Params = k.GetParams(ctx)
csrs := k.GetAllCSRs(ctx)

if len(csrs) == 0 {
genesis.Csrs = []types.CSR{}
} else {
genesis.Csrs = csrs
}

turnstileAddress, found := k.GetTurnstile(ctx)
if found {
genesis.TurnstileAddress = turnstileAddress.Bytes()
} else {
genesis.TurnstileAddress = nil
}

return genesis
}
21 changes: 21 additions & 0 deletions x/csr/keeper/csr.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,27 @@ func (k Keeper) GetCSR(ctx sdk.Context, nftId uint64) (*types.CSR, bool) {
return csr, true
}

func (k Keeper) IterateAllCSRs(ctx sdk.Context, cb func(csr types.CSR) (stop bool)) {
store := ctx.KVStore(k.storeKey)
iter := sdk.KVStorePrefixIterator(store, types.KeyPrefixCSR)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
var csr types.CSR
k.cdc.MustUnmarshal(iter.Value(), &csr)
if cb(csr) {
break
}
}
}

func (k Keeper) GetAllCSRs(ctx sdk.Context) (csrs []types.CSR) {
k.IterateAllCSRs(ctx, func(csr types.CSR) (stop bool) {
csrs = append(csrs, csr)
return false
})
return
}

// Returns the NFT ID associated with a smart contract address. If the smart contract address
// entered does belong to some NFT, then it will return (id, true), otherwise (0, false).
func (k Keeper) GetNFTByContract(ctx sdk.Context, address string) (uint64, bool) {
Expand Down
95 changes: 95 additions & 0 deletions x/csr/keeper/genesis_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package keeper_test

import (
"time"

"github.com/Canto-Network/Canto/v7/x/csr"
"github.com/Canto-Network/Canto/v7/x/csr/types"
"github.com/evmos/ethermint/tests"
)

func (suite *KeeperTestSuite) TestDefaultGenesis() {
genState := types.DefaultGenesis()

csr.InitGenesis(suite.ctx, suite.app.CSRKeeper, suite.app.AccountKeeper, *genState)
got := csr.ExportGenesis(suite.ctx, suite.app.CSRKeeper)
suite.Require().Equal(genState, got)
}

func (suite *KeeperTestSuite) TestImportExportGenesisEmpty() {
_, found := suite.app.CSRKeeper.GetTurnstile(suite.ctx)
suite.Require().False(found)
csrs := suite.app.CSRKeeper.GetAllCSRs(suite.ctx)
suite.Require().Empty(csrs)

genState := csr.ExportGenesis(suite.ctx, suite.app.CSRKeeper)
suite.Require().Nil(genState.TurnstileAddress)
suite.Require().Empty(genState.Csrs)

// Copy genState to genState2 and init with it
var genState2 types.GenesisState
bz := suite.app.AppCodec().MustMarshalJSON(genState)
suite.app.AppCodec().MustUnmarshalJSON(bz, &genState2)
csr.InitGenesis(suite.ctx, suite.app.CSRKeeper, suite.app.AccountKeeper, genState2)

_, found = suite.app.CSRKeeper.GetTurnstile(suite.ctx)
suite.Require().False(found)
csrs = suite.app.CSRKeeper.GetAllCSRs(suite.ctx)
suite.Require().Empty(csrs)
genState3 := csr.ExportGenesis(suite.ctx, suite.app.CSRKeeper)
suite.Equal(*genState, genState2)
suite.Equal(genState2, *genState3)
suite.Require().Nil(genState3.TurnstileAddress)
suite.Require().Empty(genState3.Csrs)
}

func (suite *KeeperTestSuite) TestInitExportGenesis() {
expGenesis := types.DefaultGenesis()

csr.InitGenesis(suite.ctx, suite.app.CSRKeeper, suite.app.AccountKeeper, *expGenesis)
genState := csr.ExportGenesis(suite.ctx, suite.app.CSRKeeper)
suite.Require().Equal(expGenesis, genState)

bz := suite.app.AppCodec().MustMarshalJSON(genState)

var genState2 types.GenesisState
suite.app.AppCodec().MustUnmarshalJSON(bz, &genState2)
csr.InitGenesis(suite.ctx, suite.app.CSRKeeper, suite.app.AccountKeeper, genState2)
genState3 := csr.ExportGenesis(suite.ctx, suite.app.CSRKeeper)

suite.Require().Equal(*genState, genState2)
suite.Require().Equal(genState2, *genState3)
}

func (suite *KeeperTestSuite) TestImportExportGenesis() {
t, _ := time.Parse(time.RFC3339, "2022-01-01T00:00:00Z")
suite.ctx = suite.ctx.WithBlockHeight(1).WithBlockTime(t)

numberCSRs := 10
csrs := GenerateCSRs(numberCSRs)
for _, csr := range csrs {
suite.app.CSRKeeper.SetCSR(suite.ctx, csr)
}

turnstileAddress := tests.GenerateAddress()
suite.app.CSRKeeper.SetTurnstile(suite.ctx, turnstileAddress)

genState := csr.ExportGenesis(suite.ctx, suite.app.CSRKeeper)
bz := suite.app.AppCodec().MustMarshalJSON(genState)

// Copy genState to genState2 and init with it
var genState2 types.GenesisState
suite.app.AppCodec().MustUnmarshalJSON(bz, &genState2)
csr.InitGenesis(suite.ctx, suite.app.CSRKeeper, suite.app.AccountKeeper, genState2)
exported := csr.ExportGenesis(suite.ctx, suite.app.CSRKeeper)
suite.Equal(*genState, *exported)

suite.ctx = suite.ctx.WithBlockHeight(1).WithBlockTime(t)

c := suite.app.CSRKeeper.GetAllCSRs(suite.ctx)
suite.Equal(csrs, c)

ta, found := suite.app.CSRKeeper.GetTurnstile(suite.ctx)
suite.True(found)
suite.Equal(turnstileAddress, ta)
}
8 changes: 7 additions & 1 deletion x/csr/types/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ const DefaultIndex uint64 = 1

// DefaultGenesis returns the default Capability genesis state
func DefaultGenesis() *GenesisState {
return NewGenesisState(DefaultParams(), []CSR{}, nil)
}

func NewGenesisState(params Params, csrs []CSR, turnstileAddress []byte) *GenesisState {
return &GenesisState{
Params: DefaultParams(),
Params: params,
Csrs: csrs,
TurnstileAddress: turnstileAddress,
}
}

Expand Down
141 changes: 130 additions & 11 deletions x/csr/types/genesis.pb.go

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

Loading
Loading