diff --git a/app/app_test.go b/app/app_test.go index e50ac9ce..140c6c2c 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -27,8 +27,6 @@ import ( var emptyWasmOpts []wasm.Option = nil func TestTgradeExport(t *testing.T) { - t.Skip("Alex, export is not implemented") - db := db.NewMemDB() gapp := NewTgradeApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, MakeEncodingConfig(), EmptyBaseAppOptions{}, emptyWasmOpts) genesisState := NewDefaultGenesisState() @@ -37,7 +35,6 @@ func TestTgradeExport(t *testing.T) { stateBytes, err := json.MarshalIndent(genesisState, "", " ") require.NoError(t, err) - // Initialize the chain gapp.InitChain( abci.RequestInitChain{ @@ -62,6 +59,10 @@ func setupWithSingleValidatorGenTX(t *testing.T, genesisState GenesisState) { // - enough funds on the bank // - membership in engagement group marshaler := MakeEncodingConfig().Codec + poeGS := poetypes.GetGenesisStateFromAppState(marshaler, genesisState) + if poeGS.GetSeedContracts() == nil { + panic("not in seed mode") + } systemAdminAddr := sdk.AccAddress(rand.Bytes(address.Len)) myGenTx, myAddr, _ := poetypes.RandomGenTX(t, 100) @@ -79,8 +80,10 @@ func setupWithSingleValidatorGenTX(t *testing.T, genesisState GenesisState) { marshaler.MustUnmarshalJSON(genesisState[banktypes.ModuleName], &bankGenState) coins := sdk.Coins{sdk.NewCoin(poetypes.DefaultBondDenom, sdk.NewInt(1000000000))} - bankGenState.Balances = append(bankGenState.Balances, banktypes.Balance{Address: myAddr.String(), Coins: coins.Sort()}) - bankGenState.Balances = append(bankGenState.Balances, banktypes.Balance{Address: systemAdminAddr.String(), Coins: coins.Sort()}) + bankGenState.Balances = append(bankGenState.Balances, banktypes.Balance{Address: myAddr.String(), Coins: coins}) + bankGenState.Supply = bankGenState.Supply.Add(coins...) + bankGenState.Balances = append(bankGenState.Balances, banktypes.Balance{Address: systemAdminAddr.String(), Coins: coins}) + bankGenState.Supply = bankGenState.Supply.Add(coins...) genAddrAndUpdateBalance := func(numAddr int, balance sdk.Coins) []string { genAddr := make([]string, numAddr) @@ -88,25 +91,25 @@ func setupWithSingleValidatorGenTX(t *testing.T, genesisState GenesisState) { addr := poetypes.RandomAccAddress().String() bankGenState.Balances = append(bankGenState.Balances, banktypes.Balance{Address: addr, Coins: balance}) genAddr[i] = addr + bankGenState.Supply = bankGenState.Supply.Add(balance...) } return genAddr } // add 3 oc members - ocMembers := genAddrAndUpdateBalance(3, coins.Sort()) + ocMembers := genAddrAndUpdateBalance(3, coins) // add 2 ap members - apMembers := genAddrAndUpdateBalance(2, coins.Sort()) + apMembers := genAddrAndUpdateBalance(2, coins) genesisState[banktypes.ModuleName] = marshaler.MustMarshalJSON(&bankGenState) // add system admin to not fail poe on validation - poeGS := poetypes.GetGenesisStateFromAppState(marshaler, genesisState) - poeGS.BondDenom = poetypes.DefaultBondDenom - poeGS.GenTxs = []json.RawMessage{myGenTx} - poeGS.Engagement = []poetypes.TG4Member{{Address: myAddr.String(), Points: 10}} - poeGS.SystemAdminAddress = systemAdminAddr.String() - poeGS.OversightCommunityMembers = ocMembers - poeGS.ArbiterPoolMembers = apMembers + poeGS.GetSeedContracts().BondDenom = poetypes.DefaultBondDenom + poeGS.GetSeedContracts().GenTxs = []json.RawMessage{myGenTx} + poeGS.GetSeedContracts().Engagement = []poetypes.TG4Member{{Address: myAddr.String(), Points: 10}} + poeGS.GetSeedContracts().SystemAdminAddress = systemAdminAddr.String() + poeGS.GetSeedContracts().OversightCommunityMembers = ocMembers + poeGS.GetSeedContracts().ArbiterPoolMembers = apMembers genesisState = poetypes.SetGenesisStateInAppState(marshaler, genesisState, poeGS) } diff --git a/app/export.go b/app/export.go index 4fd2ed15..0247d80e 100644 --- a/app/export.go +++ b/app/export.go @@ -1,7 +1,19 @@ package app import ( + "encoding/json" + "time" + servertypes "github.com/cosmos/cosmos-sdk/server/types" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + tmcrypto "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/encoding" + pc "github.com/tendermint/tendermint/proto/tendermint/crypto" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/confio/tgrade/x/poe/contract" ) // ExportAppStateAndValidators exports the state of the application for a genesis @@ -9,177 +21,69 @@ import ( func (app *TgradeApp) ExportAppStateAndValidators( forZeroHeight bool, jailAllowedAddrs []string, ) (servertypes.ExportedApp, error) { - panic("Alex, not implemented") - //// as if they could withdraw from the start of the next block - //ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) - // - //// We export at last height + 1, because that's the height at which - //// Tendermint will start InitChain. - //height := app.LastBlockHeight() + 1 - //if forZeroHeight { - // height = 0 - // app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs) - //} - // - //genState := app.mm.ExportGenesis(ctx, app.appCodec) - //appState, err := json.MarshalIndent(genState, "", " ") - //if err != nil { - // return servertypes.ExportedApp{}, err - //} - // - //validators, err := staking.WriteValidators(ctx, app.stakingKeeper) - //return servertypes.ExportedApp{ - // AppState: appState, - // Validators: validators, - // Height: height, - // ConsensusParams: app.BaseApp.GetConsensusParams(ctx), - //}, err + if forZeroHeight { + panic("zero height export not supported") + } + // as if they could withdraw from the start of the next block + ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}). + WithBlockTime(time.Now().UTC()) // todo (Alex): check if there is any way to get the last block time + + // We export at last height + 1, because that's the height at which + // Tendermint will start InitChain. + height := app.LastBlockHeight() + 1 + genState := app.mm.ExportGenesis(ctx, app.appCodec) + appState, err := json.MarshalIndent(genState, "", " ") + if err != nil { + return servertypes.ExportedApp{}, err + } + + validators, err := activeValidatorSet(app, ctx, err) + if err != nil { + return servertypes.ExportedApp{}, err + } + return servertypes.ExportedApp{ + AppState: appState, + Validators: validators, + Height: height, + ConsensusParams: app.BaseApp.GetConsensusParams(ctx), + }, err } -// prepare for fresh start at zero height -// NOTE zero height genesis is a temporary feature which will be deprecated -// in favour of export at a block height -//func (app *TgradeApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) { -// applyAllowedAddrs := false -// -// // check if there is a allowed address list -// if len(jailAllowedAddrs) > 0 { -// applyAllowedAddrs = true -// } -// -// allowedAddrsMap := make(map[string]bool) -// -// for _, addr := range jailAllowedAddrs { -// _, err := sdk.ValAddressFromBech32(addr) -// if err != nil { -// log.Fatal(err) -// } -// allowedAddrsMap[addr] = true -// } -// -// /* Just to be safe, assert the invariants on current state. */ -// app.crisisKeeper.AssertInvariants(ctx) -// -// /* Handle fee distribution state. */ -// -// // withdraw all validator commission -// app.stakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { -// _, _ = app.distrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator()) -// return false -// }) -// -// // withdraw all delegator rewards -// dels := app.stakingKeeper.GetAllDelegations(ctx) -// for _, delegation := range dels { -// valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress) -// if err != nil { -// panic(err) -// } -// -// delAddr, err := sdk.AccAddressFromBech32(delegation.OperatorAddress) -// if err != nil { -// panic(err) -// } -// _, _ = app.distrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr) -// } -// -// // clear validator slash events -// app.distrKeeper.DeleteAllValidatorSlashEvents(ctx) -// -// // clear validator historical rewards -// app.distrKeeper.DeleteAllValidatorHistoricalRewards(ctx) -// -// // set context height to zero -// height := ctx.BlockHeight() -// ctx = ctx.WithBlockHeight(0) -// -// // reinitialize all validators -// app.stakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { -// // donate any unwithdrawn outstanding reward fraction tokens to the community pool -// scraps := app.distrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) -// feePool := app.distrKeeper.GetFeePool(ctx) -// feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) -// app.distrKeeper.SetFeePool(ctx, feePool) -// -// app.distrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) -// return false -// }) -// -// // reinitialize all delegations -// for _, del := range dels { -// valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress) -// if err != nil { -// panic(err) -// } -// delAddr, err := sdk.AccAddressFromBech32(del.OperatorAddress) -// if err != nil { -// panic(err) -// } -// app.distrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr) -// app.distrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr) -// } -// -// // reset context height -// ctx = ctx.WithBlockHeight(height) -// -// /* Handle staking state. */ -// -// // iterate through redelegations, reset creation height -// app.stakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) { -// for i := range red.Entries { -// red.Entries[i].CreationHeight = 0 -// } -// app.stakingKeeper.SetRedelegation(ctx, red) -// return false -// }) -// -// // iterate through unbonding delegations, reset creation height -// app.stakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) { -// for i := range ubd.Entries { -// ubd.Entries[i].CreationHeight = 0 -// } -// app.stakingKeeper.SetUnbondingDelegation(ctx, ubd) -// return false -// }) -// -// // Iterate through validators by power descending, reset bond heights, and -// // update bond intra-tx counters. -// store := ctx.KVStore(app.keys[stakingtypes.StoreKey]) -// iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) -// counter := int16(0) -// -// for ; iter.Valid(); iter.Next() { -// addr := sdk.ValAddress(iter.Key()[1:]) -// validator, found := app.stakingKeeper.GetValidator(ctx, addr) -// if !found { -// panic("expected validator, not found") -// } -// -// validator.UnbondingHeight = 0 -// if applyAllowedAddrs && !allowedAddrsMap[addr.String()] { -// validator.Jailed = true -// } -// -// app.stakingKeeper.SetValidator(ctx, validator) -// counter++ -// } -// -// iter.Close() -// -// _, err := app.stakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) -// if err != nil { -// log.Fatal(err) -// } -// -// /* Handle slashing state. */ -// -// // reset start height on signing infos -// app.slashingKeeper.IterateValidatorSigningInfos( -// ctx, -// func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) { -// info.StartHeight = 0 -// app.slashingKeeper.SetValidatorSigningInfo(ctx, addr, info) -// return false -// }, -// ) -//} +func activeValidatorSet(app *TgradeApp, ctx sdk.Context, err error) ([]tmtypes.GenesisValidator, error) { + var result []tmtypes.GenesisValidator + valset := app.poeKeeper.ValsetContract(ctx) + valset.IterateActiveValidators(ctx, func(c contract.ValidatorInfo) bool { + var opAddr sdk.AccAddress + opAddr, err = sdk.AccAddressFromBech32(c.Operator) + if err != nil { + return true + } + var pk pc.PublicKey + pk, err = contract.ConvertToTendermintPubKey(c.ValidatorPubkey) + if err != nil { + return true + } + var tmPk tmcrypto.PubKey + tmPk, err = encoding.PubKeyFromProto(pk) + if err != nil { + return true + } + var meta *stakingtypes.Validator + meta, err = valset.QueryValidator(ctx, opAddr) + if err != nil { + return true + } + moniker := "" + if meta != nil { + moniker = meta.GetMoniker() + } + result = append(result, tmtypes.GenesisValidator{ + Address: tmPk.Address(), + PubKey: tmPk, + Power: int64(c.Power), + Name: moniker, + }) + return false + }, nil) + return result, err +} diff --git a/app/genesis_integration_test.go b/app/genesis_integration_test.go new file mode 100644 index 00000000..7c66011e --- /dev/null +++ b/app/genesis_integration_test.go @@ -0,0 +1,122 @@ +package app + +import ( + "encoding/json" + "fmt" + "os" + "testing" + "time" + + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + poetypes "github.com/confio/tgrade/x/poe/types" + + "github.com/stretchr/testify/assert" + tmjson "github.com/tendermint/tendermint/libs/json" + + "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/log" + db "github.com/tendermint/tm-db" + + "github.com/confio/tgrade/x/twasm" + twasmtypes "github.com/confio/tgrade/x/twasm/types" +) + +func TestTgradeGenesisExportImport(t *testing.T) { + doInitWithGenesis := func(gapp *TgradeApp, genesisState GenesisState) { + stateBytes, err := json.MarshalIndent(genesisState, "", " ") + require.NoError(t, err) + + // Initialize the chain + gapp.InitChain( + abci.RequestInitChain{ + Time: time.Now().UTC(), + Validators: []abci.ValidatorUpdate{}, + AppStateBytes: stateBytes, + }, + ) + gapp.Commit() + } + memDB := db.NewMemDB() + srcApp := NewTgradeApp( + log.NewTMLogger(log.NewSyncWriter(os.Stdout)), + memDB, + nil, + true, + map[int64]bool{}, + DefaultNodeHome, + 0, + MakeEncodingConfig(), + EmptyBaseAppOptions{}, + emptyWasmOpts, + ) + + init := NewDefaultGenesisState() + setupWithSingleValidatorGenTX(t, init) + doInitWithGenesis(srcApp, init) + + now := time.Now().UTC() + for i := 0; i < 3; i++ { // add some blocks + header := tmproto.Header{ + ChainID: "testing-1", + Height: int64(2 + i), + Time: now.Add(time.Duration(i+1) * time.Hour), // big step > epoch + AppHash: []byte(fmt.Sprintf("myAppHash%d", i)), + } + srcApp.BeginBlock(abci.RequestBeginBlock{Header: header}) + srcApp.Commit() + } + + // create a new instance to read state only from db. initchain was not called on this + srcApp = NewTgradeApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), memDB, nil, true, map[int64]bool{}, DefaultNodeHome, 0, MakeEncodingConfig(), EmptyBaseAppOptions{}, emptyWasmOpts) + + exported, err := srcApp.ExportAppStateAndValidators(false, []string{}) + require.NoError(t, err, "ExportAppStateAndValidators should not have an error") + + // then ensure that valset contract state is exported + var gs GenesisState + require.NoError(t, tmjson.Unmarshal(exported.AppState, &gs)) + require.Contains(t, gs, twasm.ModuleName) + var twasmGs twasmtypes.GenesisState + require.NoError(t, srcApp.appCodec.UnmarshalJSON(gs[twasm.ModuleName], &twasmGs)) + // todo (Alex): enable require.NoError(t, twasmGs.ValidateBasic()) + + var customModelContractCount int + for _, v := range twasmGs.Contracts { + var ext twasmtypes.TgradeContractDetails + require.NoError(t, v.ContractInfo.ReadExtension(&ext)) + if ext.HasRegisteredPrivilege(twasmtypes.PrivilegeStateExporterImporter) { + m := v.GetCustomModel() + require.NotNil(t, m) + assert.Nil(t, v.GetKvModel()) + assert.NoError(t, m.Msg.ValidateBasic()) + customModelContractCount++ + } else { + m := v.GetKvModel() + require.NotNil(t, m) + assert.Nil(t, v.GetCustomModel()) + } + } + assert.Equal(t, 1, customModelContractCount) + + // ensure poe is correct + var poeGs poetypes.GenesisState + require.NoError(t, srcApp.appCodec.UnmarshalJSON(gs[poetypes.ModuleName], &poeGs)) + require.NoError(t, poetypes.ValidateGenesis(poeGs, MakeEncodingConfig().TxConfig.TxJSONDecoder())) + // now import the state on a fresh DB + memDB = db.NewMemDB() + newApp := NewTgradeApp( + log.NewTMLogger(log.NewSyncWriter(os.Stdout)), + memDB, + nil, + true, + map[int64]bool{}, + DefaultNodeHome, + 0, + MakeEncodingConfig(), + EmptyBaseAppOptions{}, + emptyWasmOpts, + ) + doInitWithGenesis(newApp, gs) +} diff --git a/cmd/tgrade/testnet.go b/cmd/tgrade/testnet.go index c5107e65..76d35d2a 100644 --- a/cmd/tgrade/testnet.go +++ b/cmd/tgrade/testnet.go @@ -408,14 +408,14 @@ func initGenFiles( appGenState[banktypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&bankGenState) poeGenesisState := poetypes.GetGenesisStateFromAppState(clientCtx.Codec, appGenState) for i, addr := range genAccounts { - poeGenesisState.Engagement = append(poeGenesisState.Engagement, poetypes.TG4Member{ + poeGenesisState.GetSeedContracts().Engagement = append(poeGenesisState.GetSeedContracts().Engagement, poetypes.TG4Member{ Address: addr.GetAddress().String(), Points: uint64(len(genAccounts) - i), // unique weight }) } - poeGenesisState.SystemAdminAddress = admin.String() - poeGenesisState.OversightCommunityMembers = ocMemberAddrs - poeGenesisState.ArbiterPoolMembers = apMemberAddrs + poeGenesisState.GetSeedContracts().SystemAdminAddress = admin.String() + poeGenesisState.GetSeedContracts().OversightCommunityMembers = ocMemberAddrs + poeGenesisState.GetSeedContracts().ArbiterPoolMembers = apMemberAddrs poetypes.SetGenesisStateInAppState(clientCtx.Codec, appGenState, poeGenesisState) appGenStateJSON, err := json.MarshalIndent(appGenState, "", " ") diff --git a/contrib/local/setup_tgrade.sh b/contrib/local/setup_tgrade.sh index 0fe81a49..36783ee1 100755 --- a/contrib/local/setup_tgrade.sh +++ b/contrib/local/setup_tgrade.sh @@ -43,13 +43,13 @@ done # set systemadmin address (temporary) # set engagement points -content=$(cat "$HOME"/.tgrade/config/genesis.json | jq ".app_state.poe.engagement |= . + [{\"address\":\"$(echo "$PASSWORD" | tgrade keys show -a validator)\",\"points\":\"100\"}]") +content=$(cat "$HOME"/.tgrade/config/genesis.json | jq ".app_state.poe.seed_contracts.engagement |= . + [{\"address\":\"$(echo "$PASSWORD" | tgrade keys show -a validator)\",\"points\":\"100\"}]") # set oversight community -content=$(echo "$content" | jq ".app_state.poe.oversightCommunityMembers |= . + [\"$(echo "$PASSWORD" | tgrade keys show -a systemadmin)\"]") -# set arbiter pool -content=$(echo "$content" | jq ".app_state.poe.arbiterPoolMembers |= . + [\"$(echo "$PASSWORD" | tgrade keys show -a systemadmin)\"]") +content=$(echo "$content" | jq ".app_state.poe.seed_contracts.oversightCommunityMembers |= . + [\"$(echo "$PASSWORD" | tgrade keys show -a systemadmin)\"]") +# set arbiter +content=$(echo "$content" | jq ".app_state.poe.seed_contracts.arbiterPoolMembers |= . + [\"$(echo "$PASSWORD" | tgrade keys show -a systemadmin)\"]") # set system admin -content=$(echo "$content" | jq ".app_state.poe.system_admin_address |= \"$(echo "$PASSWORD" | tgrade keys show -a systemadmin)\"") +content=$(echo "$content" | jq ".app_state.poe.seed_contracts.system_admin_address |= \"$(echo "$PASSWORD" | tgrade keys show -a systemadmin)\"") # set min fee content=$(echo "$content" | jq ".app_state.globalfee.params.minimum_gas_prices |= [{\"denom\":\"$STAKE\",\"amount\":\"0.001\"}]") diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index a1c90455..a7fd0df0 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -24,8 +24,10 @@ - [CommunityPoolContractConfig](#confio.poe.v1beta1.CommunityPoolContractConfig) - [EngagementContractConfig](#confio.poe.v1beta1.EngagementContractConfig) - [GenesisState](#confio.poe.v1beta1.GenesisState) + - [ImportDump](#confio.poe.v1beta1.ImportDump) - [OversightCommitteeContractConfig](#confio.poe.v1beta1.OversightCommitteeContractConfig) - [PoEContract](#confio.poe.v1beta1.PoEContract) + - [SeedContracts](#confio.poe.v1beta1.SeedContracts) - [StakeContractConfig](#confio.poe.v1beta1.StakeContractConfig) - [TG4Member](#confio.poe.v1beta1.TG4Member) - [ValidatorVotingContractConfig](#confio.poe.v1beta1.ValidatorVotingContractConfig) @@ -63,7 +65,10 @@ - [TgradeContractDetails](#confio.twasm.v1beta1.TgradeContractDetails) - [confio/twasm/v1beta1/genesis.proto](#confio/twasm/v1beta1/genesis.proto) + - [Contract](#confio.twasm.v1beta1.Contract) + - [CustomModel](#confio.twasm.v1beta1.CustomModel) - [GenesisState](#confio.twasm.v1beta1.GenesisState) + - [KVModel](#confio.twasm.v1beta1.KVModel) - [confio/twasm/v1beta1/proposal.proto](#confio/twasm/v1beta1/proposal.proto) - [DemotePrivilegedContractProposal](#confio.twasm.v1beta1.DemotePrivilegedContractProposal) @@ -301,21 +306,23 @@ GenesisState - initial state of module | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | `params` | [Params](#confio.poe.v1beta1.Params) | | params defines all the parameter of the module | -| `seed_contracts` | [bool](#bool) | | SeedContracts when enabled stores and instantiates the Proof of Engagement contracts on the chain. | -| `gen_txs` | [bytes](#bytes) | repeated | GenTxs defines the genesis transactions to create a validator. | -| `system_admin_address` | [string](#string) | | SystemAdminAddress single address that is set as admin for the PoE contracts in seed mode. | -| `contracts` | [PoEContract](#confio.poe.v1beta1.PoEContract) | repeated | Contracts Poe contract addresses and types when used with state dump in non seed mode. | -| `engagement` | [TG4Member](#confio.poe.v1beta1.TG4Member) | repeated | Engagement weighted members of the engagement group. Validators should be in here. | -| `stake_contract_config` | [StakeContractConfig](#confio.poe.v1beta1.StakeContractConfig) | | | -| `valset_contract_config` | [ValsetContractConfig](#confio.poe.v1beta1.ValsetContractConfig) | | | -| `engagement_contract_config` | [EngagementContractConfig](#confio.poe.v1beta1.EngagementContractConfig) | | | -| `bond_denom` | [string](#string) | | BondDenom defines the bondable coin denomination. | -| `oversight_committee_contract_config` | [OversightCommitteeContractConfig](#confio.poe.v1beta1.OversightCommitteeContractConfig) | | | -| `community_pool_contract_config` | [CommunityPoolContractConfig](#confio.poe.v1beta1.CommunityPoolContractConfig) | | | -| `validator_voting_contract_config` | [ValidatorVotingContractConfig](#confio.poe.v1beta1.ValidatorVotingContractConfig) | | | -| `oversightCommunityMembers` | [string](#string) | repeated | | -| `arbiterPoolMembers` | [string](#string) | repeated | | -| `arbiter_pool_contract_config` | [ArbiterPoolContractConfig](#confio.poe.v1beta1.ArbiterPoolContractConfig) | | | +| `seed_contracts` | [SeedContracts](#confio.poe.v1beta1.SeedContracts) | | SeedContracts stores and instantiates the Proof of Engagement contracts on the chain. | +| `import_dump` | [ImportDump](#confio.poe.v1beta1.ImportDump) | | ImportDump restores the state from an exported state genesis | + + + + + + + + +### ImportDump +ImportDump has all module data for non seed mode. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `contracts` | [PoEContract](#confio.poe.v1beta1.PoEContract) | repeated | Contracts PoE contract addresses and types | @@ -356,6 +363,34 @@ PoEContract address and type information + + +### SeedContracts +SeedContracts contains the contract configuration and group members to setup +all PoE contracts on chain. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `gen_txs` | [bytes](#bytes) | repeated | GenTxs defines the genesis transactions to create a validator. | +| `system_admin_address` | [string](#string) | | SystemAdminAddress single address that is set as admin for the PoE contracts in seed mode. | +| `engagement` | [TG4Member](#confio.poe.v1beta1.TG4Member) | repeated | Engagement weighted members of the engagement group. Validators should be in here. | +| `stake_contract_config` | [StakeContractConfig](#confio.poe.v1beta1.StakeContractConfig) | | | +| `valset_contract_config` | [ValsetContractConfig](#confio.poe.v1beta1.ValsetContractConfig) | | | +| `engagement_contract_config` | [EngagementContractConfig](#confio.poe.v1beta1.EngagementContractConfig) | | | +| `bond_denom` | [string](#string) | | BondDenom defines the bondable coin denomination. | +| `oversight_committee_contract_config` | [OversightCommitteeContractConfig](#confio.poe.v1beta1.OversightCommitteeContractConfig) | | | +| `community_pool_contract_config` | [CommunityPoolContractConfig](#confio.poe.v1beta1.CommunityPoolContractConfig) | | | +| `validator_voting_contract_config` | [ValidatorVotingContractConfig](#confio.poe.v1beta1.ValidatorVotingContractConfig) | | | +| `oversightCommunityMembers` | [string](#string) | repeated | | +| `arbiterPoolMembers` | [string](#string) | repeated | | +| `arbiter_pool_contract_config` | [ArbiterPoolContractConfig](#confio.poe.v1beta1.ArbiterPoolContractConfig) | | | + + + + + + ### StakeContractConfig @@ -424,6 +459,9 @@ ValsetContractConfig initial setup config | `validator_reward_ratio` | [string](#string) | | ValidatorRewardRation in percentage for all | | `auto_unjail` | [bool](#bool) | | AutoUnjail if set to true, we will auto-unjail any validator after their jailtime is over. | | `double_sign_slash_ratio` | [string](#string) | | DoubleSignSlashRatio Validators who are caught double signing are jailed forever and their bonded tokens are slashed based on this value. | +| `verify_validators` | [bool](#bool) | | When a validator joins the valset, verify they sign the first block since joining or jail them for a period otherwise. + +The verification happens every time the validator becomes an active validator, including when they are unjailed or when they just gain enough power to participate. | @@ -846,6 +884,40 @@ TgradeContractDetails is a custom extension to the wasmd ContractInfo + + +### Contract +Contract struct encompasses ContractAddress, ContractInfo, and ContractState + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `contract_address` | [string](#string) | | | +| `contract_info` | [cosmwasm.wasm.v1.ContractInfo](#cosmwasm.wasm.v1.ContractInfo) | | | +| `kv_model` | [KVModel](#confio.twasm.v1beta1.KVModel) | | | +| `custom_model` | [CustomModel](#confio.twasm.v1beta1.CustomModel) | | | + + + + + + + + +### CustomModel +CustomModel contains the raw json data for a contract to seed its state on +import + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on import | + + + + + + ### GenesisState @@ -854,9 +926,28 @@ TgradeContractDetails is a custom extension to the wasmd ContractInfo | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `wasm` | [cosmwasm.wasm.v1.GenesisState](#cosmwasm.wasm.v1.GenesisState) | | | -| `privileged_contract_addresses` | [string](#string) | repeated | | -| `pinned_code_ids` | [uint64](#uint64) | repeated | | +| `params` | [cosmwasm.wasm.v1.Params](#cosmwasm.wasm.v1.Params) | | Params sdk type Params for wasmd | +| `codes` | [cosmwasm.wasm.v1.Code](#cosmwasm.wasm.v1.Code) | repeated | Codes has all stored wasm codes and metadata | +| `contracts` | [Contract](#confio.twasm.v1beta1.Contract) | repeated | Contracts contains all instantiated contracts, state and metadata | +| `sequences` | [cosmwasm.wasm.v1.Sequence](#cosmwasm.wasm.v1.Sequence) | repeated | Sequences names and values | +| `gen_msgs` | [cosmwasm.wasm.v1.GenesisState.GenMsgs](#cosmwasm.wasm.v1.GenesisState.GenMsgs) | repeated | GenMsgs has wasmd sdk type messages to execute in the genesis phase | +| `privileged_contract_addresses` | [string](#string) | repeated | PrivilegedContractAddresses is a list of contract addresses that can have special permissions | +| `pinned_code_ids` | [uint64](#uint64) | repeated | PinnedCodeIDs has codeInfo ids for wasm codes that are pinned in cache | + + + + + + + + +### KVModel +KVModel is a wrapper around the wasmd default key value model. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `models` | [cosmwasm.wasm.v1.Model](#cosmwasm.wasm.v1.Model) | repeated | | diff --git a/proto/confio/poe/v1beta1/genesis.proto b/proto/confio/poe/v1beta1/genesis.proto index 523165dc..b5b33ae2 100644 --- a/proto/confio/poe/v1beta1/genesis.proto +++ b/proto/confio/poe/v1beta1/genesis.proto @@ -15,12 +15,33 @@ message GenesisState { // params defines all the parameter of the module Params params = 1 [ (gogoproto.nullable) = false ]; - // SeedContracts when enabled stores and instantiates the Proof of Engagement - // contracts on the chain. - bool seed_contracts = 2; + // SetupMode defines which scenario to apply on a genesis import. + // Either it is a fresh chain that needs PoE contracts bootstrapped or + // the module state has to be restored from a previous state dump. + oneof setup_mode { + // SeedContracts stores and instantiates the Proof of Engagement + // contracts on the chain. + SeedContracts seed_contracts = 2; + // ImportDump restores the state from an exported state genesis + ImportDump import_dump = 3; + } +} + +// ImportDump has all module data for non seed mode. +message ImportDump { + // Contracts PoE contract addresses and types + repeated PoEContract contracts = 1 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "contracts,omitempty" + ]; +} + +// SeedContracts contains the contract configuration and group members to setup +// all PoE contracts on chain. +message SeedContracts { // GenTxs defines the genesis transactions to create a validator. - repeated bytes gen_txs = 3 [ + repeated bytes gen_txs = 1 [ (gogoproto.casttype) = "encoding/json.RawMessage", (gogoproto.jsontag) = "gentxs", (gogoproto.moretags) = "yaml:\"gentxs\"" @@ -28,45 +49,43 @@ message GenesisState { // SystemAdminAddress single address that is set as admin for the PoE // contracts in seed mode. - string system_admin_address = 4; - - // Contracts Poe contract addresses and types when used with state dump in non - // seed mode. - repeated PoEContract contracts = 5 [ - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "contracts,omitempty" - ]; + string system_admin_address = 2; // Engagement weighted members of the engagement group. Validators should be // in here. - repeated TG4Member engagement = 6 [ + repeated TG4Member engagement = 3 [ (gogoproto.nullable) = false, (gogoproto.jsontag) = "engagement,omitempty" ]; - StakeContractConfig stake_contract_config = 7 + StakeContractConfig stake_contract_config = 4 [ (gogoproto.jsontag) = "stake_contract_config,omitempty" ]; - ValsetContractConfig valset_contract_config = 8 + ValsetContractConfig valset_contract_config = 5 [ (gogoproto.jsontag) = "valset_contract_config,omitempty" ]; - EngagementContractConfig engagement_contract_config = 9 + + EngagementContractConfig engagement_contract_config = 6 [ (gogoproto.jsontag) = "engagement_contract_config,omitempty" ]; + // BondDenom defines the bondable coin denomination. - string bond_denom = 10 [ (gogoproto.moretags) = "yaml:\"bond_denom\"" ]; - OversightCommitteeContractConfig oversight_committee_contract_config = 11 + string bond_denom = 7 [ (gogoproto.moretags) = "yaml:\"bond_denom\"" ]; + + OversightCommitteeContractConfig oversight_committee_contract_config = 8 [ (gogoproto.jsontag) = "oversight_committee_contract_config,omitempty" ]; - CommunityPoolContractConfig community_pool_contract_config = 12 + + CommunityPoolContractConfig community_pool_contract_config = 9 [ (gogoproto.jsontag) = "community_pool_contract_config,omitempty" ]; - ValidatorVotingContractConfig validator_voting_contract_config = 13 + + ValidatorVotingContractConfig validator_voting_contract_config = 10 [ (gogoproto.jsontag) = "validator_voting_contract_config,omitempty" ]; - repeated string oversightCommunityMembers = 14 + repeated string oversightCommunityMembers = 11 [ (gogoproto.jsontag) = "oversight_community_members,omitempty" ]; - repeated string arbiterPoolMembers = 15 + repeated string arbiterPoolMembers = 12 [ (gogoproto.jsontag) = "arbiter_pool_members,omitempty" ]; - ArbiterPoolContractConfig arbiter_pool_contract_config = 16 + ArbiterPoolContractConfig arbiter_pool_contract_config = 13 [ (gogoproto.jsontag) = "arbiter_pool_contract_config,omitempty" ]; } @@ -122,6 +141,14 @@ message ValsetContractConfig { (gogoproto.nullable) = false, (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec" ]; + + // When a validator joins the valset, verify they sign the first block since + // joining or jail them for a period otherwise. + // + // The verification happens every time the validator becomes an active + // validator, including when they are unjailed or when they just gain enough + // power to participate. + bool verify_validators = 12; } // EngagementContractConfig initial setup config diff --git a/proto/confio/twasm/v1beta1/genesis.proto b/proto/confio/twasm/v1beta1/genesis.proto index 77374c6c..643d6c46 100644 --- a/proto/confio/twasm/v1beta1/genesis.proto +++ b/proto/confio/twasm/v1beta1/genesis.proto @@ -4,21 +4,73 @@ package confio.twasm.v1beta1; import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; import "cosmwasm/wasm/v1/genesis.proto"; +import "cosmwasm/wasm/v1/types.proto"; +import "cosmwasm/wasm/v1/tx.proto"; option go_package = "github.com/confio/tgrade/x/twasm/types"; message GenesisState { - cosmwasm.wasm.v1.GenesisState wasm = 1 [ + // Params sdk type Params for wasmd + cosmwasm.wasm.v1.Params params = 1 [ (gogoproto.nullable) = false ]; + + // Codes has all stored wasm codes and metadata + repeated cosmwasm.wasm.v1.Code codes = 2 + [ (gogoproto.nullable) = false, (gogoproto.jsontag) = "codes,omitempty" ]; + + // Contracts contains all instantiated contracts, state and metadata + repeated Contract contracts = 3 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "contracts,omitempty" + ]; + + // Sequences names and values + repeated cosmwasm.wasm.v1.Sequence sequences = 4 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "sequences,omitempty" + ]; + + // GenMsgs has wasmd sdk type messages to execute in the genesis phase + repeated cosmwasm.wasm.v1.GenesisState.GenMsgs gen_msgs = 5 [ (gogoproto.nullable) = false, - (gogoproto.jsontag) = "wasm_genesis,omitempty" + (gogoproto.jsontag) = "gen_msgs,omitempty" ]; - repeated string privileged_contract_addresses = 2 + // PrivilegedContractAddresses is a list of contract addresses that can have + // special permissions + repeated string privileged_contract_addresses = 6 [ (gogoproto.jsontag) = "privileged_contract_addresses,omitempty" ]; - repeated uint64 pinned_code_ids = 3 [ + // PinnedCodeIDs has codeInfo ids for wasm codes that are pinned in cache + repeated uint64 pinned_code_ids = 7 [ (gogoproto.jsontag) = "pinned_code_ids,omitempty", (gogoproto.customname) = "PinnedCodeIDs" ]; } + +// Contract struct encompasses ContractAddress, ContractInfo, and ContractState +message Contract { + string contract_address = 1; + cosmwasm.wasm.v1.ContractInfo contract_info = 2 + [ (gogoproto.nullable) = false ]; + + // ContractSate is one of default wasmd Model or custom state model + oneof contract_state { + KVModel kv_model = 3; + CustomModel custom_model = 4; + } +} + +// KVModel is a wrapper around the wasmd default key value model. +message KVModel { + repeated cosmwasm.wasm.v1.Model models = 1 [ (gogoproto.nullable) = false ]; +} + +// CustomModel contains the raw json data for a contract to seed its state on +// import +message CustomModel { + // Msg json encoded message to be passed to the contract on import + bytes msg = 5 + [ (gogoproto.casttype) = + "github.com/CosmWasm/wasmd/x/wasm/types.RawContractMessage" ]; +} diff --git a/testing/genesis_mutators.go b/testing/genesis_mutators.go index 6aed5f9b..d4093b2c 100644 --- a/testing/genesis_mutators.go +++ b/testing/genesis_mutators.go @@ -43,10 +43,10 @@ func SetGlobalMinFee(t *testing.T, fees ...sdk.DecCoin) GenesisMutator { // SetAllEngagementPoints set the given value for all members of the engagement group (default = validators) func SetAllEngagementPoints(t *testing.T, points int) GenesisMutator { return func(raw []byte) []byte { - group := gjson.GetBytes(raw, "app_state.poe.engagement").Array() + group := gjson.GetBytes(raw, "app_state.poe.seed_contracts.engagement").Array() for i := range group { var err error - raw, err = sjson.SetRawBytes(raw, fmt.Sprintf("app_state.poe.engagement.%d.points", i), []byte(fmt.Sprintf(`"%d"`, points))) + raw, err = sjson.SetRawBytes(raw, fmt.Sprintf("app_state.poe.seed_contracts.engagement.%d.points", i), []byte(fmt.Sprintf(`"%d"`, points))) require.NoError(t, err) } return raw @@ -57,7 +57,7 @@ func SetAllEngagementPoints(t *testing.T, points int) GenesisMutator { func SetEpochLength(t *testing.T, epoch time.Duration) GenesisMutator { return func(genesis []byte) []byte { t.Helper() - state, err := sjson.SetRawBytes(genesis, "app_state.poe.valset_contract_config.epoch_length", []byte(fmt.Sprintf("%q", epoch))) + state, err := sjson.SetRawBytes(genesis, "app_state.poe.seed_contracts.valset_contract_config.epoch_length", []byte(fmt.Sprintf("%q", epoch))) require.NoError(t, err) return state } @@ -67,7 +67,7 @@ func SetEpochLength(t *testing.T, epoch time.Duration) GenesisMutator { func SetUnbondingPeriod(t *testing.T, unbonding time.Duration) GenesisMutator { return func(genesis []byte) []byte { t.Helper() - state, err := sjson.SetRawBytes(genesis, "app_state.poe.stake_contract_config.unbonding_period", []byte(fmt.Sprintf("%q", unbonding))) + state, err := sjson.SetRawBytes(genesis, "app_state.poe.seed_contracts.stake_contract_config.unbonding_period", []byte(fmt.Sprintf("%q", unbonding))) require.NoError(t, err) return state } @@ -79,7 +79,7 @@ func SetBlockRewards(t *testing.T, amount sdk.Coin) GenesisMutator { t.Helper() bz, err := json.Marshal(amount) require.NoError(t, err) - state, err := sjson.SetRawBytes(genesis, "app_state.poe.valset_contract_config.epoch_reward", bz) + state, err := sjson.SetRawBytes(genesis, "app_state.poe.seed_contracts.valset_contract_config.epoch_reward", bz) require.NoError(t, err) return state } diff --git a/testing/system.go b/testing/system.go index 9976c6fa..2fe83a1b 100644 --- a/testing/system.go +++ b/testing/system.go @@ -100,7 +100,7 @@ func (s *SystemUnderTest) SetupChain() { if err != nil { panic(fmt.Sprintf("failed to load genesis: %s", err)) } - genesisBz, err = sjson.SetRawBytes(genesisBz, "app_state.poe.valset_contract_config.epoch_length", []byte(fmt.Sprintf(`%q`, sutEpochDuration.String()))) + genesisBz, err = sjson.SetRawBytes(genesisBz, "app_state.poe.seed_contracts.valset_contract_config.epoch_length", []byte(fmt.Sprintf(`%q`, sutEpochDuration.String()))) if err != nil { panic(fmt.Sprintf("failed set epoche length: %s", err)) } diff --git a/x/poe/bootstrap.go b/x/poe/bootstrap.go index 3543972b..dc14c398 100644 --- a/x/poe/bootstrap.go +++ b/x/poe/bootstrap.go @@ -3,7 +3,6 @@ package poe import ( _ "embed" "encoding/json" - "errors" "fmt" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" @@ -62,7 +61,7 @@ type poeKeeper interface { // BootstrapPoEContracts stores and instantiates all PoE contracts: // See https://github.com/confio/tgrade-contracts/blob/main/docs/Architecture.md#multi-level-governance for an overview -func BootstrapPoEContracts(ctx sdk.Context, k wasmtypes.ContractOpsKeeper, tk twasmKeeper, poeKeeper poeKeeper, gs types.GenesisState) error { +func BootstrapPoEContracts(ctx sdk.Context, k wasmtypes.ContractOpsKeeper, tk twasmKeeper, poeKeeper poeKeeper, gs types.SeedContracts) error { systemAdminAddr, err := sdk.AccAddressFromBech32(gs.SystemAdminAddress) if err != nil { return sdkerrors.Wrap(err, "system admin") @@ -303,14 +302,6 @@ func BootstrapPoEContracts(ctx sdk.Context, k wasmtypes.ContractOpsKeeper, tk tw return sdkerrors.Wrap(err, "set new instance admin") } - // ensure setup constraints - ok, err := tk.HasPrivilegedContract(ctx, stakeContractAddr, twasmtypes.PrivilegeDelegator) - if err != nil { - panic(err) - } - if !ok { - panic("no contract with delegator privileges") - } return nil } @@ -360,7 +351,7 @@ func setAllPoEContractsInstanceMigrators(ctx sdk.Context, k wasmtypes.ContractOp } // build instantiate message for the trusted circle contract that contains the oversight committee -func newOCInitMsg(gs types.GenesisState) contract.TrustedCircleInitMsg { +func newOCInitMsg(gs types.SeedContracts) contract.TrustedCircleInitMsg { cfg := gs.OversightCommitteeContractConfig return contract.TrustedCircleInitMsg{ Name: cfg.Name, @@ -378,7 +369,7 @@ func newOCInitMsg(gs types.GenesisState) contract.TrustedCircleInitMsg { } // build instantiate message for OC Proposals contract -func newOCGovProposalsInitMsg(gs types.GenesisState, ocContract, engagementContract, valsetContract sdk.AccAddress) contract.OCProposalsInitMsg { +func newOCGovProposalsInitMsg(gs types.SeedContracts, ocContract, engagementContract, valsetContract sdk.AccAddress) contract.OCProposalsInitMsg { cfg := gs.OversightCommitteeContractConfig return contract.OCProposalsInitMsg{ GroupContractAddress: ocContract.String(), @@ -389,7 +380,7 @@ func newOCGovProposalsInitMsg(gs types.GenesisState, ocContract, engagementContr } // build instantiate message for the trusted circle contract that contains the arbiter pool -func newAPTrustedCircleInitMsg(gs types.GenesisState) contract.TrustedCircleInitMsg { +func newAPTrustedCircleInitMsg(gs types.SeedContracts) contract.TrustedCircleInitMsg { cfg := gs.ArbiterPoolContractConfig return contract.TrustedCircleInitMsg{ Name: cfg.Name, @@ -407,7 +398,7 @@ func newAPTrustedCircleInitMsg(gs types.GenesisState) contract.TrustedCircleInit } // build instantiate message for AP contract -func newArbiterPoolVotingInitMsg(gs types.GenesisState, apContract sdk.AccAddress) contract.APVotingInitMsg { +func newArbiterPoolVotingInitMsg(gs types.SeedContracts, apContract sdk.AccAddress) contract.APVotingInitMsg { cfg := gs.ArbiterPoolContractConfig return contract.APVotingInitMsg{ GroupContractAddress: apContract.String(), @@ -417,7 +408,7 @@ func newArbiterPoolVotingInitMsg(gs types.GenesisState, apContract sdk.AccAddres } } -func newEngagementInitMsg(gs types.GenesisState, adminAddr sdk.AccAddress) contract.TG4EngagementInitMsg { +func newEngagementInitMsg(gs types.SeedContracts, adminAddr sdk.AccAddress) contract.TG4EngagementInitMsg { tg4EngagementInitMsg := contract.TG4EngagementInitMsg{ Admin: adminAddr.String(), Members: make([]contract.TG4Member, len(gs.Engagement)), @@ -435,7 +426,7 @@ func newEngagementInitMsg(gs types.GenesisState, adminAddr sdk.AccAddress) contr return tg4EngagementInitMsg } -func newStakeInitMsg(gs types.GenesisState, adminAddr sdk.AccAddress) contract.TG4StakeInitMsg { +func newStakeInitMsg(gs types.SeedContracts, adminAddr sdk.AccAddress) contract.TG4StakeInitMsg { var claimLimit = uint64(gs.StakeContractConfig.ClaimAutoreturnLimit) return contract.TG4StakeInitMsg{ Admin: adminAddr.String(), @@ -450,7 +441,7 @@ func newStakeInitMsg(gs types.GenesisState, adminAddr sdk.AccAddress) contract.T } func newValsetInitMsg( - gs types.GenesisState, + gs types.SeedContracts, admin sdk.AccAddress, mixerContractAddr sdk.AccAddress, engagementAddr sdk.AccAddress, @@ -477,13 +468,62 @@ func newValsetInitMsg( } } -// verifyPoEContracts verifies all PoE contracts are setup as expected -func verifyPoEContracts(ctx sdk.Context, k wasmtypes.ContractOpsKeeper, tk twasmKeeper, poeKeeper poeKeeper, gs types.GenesisState) error { - return errors.New("not supported, yet") - // all poe contracts pinned - // valset privileged - // valset has registered for endblock valset update privilege - // admin set matches genesis system admin address for engagement and staking contract +// VerifyPoEContracts sanity check that verifies all PoE contracts are setup as expected +func VerifyPoEContracts(ctx sdk.Context, tk twasmKeeper, poeKeeper poeKeeper) error { + valVotingContractAddr, err := poeKeeper.GetPoEContractAddress(ctx, types.PoEContractTypeValidatorVoting) + if err != nil { + return sdkerrors.Wrap(err, "validator voting address") + } + types.IteratePoEContractTypes(func(tp types.PoEContractType) bool { + var addr sdk.AccAddress + addr, err = poeKeeper.GetPoEContractAddress(ctx, tp) + if err != nil { + return true + } + // migrator set to validator voting contract address + c := tk.GetContractInfo(ctx, addr) + if c == nil { + err = sdkerrors.Wrapf(types.ErrInvalid, "unknown contract: %s", addr) + return true + } + if c.Admin != valVotingContractAddr.String() { + err = sdkerrors.Wrapf(types.ErrInvalid, "admin address: %s", c.Admin) + return true + } + // all poe contracts pinned + if !tk.IsPinnedCode(ctx, c.CodeID) { + err = sdkerrors.Wrapf(types.ErrInvalid, "code not pinned for :%s", tp.String()) + return true + } + return false + }) + if err != nil { // return any error from within the iteration + return err + } + // verify PoE setup + addr, err := poeKeeper.GetPoEContractAddress(ctx, types.PoEContractTypeValset) + if err != nil { + return sdkerrors.Wrap(err, "valset addr") + } + switch ok, err := tk.HasPrivilegedContract(ctx, addr, twasmtypes.PrivilegeTypeValidatorSetUpdate); { + case err != nil: + return sdkerrors.Wrap(err, "valset contract") + case !ok: + return sdkerrors.Wrap(types.ErrInvalid, "valset contract not registered for validator updates") + } + // staking contract must be privileged and registered for delegations + stakeContractAddr, err := poeKeeper.GetPoEContractAddress(ctx, types.PoEContractTypeStaking) + if err != nil { + return sdkerrors.Wrap(err, "validator voting address") + } + ok, err := tk.HasPrivilegedContract(ctx, stakeContractAddr, twasmtypes.PrivilegeDelegator) + if err != nil { + return sdkerrors.Wrap(err, "staking contract") + } + if !ok { + return sdkerrors.Wrap(types.ErrInvalid, "no contract with delegator privileges") + } + return nil } // mustMarshalJson with stdlib json diff --git a/x/poe/bootstrap_integration_test.go b/x/poe/bootstrap_integration_test.go index 7868e9d0..77bbeac3 100644 --- a/x/poe/bootstrap_integration_test.go +++ b/x/poe/bootstrap_integration_test.go @@ -5,6 +5,9 @@ import ( "sort" "testing" + "github.com/cosmos/cosmos-sdk/types/address" + "github.com/tendermint/tendermint/libs/rand" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -110,10 +113,65 @@ func TestIntegrationBootstrapPoEContracts(t *testing.T) { switch tc.contractType { case types.PoEContractTypeOversightCommunity: - membersAreAllVotingMembers(t, ctx, gs.OversightCommunityMembers, contractAddr, example.TWasmKeeper) + membersAreAllVotingMembers(t, ctx, gs.GetSeedContracts().OversightCommunityMembers, contractAddr, example.TWasmKeeper) case types.PoEContractTypeArbiterPool: - membersAreAllVotingMembers(t, ctx, gs.ArbiterPoolMembers, contractAddr, example.TWasmKeeper) + membersAreAllVotingMembers(t, ctx, gs.GetSeedContracts().ArbiterPoolMembers, contractAddr, example.TWasmKeeper) + } + }) + } +} + +func TestVerifyPoEContracts(t *testing.T) { + // setup contracts and seed some data + parentCtx, example, _ := setupPoEContracts(t) + specs := map[string]struct { + alterState func(t *testing.T, ctx sdk.Context) + expErr bool + }{ + "all good": { + alterState: func(t *testing.T, ctx sdk.Context) {}, // noop + }, + "poe contract not pinned": { + alterState: func(t *testing.T, ctx sdk.Context) { + require.NoError(t, example.TWasmKeeper.GetContractKeeper().UnpinCode(ctx, 1)) + }, + expErr: true, + }, + "poe contract without correct migrator": { + alterState: func(t *testing.T, ctx sdk.Context) { + contractAddr, _ := example.PoEKeeper.GetPoEContractAddress(ctx, types.PoEContractTypeStaking) + valVotingAddr, _ := example.PoEKeeper.GetPoEContractAddress(ctx, types.PoEContractTypeValidatorVoting) + otherAddr := rand.Bytes(address.Len) + require.NoError(t, example.TWasmKeeper.GetContractKeeper().UpdateContractAdmin(ctx, contractAddr, valVotingAddr, otherAddr)) + }, + expErr: true, + }, + "without validator update privilege set": { + alterState: func(t *testing.T, ctx sdk.Context) { + otherContract, _ := example.PoEKeeper.GetPoEContractAddress(ctx, types.PoEContractTypeEngagement) + example.PoEKeeper.SetPoEContractAddress(ctx, types.PoEContractTypeValset, otherContract) + }, + expErr: true, + }, + "without delegator privilege set": { + alterState: func(t *testing.T, ctx sdk.Context) { + otherContract, _ := example.PoEKeeper.GetPoEContractAddress(ctx, types.PoEContractTypeEngagement) + example.PoEKeeper.SetPoEContractAddress(ctx, types.PoEContractTypeStaking, otherContract) + }, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + ctx, _ := parentCtx.CacheContext() + spec.alterState(t, ctx) + + gotErr := poe.VerifyPoEContracts(ctx, example.TWasmKeeper, example.PoEKeeper) + if spec.expErr { + require.Error(t, gotErr) + return } + require.NoError(t, gotErr) }) } } @@ -126,7 +184,7 @@ func setupPoEContracts(t *testing.T, mutators ...func(m *types.GenesisState)) (s mutator, _ := withRandomValidators(t, ctx, example, 3) gs := types.GenesisStateFixture(append([]func(m *types.GenesisState){mutator}, mutators...)...) - adminAddress, _ := sdk.AccAddressFromBech32(gs.SystemAdminAddress) + adminAddress, _ := sdk.AccAddressFromBech32(gs.GetSeedContracts().SystemAdminAddress) example.Faucet.Fund(ctx, adminAddress, sdk.NewCoin(types.DefaultBondDenom, sdk.NewInt(100_000_000_000))) fundMembers := func(members []string, coins sdk.Int) { @@ -137,12 +195,12 @@ func setupPoEContracts(t *testing.T, mutators ...func(m *types.GenesisState)) (s } } - fundMembers(gs.OversightCommunityMembers, sdk.NewInt(1_000_000)) - fundMembers(gs.ArbiterPoolMembers, sdk.NewInt(1_000_000)) + fundMembers(gs.GetSeedContracts().OversightCommunityMembers, sdk.NewInt(1_000_000)) + fundMembers(gs.GetSeedContracts().ArbiterPoolMembers, sdk.NewInt(1_000_000)) - genesisBz := example.EncodingConfig.Marshaler.MustMarshalJSON(&gs) + genesisBz := example.EncodingConfig.Marshaler.MustMarshalJSON(gs) module.InitGenesis(ctx, example.EncodingConfig.Marshaler, genesisBz) - return ctx, example, gs + return ctx, example, *gs } // unAuthorizedDeliverTXFn applies the TX without ante handler checks for testing purpose @@ -157,7 +215,6 @@ func unAuthorizedDeliverTXFn(t *testing.T, ctx sdk.Context, k keeper.Keeper, con msg := msgs[0].(*types.MsgCreateValidator) _, err = h(ctx, msg) require.NoError(t, err) - t.Logf("+++ create validator: %s\n", msg.OperatorAddress) return abci.ResponseDeliverTx{} } } @@ -167,8 +224,8 @@ func withRandomValidators(t *testing.T, ctx sdk.Context, example keeper.TestKeep collectValidators := make([]stakingtypes.Validator, numValidators) return func(m *types.GenesisState) { f := fuzz.New() - m.GenTxs = make([]json.RawMessage, numValidators) - m.Engagement = make([]types.TG4Member, numValidators) + m.GetSeedContracts().GenTxs = make([]json.RawMessage, numValidators) + m.GetSeedContracts().Engagement = make([]types.TG4Member, numValidators) for i := 0; i < numValidators; i++ { var ( // power * engagement must be less than 10^18 (constraint is in the contract) desc stakingtypes.Description @@ -195,8 +252,8 @@ func withRandomValidators(t *testing.T, ctx sdk.Context, example keeper.TestKeep m.DelegatorShares = sdk.OneDec() }) - m.GenTxs[i] = genTx - m.Engagement[i] = types.TG4Member{Address: opAddr.String(), Points: uint64(engagement)} + m.GetSeedContracts().GenTxs[i] = genTx + m.GetSeedContracts().Engagement[i] = types.TG4Member{Address: opAddr.String(), Points: uint64(engagement)} example.AccountKeeper.NewAccountWithAddress(ctx, opAddr) example.Faucet.Fund(ctx, opAddr, sdk.NewCoin(types.DefaultBondDenom, stakedAmount)) } diff --git a/x/poe/bootstrap_test.go b/x/poe/bootstrap_test.go index b2b9ed7f..588e74a7 100644 --- a/x/poe/bootstrap_test.go +++ b/x/poe/bootstrap_test.go @@ -261,10 +261,10 @@ func TestBootstrapPoEContracts(t *testing.T) { // when ctx := sdk.Context{}.WithLogger(log.TestingLogger()) genesis := types.GenesisStateFixture(func(m *types.GenesisState) { - m.SystemAdminAddress = mySystemAdmin - m.Engagement = []types.TG4Member{{Address: myUser, Points: 10}, {Address: myOtherUser, Points: 11}} + m.GetSeedContracts().SystemAdminAddress = mySystemAdmin + m.GetSeedContracts().Engagement = []types.TG4Member{{Address: myUser, Points: 10}, {Address: myOtherUser, Points: 11}} }) - gotErr := BootstrapPoEContracts(ctx, cm, tm, pm, genesis) + gotErr := BootstrapPoEContracts(ctx, cm, tm, pm, *genesis.GetSeedContracts()) // then require.NoError(t, gotErr) @@ -330,7 +330,7 @@ func TestCreateValsetInitMsg(t *testing.T) { systemAdmin := types.RandomAccAddress() specs := map[string]struct { - genesis types.GenesisState + genesis *types.GenesisState exp contract.ValsetInitMsg }{ "default": { @@ -355,7 +355,7 @@ func TestCreateValsetInitMsg(t *testing.T) { "fee percentage with comma value": { genesis: types.GenesisStateFixture(func(m *types.GenesisState) { var err error - m.ValsetContractConfig.FeePercentage, err = sdk.NewDecFromStr("50.1") + m.GetSeedContracts().ValsetContractConfig.FeePercentage, err = sdk.NewDecFromStr("50.1") require.NoError(t, err) }), exp: contract.ValsetInitMsg{ @@ -378,7 +378,7 @@ func TestCreateValsetInitMsg(t *testing.T) { "fee percentage with after comma value": { genesis: types.GenesisStateFixture(func(m *types.GenesisState) { var err error - m.ValsetContractConfig.FeePercentage, err = sdk.NewDecFromStr("0.1") + m.GetSeedContracts().ValsetContractConfig.FeePercentage, err = sdk.NewDecFromStr("0.1") require.NoError(t, err) }), exp: contract.ValsetInitMsg{ @@ -401,7 +401,7 @@ func TestCreateValsetInitMsg(t *testing.T) { "fee percentage with min comma value": { genesis: types.GenesisStateFixture(func(m *types.GenesisState) { var err error - m.ValsetContractConfig.FeePercentage, err = sdk.NewDecFromStr("0.0000000000000001") + m.GetSeedContracts().ValsetContractConfig.FeePercentage, err = sdk.NewDecFromStr("0.0000000000000001") require.NoError(t, err) }), exp: contract.ValsetInitMsg{ @@ -424,7 +424,7 @@ func TestCreateValsetInitMsg(t *testing.T) { } for name, spec := range specs { t.Run(name, func(t *testing.T) { - got := newValsetInitMsg(spec.genesis, systemAdmin, mixerContractAddr, engagementAddr, communityPoolAddr, engagementID) + got := newValsetInitMsg(*spec.genesis.GetSeedContracts(), systemAdmin, mixerContractAddr, engagementAddr, communityPoolAddr, engagementID) assert.Equal(t, spec.exp, got) }) } @@ -437,6 +437,8 @@ type twasmKeeperMock struct { SudoFn func(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) ([]byte, error) SetPrivilegedFn func(ctx sdk.Context, contractAddr sdk.AccAddress) error HasPrivilegedContractFn func(ctx sdk.Context, contractAddr sdk.AccAddress, privilegeType twasmtypes.PrivilegeType) (bool, error) + IsPinnedCodeFn func(ctx sdk.Context, codeID uint64) bool + GetContractInfoFn func(ctx sdk.Context, contractAddress sdk.AccAddress) *wasmtypes.ContractInfo } func (m twasmKeeperMock) GetContractKeeper() wasmtypes.ContractOpsKeeper { @@ -493,3 +495,17 @@ func CaptureHasPrivilegedContractFn(r *[]sdk.AccAddress) func(ctx sdk.Context, c return false, nil } } + +func (m twasmKeeperMock) IsPinnedCode(ctx sdk.Context, codeID uint64) bool { + if m.IsPinnedCodeFn == nil { + panic("not expected to be called") + } + return m.IsPinnedCodeFn(ctx, codeID) +} + +func (m twasmKeeperMock) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *wasmtypes.ContractInfo { + if m.GetContractInfoFn == nil { + panic("not expected to be called") + } + return m.GetContractInfoFn(ctx, contractAddress) +} diff --git a/x/poe/client/cli/genutil_gentx.go b/x/poe/client/cli/genutil_gentx.go index 247adf12..703639e0 100644 --- a/x/poe/client/cli/genutil_gentx.go +++ b/x/poe/client/cli/genutil_gentx.go @@ -269,7 +269,7 @@ func ValidateAccountInGenesis( addr sdk.Address, coins sdk.Coins, cdc codec.JSONCodec, ) error { gs := types.GetGenesisStateFromAppState(cdc, appGenesisState) - bondDenom := gs.BondDenom + bondDenom := gs.GetSeedContracts().BondDenom var err error accountIsInGenesis := false diff --git a/x/poe/client/cli/genutil_gentx_test.go b/x/poe/client/cli/genutil_gentx_test.go index 23065a8c..85141364 100644 --- a/x/poe/client/cli/genutil_gentx_test.go +++ b/x/poe/client/cli/genutil_gentx_test.go @@ -151,13 +151,13 @@ func setupSystem(t *testing.T, workDir string, encodingConfig appparams.Encoding // with PoE setup state := types.GetGenesisStateFromAppState(encodingConfig.Codec, gs) - state.BondDenom = bondDenum - state.Engagement = append(state.Engagement, types.TG4Member{ + state.GetSeedContracts().BondDenom = bondDenum + state.GetSeedContracts().Engagement = append(state.GetSeedContracts().Engagement, types.TG4Member{ Address: addr.String(), Points: 1, }) - state.OversightCommunityMembers = []string{types.RandomAccAddress().String()} - state.ArbiterPoolMembers = []string{types.RandomAccAddress().String()} + state.GetSeedContracts().OversightCommunityMembers = []string{types.RandomAccAddress().String()} + state.GetSeedContracts().ArbiterPoolMembers = []string{types.RandomAccAddress().String()} types.SetGenesisStateInAppState(encodingConfig.Codec, gs, state) // with bank setup diff --git a/x/poe/contract/common_test.go b/x/poe/contract/common_test.go index 7d047782..d48e4a9f 100644 --- a/x/poe/contract/common_test.go +++ b/x/poe/contract/common_test.go @@ -19,19 +19,20 @@ import ( "github.com/confio/tgrade/x/poe/types" ) -type ExampleValidator struct { - stakingtypes.Validator +func setupPoEContracts(t *testing.T, mutators ...func(m *types.GenesisState)) (sdk.Context, keeper.TestKeepers, []stakingtypes.Validator, []types.TG4Member) { + return setupPoEContractsNVal(t, 3, mutators...) } -func setupPoEContracts(t *testing.T, mutators ...func(m *types.GenesisState)) (sdk.Context, keeper.TestKeepers, []stakingtypes.Validator, []types.TG4Member) { +// setup with n validators +func setupPoEContractsNVal(t *testing.T, n int, mutators ...func(m *types.GenesisState)) (sdk.Context, keeper.TestKeepers, []stakingtypes.Validator, []types.TG4Member) { t.Helper() ctx, example := keeper.CreateDefaultTestInput(t) deliverTXFn := unAuthorizedDeliverTXFn(t, ctx, example.PoEKeeper, example.TWasmKeeper.GetContractKeeper(), example.EncodingConfig.TxConfig.TxDecoder()) module := poe.NewAppModule(example.PoEKeeper, example.TWasmKeeper, deliverTXFn, example.EncodingConfig.TxConfig, example.TWasmKeeper.GetContractKeeper()) - mutator, expValidators := withRandomValidators(t, ctx, example, 3) + mutator, expValidators := withRandomValidators(t, ctx, example, n) gs := types.GenesisStateFixture(append([]func(m *types.GenesisState){mutator}, mutators...)...) - adminAddress, _ := sdk.AccAddressFromBech32(gs.SystemAdminAddress) + adminAddress, _ := sdk.AccAddressFromBech32(gs.GetSeedContracts().SystemAdminAddress) example.Faucet.Fund(ctx, adminAddress, sdk.NewCoin(types.DefaultBondDenom, sdk.NewInt(100_000_000_000))) fundMembers := func(members []string, coins sdk.Int) { for _, member := range members { @@ -41,12 +42,12 @@ func setupPoEContracts(t *testing.T, mutators ...func(m *types.GenesisState)) (s } } - fundMembers(gs.OversightCommunityMembers, sdk.NewInt(1_000_000)) - fundMembers(gs.ArbiterPoolMembers, sdk.NewInt(1_000_000)) + fundMembers(gs.GetSeedContracts().OversightCommunityMembers, sdk.NewInt(1_000_000)) + fundMembers(gs.GetSeedContracts().ArbiterPoolMembers, sdk.NewInt(1_000_000)) - genesisBz := example.EncodingConfig.Marshaler.MustMarshalJSON(&gs) + genesisBz := example.EncodingConfig.Marshaler.MustMarshalJSON(gs) module.InitGenesis(ctx, example.EncodingConfig.Marshaler, genesisBz) - return ctx, example, expValidators, gs.Engagement + return ctx, example, expValidators, gs.GetSeedContracts().Engagement } // unAuthorizedDeliverTXFn applies the TX without ante handler checks for testing purpose @@ -61,7 +62,6 @@ func unAuthorizedDeliverTXFn(t *testing.T, ctx sdk.Context, k keeper.Keeper, con msg := msgs[0].(*types.MsgCreateValidator) _, err = h(ctx, msg) require.NoError(t, err) - t.Logf("+++ create validator: %s\n", msg.OperatorAddress) return abci.ResponseDeliverTx{} } } @@ -71,8 +71,8 @@ func withRandomValidators(t *testing.T, ctx sdk.Context, example keeper.TestKeep collectValidators := make([]stakingtypes.Validator, numValidators) return func(m *types.GenesisState) { f := fuzz.New() - m.GenTxs = make([]json.RawMessage, numValidators) - m.Engagement = make([]types.TG4Member, numValidators) + m.GetSeedContracts().GenTxs = make([]json.RawMessage, numValidators) + m.GetSeedContracts().Engagement = make([]types.TG4Member, numValidators) for i := 0; i < numValidators; i++ { var ( // power * engagement must be less than 10^18 (constraint is in the contract) desc stakingtypes.Description @@ -99,8 +99,8 @@ func withRandomValidators(t *testing.T, ctx sdk.Context, example keeper.TestKeep m.DelegatorShares = sdk.OneDec() }) - m.GenTxs[i] = genTx - m.Engagement[i] = types.TG4Member{Address: opAddr.String(), Points: uint64(engagement)} + m.GetSeedContracts().GenTxs[i] = genTx + m.GetSeedContracts().Engagement[i] = types.TG4Member{Address: opAddr.String(), Points: uint64(engagement)} example.AccountKeeper.NewAccountWithAddress(ctx, opAddr) example.Faucet.Fund(ctx, opAddr, sdk.NewCoin(types.DefaultBondDenom, stakedAmount)) } diff --git a/x/poe/contract/contractio.go b/x/poe/contract/contractio.go index fd78c182..94ccc8a7 100644 --- a/x/poe/contract/contractio.go +++ b/x/poe/contract/contractio.go @@ -1,6 +1,7 @@ package contract import ( + "bytes" "encoding/json" "strconv" "time" @@ -84,7 +85,7 @@ func CallEndBlockWithValidatorUpdate(ctx sdk.Context, contractAddr sdk.AccAddres result := make([]abci.ValidatorUpdate, len(contractResult.Diffs)) for i, v := range contractResult.Diffs { - pub, err := convertToTendermintPubKey(v.PubKey) + pub, err := ConvertToTendermintPubKey(v.PubKey) if err != nil { return nil, err } @@ -180,7 +181,7 @@ func SetEngagementPoints(ctx sdk.Context, contractAddr sdk.AccAddress, k types.S return sdkerrors.Wrap(err, "sudo") } -func convertToTendermintPubKey(key ValidatorPubkey) (crypto.PublicKey, error) { +func ConvertToTendermintPubKey(key ValidatorPubkey) (crypto.PublicKey, error) { switch { case key.Ed25519 != nil: return crypto.PublicKey{ @@ -226,7 +227,8 @@ func (a ContractAdapter) doExecute(ctx sdk.Context, msg interface{}, sender sdk. // PageableResult is a query response where the cursor is a subset of the raw last element. type PageableResult interface { - PaginationCursor() PaginationCursor + // PaginationCursor pagination cursor + PaginationCursor(raw []byte) (PaginationCursor, error) } // execute a smart query with the contract that returns multiple elements @@ -243,17 +245,16 @@ func (a ContractAdapter) doPageableQuery(ctx sdk.Context, query interface{}, res if err != nil { return nil, err } - if err := json.Unmarshal(res, result); err != nil { return nil, sdkerrors.Wrap(err, "unmarshal result") } - - var cursor PaginationCursor switch p := result.(type) { case PageableResult: - cursor = p.PaginationCursor() + // has cursor value + return p.PaginationCursor(res) } - return cursor, nil + // no pagination support (in tgrade, yet) + return nil, nil } // execute a smart query with the contract @@ -272,14 +273,44 @@ func (a ContractAdapter) doQuery(ctx sdk.Context, query interface{}, result inte return json.Unmarshal(res, result) } +// Address returns contract address +func (a ContractAdapter) Address() (sdk.AccAddress, error) { + return a.contractAddr, a.addressLookupErr +} + // PaginationCursor is the contracts "last element" as raw data that can be used to navigate through the result set. type PaginationCursor []byte +// Empty is nil or zero size +func (p PaginationCursor) Empty() bool { + return len(p) == 0 +} + +// String convert to string representation +func (p PaginationCursor) String() string { + if p.Empty() { + return "" + } + return string(p) +} + +func (p PaginationCursor) Equal(o PaginationCursor) bool { + return bytes.Equal(p, o) +} + type Paginator struct { StartAfter PaginationCursor `json:"start_after,omitempty"` Limit uint64 `json:"limit,omitempty"` } +// ToQuery converts to poe contract query format +func (p *Paginator) ToQuery() (string, int) { + if p == nil { + return "", 0 + } + return string(p.StartAfter), int(p.Limit) +} + // NewPaginator constructor func NewPaginator(pag *query.PageRequest) (*Paginator, error) { if pag == nil { diff --git a/x/poe/contract/contractio_test.go b/x/poe/contract/contractio_test.go index 21ace462..22decd85 100644 --- a/x/poe/contract/contractio_test.go +++ b/x/poe/contract/contractio_test.go @@ -40,7 +40,7 @@ func TestConvertToTendermintPubKey(t *testing.T) { }} for name, spec := range specs { t.Run(name, func(t *testing.T) { - gotRes, gotErr := convertToTendermintPubKey(spec.src) + gotRes, gotErr := ConvertToTendermintPubKey(spec.src) if spec.expErr { require.Error(t, gotErr) return diff --git a/x/poe/contract/tg4_stake.go b/x/poe/contract/tg4_stake.go index 5725a42d..674df9d2 100644 --- a/x/poe/contract/tg4_stake.go +++ b/x/poe/contract/tg4_stake.go @@ -183,3 +183,7 @@ func (v StakeContractAdapter) QueryStakingUnbonding(ctx sdk.Context, opAddr sdk. } return unbodings, nil } + +func (v StakeContractAdapter) Address() (sdk.AccAddress, error) { + return v.contractAddr, v.addressLookupErr +} diff --git a/x/poe/contract/tgrade_distribution.go b/x/poe/contract/tgrade_distribution.go index b1533230..d41ae714 100644 --- a/x/poe/contract/tgrade_distribution.go +++ b/x/poe/contract/tgrade_distribution.go @@ -40,3 +40,7 @@ func (d DistributionContractAdapter) ValidatorOutstandingReward(ctx sdk.Context, } return resp.Rewards, err } + +func (d DistributionContractAdapter) Address() (sdk.AccAddress, error) { + return d.contractAddr, d.addressLookupErr +} diff --git a/x/poe/contract/tgrade_distribution_integration_test.go b/x/poe/contract/tgrade_distribution_integration_test.go index b8035020..39d06103 100644 --- a/x/poe/contract/tgrade_distribution_integration_test.go +++ b/x/poe/contract/tgrade_distribution_integration_test.go @@ -36,7 +36,7 @@ func TestQueryWithdrawableFunds(t *testing.T) { }, "with rewards after epoch": { setup: func(ctx sdk.Context) sdk.Context { - ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultGenesisState().ValsetContractConfig.EpochLength)) + ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultGenesisState().GetSeedContracts().ValsetContractConfig.EpochLength)) poe.EndBlocker(ctx, example.TWasmKeeper) return ctx }, diff --git a/x/poe/contract/tgrade_valset.go b/x/poe/contract/tgrade_valset.go index f38bd588..69d700f0 100644 --- a/x/poe/contract/tgrade_valset.go +++ b/x/poe/contract/tgrade_valset.go @@ -299,17 +299,25 @@ type ListValidatorsResponse struct { Validators []OperatorResponse `json:"validators"` } -func (l ListValidatorsResponse) PaginationCursor() PaginationCursor { +// PaginationCursor implements PageableResult.PaginationCursor with a custom key which is implemented in the contract. +func (l ListValidatorsResponse) PaginationCursor(_ []byte) (PaginationCursor, error) { if len(l.Validators) == 0 { - return nil + return nil, nil } - return PaginationCursor(l.Validators[len(l.Validators)-1].Operator) + return PaginationCursor(l.Validators[len(l.Validators)-1].Operator), nil } type ListActiveValidatorsResponse struct { Validators []ValidatorInfo `json:"validators"` } +func (l ListActiveValidatorsResponse) PaginationCursor(_ []byte) (PaginationCursor, error) { + if len(l.Validators) == 0 { + return nil, nil + } + return PaginationCursor(l.Validators[len(l.Validators)-1].Operator), nil +} + type ListValidatorSlashingResponse struct { Operator string `json:"operator"` StartHeight uint64 `json:"start_height"` @@ -329,15 +337,6 @@ func QueryValsetEpoch(ctx sdk.Context, k types.SmartQuerier, valset sdk.AccAddre return &response, err } -// TODO: add pagination support -func ListActiveValidators(ctx sdk.Context, k types.SmartQuerier, valset sdk.AccAddress) ([]ValidatorInfo, error) { - // TODO: this is just a placeholder trying to get 100 - query := ValsetQuery{ListActiveValidators: &ListValidatorsQuery{Limit: 100}} - var response ListActiveValidatorsResponse - err := doQuery(ctx, k, valset, query, &response) - return response.Validators, err -} - func SimulateActiveValidators(ctx sdk.Context, k types.SmartQuerier, valset sdk.AccAddress) ([]ValidatorInfo, error) { query := ValsetQuery{SimulateActiveValidators: &struct{}{}} var response ListActiveValidatorsResponse @@ -384,12 +383,7 @@ func (v ValsetContractAdapter) QueryRawValidator(ctx sdk.Context, opAddr sdk.Acc // ListValidators query all validators func (v ValsetContractAdapter) ListValidators(ctx sdk.Context, pagination *Paginator) ([]stakingtypes.Validator, PaginationCursor, error) { - var startAfter string - var limit int - if pagination != nil { - startAfter = string(pagination.StartAfter) - limit = int(pagination.Limit) - } + startAfter, limit := pagination.ToQuery() query := ValsetQuery{ListValidators: &ListValidatorsQuery{StartAfter: startAfter, Limit: limit}} var rsp ListValidatorsResponse cursor, err := v.doPageableQuery(ctx, query, &rsp) @@ -409,6 +403,29 @@ func (v ValsetContractAdapter) ListValidators(ctx sdk.Context, pagination *Pagin return vals, cursor, nil } +// IterateActiveValidators iterate through the active validator set. +func (v ValsetContractAdapter) IterateActiveValidators(ctx sdk.Context, callback func(ValidatorInfo) bool, pagination *Paginator) error { + startAfter, limit := pagination.ToQuery() + var rsp ListActiveValidatorsResponse + cursor, err := v.doPageableQuery(ctx, ValsetQuery{ListActiveValidators: &ListValidatorsQuery{StartAfter: startAfter, Limit: limit}}, &rsp) + if err != nil { + return err + } + for !cursor.Empty() { + for _, v := range rsp.Validators { + if callback(v) { + return nil + } + } + newCursor, err := v.doPageableQuery(ctx, ValsetQuery{ListActiveValidators: &ListValidatorsQuery{StartAfter: cursor.String()}}, &rsp) + if err != nil { + return err + } + cursor = newCursor + } + return nil +} + func (v ValsetContractAdapter) ListValidatorSlashing(ctx sdk.Context, opAddr sdk.AccAddress) ([]ValidatorSlashing, error) { query := ValsetQuery{ListValidatorSlashing: &ValidatorQuery{Operator: opAddr.String()}} var rsp ListValidatorSlashingResponse diff --git a/x/poe/contract/tgrade_valset_integration_test.go b/x/poe/contract/tgrade_valset_integration_test.go index d0b1fbd5..42a4e878 100644 --- a/x/poe/contract/tgrade_valset_integration_test.go +++ b/x/poe/contract/tgrade_valset_integration_test.go @@ -286,5 +286,45 @@ func TestJailUnjail(t *testing.T) { assert.Empty(t, res.Validator.JailedUntil) }) } +} +func TestIterateActiveValidators(t *testing.T) { + specs := map[string]struct { + paginator *contract.Paginator + valCount int + }{ + "list single pages": { + paginator: &contract.Paginator{Limit: 30}, + valCount: 30, + }, + "list two pages": { + paginator: &contract.Paginator{Limit: 30}, + valCount: 31, + }, + "list all actives": { + paginator: &contract.Paginator{Limit: 30}, + valCount: 100, // set as max active in default genesis + }, + "list all actives with high limit": { + paginator: &contract.Paginator{Limit: 130}, + valCount: 100, + }, + "list all actives without paginator initialized": { + valCount: 100, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + ctx, example, genesisValidators, _ := setupPoEContractsNVal(t, spec.valCount) + assert.Equal(t, spec.valCount, len(genesisValidators)) + var gotVals []contract.ValidatorInfo + cb := func(c contract.ValidatorInfo) bool { + gotVals = append(gotVals, c) + return false + } + gotErr := example.PoEKeeper.ValsetContract(ctx).IterateActiveValidators(ctx, cb, spec.paginator) + require.NoError(t, gotErr) + assert.Equal(t, spec.valCount, len(gotVals)) + }) + } } diff --git a/x/poe/keeper/contracts.go b/x/poe/keeper/contracts.go index f53ff4de..d61c6763 100644 --- a/x/poe/keeper/contracts.go +++ b/x/poe/keeper/contracts.go @@ -13,6 +13,7 @@ import ( type DistributionContract interface { // ValidatorOutstandingReward returns amount or 0 for an unknown address ValidatorOutstandingReward(ctx sdk.Context, addr sdk.AccAddress) (sdk.Coin, error) + Address() (sdk.AccAddress, error) } func (k Keeper) DistributionContract(ctx sdk.Context) DistributionContract { @@ -26,6 +27,8 @@ type ValsetContract interface { ListValidatorSlashing(ctx sdk.Context, opAddr sdk.AccAddress) ([]contract.ValidatorSlashing, error) QueryConfig(ctx sdk.Context) (*contract.ValsetConfigResponse, error) UpdateAdmin(ctx sdk.Context, new sdk.AccAddress, sender sdk.AccAddress) error + IterateActiveValidators(ctx sdk.Context, callback func(c contract.ValidatorInfo) bool, pagination *contract.Paginator) error + Address() (sdk.AccAddress, error) } func (k Keeper) ValsetContract(ctx sdk.Context) ValsetContract { @@ -39,6 +42,7 @@ type StakeContract interface { QueryStakingUnbondingPeriod(ctx sdk.Context) (time.Duration, error) // QueryStakingUnbonding returns the unbondings or empty list for an unknown address QueryStakingUnbonding(ctx sdk.Context, opAddr sdk.AccAddress) ([]stakingtypes.UnbondingDelegationEntry, error) + Address() (sdk.AccAddress, error) } func (k Keeper) StakeContract(ctx sdk.Context) StakeContract { @@ -49,6 +53,7 @@ func (k Keeper) StakeContract(ctx sdk.Context) StakeContract { type EngagementContract interface { UpdateAdmin(ctx sdk.Context, newAdmin, sender sdk.AccAddress) error QueryDelegated(ctx sdk.Context, ownerAddr sdk.AccAddress) (*contract.DelegatedResponse, error) + Address() (sdk.AccAddress, error) } func (k Keeper) EngagementContract(ctx sdk.Context) EngagementContract { diff --git a/x/poe/keeper/genesis.go b/x/poe/keeper/genesis.go index 473b8e41..05a99ace 100644 --- a/x/poe/keeper/genesis.go +++ b/x/poe/keeper/genesis.go @@ -27,14 +27,18 @@ func InitGenesis( genesisState types.GenesisState, txEncodingConfig client.TxEncodingConfig, ) error { - // todo (Alex): set contract addresses when started from dump - //for _, v := range genesisState.Contracts { - // addr, _ := sdk.AccAddressFromBech32(v.Address) - // keeper.SetPoEContractAddress(ctx, v.ContractType, addr) - //} keeper.setParams(ctx, genesisState.Params) - if len(genesisState.GenTxs) > 0 { - if err := DeliverGenTxs(genesisState.GenTxs, deliverTx, txEncodingConfig); err != nil { + if genesisState.GetImportDump() != nil { + for _, v := range genesisState.GetImportDump().Contracts { + addr, err := sdk.AccAddressFromBech32(v.Address) + if err != nil { + return sdkerrors.Wrapf(err, "decode address: %s", v.Address) + } + keeper.SetPoEContractAddress(ctx, v.ContractType, addr) + } + } else if genesisState.GetSeedContracts() != nil { + // seed mode + if err := DeliverGenTxs(genesisState.GetSeedContracts().GenTxs, deliverTx, txEncodingConfig); err != nil { return sdkerrors.Wrap(err, "deliver gentx") } } @@ -67,20 +71,16 @@ func DeliverGenTxs(genTxs []json.RawMessage, deliverTx DeliverTxFn, txEncodingCo // ExportGenesis returns a GenesisState for a given context and keeper. func ExportGenesis(ctx sdk.Context, keeper Keeper) *types.GenesisState { - // todo (Alex): implement proper - //genState := types.GenesisState{ - // SeedContracts: false, - // SystemAdminAddress: keeper.GetPoESystemAdminAddress(ctx).String(), - // Contracts: make([]types.PoEContract, 0), - // todo:add other fields - //} - //keeper.IteratePoEContracts(ctx, func(Ctype types.PoEContractType, addr sdk.AccAddress) bool { - // genState.Contracts = append(genState.Contracts, types.PoEContract{ - // ContractType: Ctype, - // Address: addr.String(), - // }) - // return false - //}) - var genState types.GenesisState + genState := types.GenesisState{ + Params: keeper.GetParams(ctx), + SetupMode: &types.GenesisState_ImportDump{ImportDump: &types.ImportDump{}}, + } + keeper.IteratePoEContracts(ctx, func(Ctype types.PoEContractType, addr sdk.AccAddress) bool { + genState.GetImportDump().Contracts = append(genState.GetImportDump().Contracts, types.PoEContract{ + ContractType: Ctype, + Address: addr.String(), + }) + return false + }) return &genState } diff --git a/x/poe/keeper/genesis_test.go b/x/poe/keeper/genesis_test.go index 35213d9e..f8099669 100644 --- a/x/poe/keeper/genesis_test.go +++ b/x/poe/keeper/genesis_test.go @@ -4,6 +4,9 @@ import ( "encoding/json" "testing" + "github.com/cosmos/cosmos-sdk/types/address" + "github.com/tendermint/tendermint/libs/rand" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -18,7 +21,7 @@ func TestInitGenesis(t *testing.T) { txConfig := types.MakeEncodingConfig(t).TxConfig specs := map[string]struct { - src types.GenesisState + src *types.GenesisState respCode uint32 expErr bool expDeliveredGenTxCount int @@ -27,7 +30,7 @@ func TestInitGenesis(t *testing.T) { }{ "all good": { src: types.GenesisStateFixture(func(m *types.GenesisState) { - m.GenTxs = []json.RawMessage{[]byte(`{"body":{"messages":[{"@type":"/confio.poe.v1beta1.MsgCreateValidator","description":{"moniker":"moniker-0","identity":"","website":"","security_contact":"","details":""},"operator_address":"tgrade18katt8evmwr7g0w545g9kgrn2s6z9a0ky27gdp","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"P4qRtdI2pfl5IZN4cv28uuFhsRhSc/CBzrlB2/+ATQs="},"amount":{"denom":"utgd","amount":"100000000"},"vesting_amount":{"denom":"utgd","amount":"0"}}],"memo":"7973f9800a585f9a5e730ee18e4abab9a06214f5@192.168.178.24:16656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AlOUwEtcgY5rV6cJHCJJntNdrY9Kpe057pY6yewFbhxW"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"0","payer":"","granter":""}},"signatures":["cJnG18yHwWsgxjh1Kqf3j/MFv7OpX69c7VLQz1MX1qtndFIylSNPVbkXOMu2i+Ufy52nXH3yujOKsMIVLP62pg=="]}`)} + m.GetSeedContracts().GenTxs = []json.RawMessage{[]byte(`{"body":{"messages":[{"@type":"/confio.poe.v1beta1.MsgCreateValidator","description":{"moniker":"moniker-0","identity":"","website":"","security_contact":"","details":""},"operator_address":"tgrade18katt8evmwr7g0w545g9kgrn2s6z9a0ky27gdp","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"P4qRtdI2pfl5IZN4cv28uuFhsRhSc/CBzrlB2/+ATQs="},"amount":{"denom":"utgd","amount":"100000000"},"vesting_amount":{"denom":"utgd","amount":"0"}}],"memo":"7973f9800a585f9a5e730ee18e4abab9a06214f5@192.168.178.24:16656","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AlOUwEtcgY5rV6cJHCJJntNdrY9Kpe057pY6yewFbhxW"},"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"sequence":"0"}],"fee":{"amount":[],"gas_limit":"0","payer":"","granter":""}},"signatures":["cJnG18yHwWsgxjh1Kqf3j/MFv7OpX69c7VLQz1MX1qtndFIylSNPVbkXOMu2i+Ufy52nXH3yujOKsMIVLP62pg=="]}`)} }, ), expDeliveredGenTxCount: 1, @@ -35,7 +38,7 @@ func TestInitGenesis(t *testing.T) { }, "deliver genTX failed": { src: types.GenesisStateFixture(func(m *types.GenesisState) { - m.GenTxs = []json.RawMessage{[]byte(`{}`)} + m.GetSeedContracts().GenTxs = []json.RawMessage{[]byte(`{}`)} }), expErr: true, expDeliveredGenTxCount: 1, @@ -57,7 +60,7 @@ func TestInitGenesis(t *testing.T) { capaturedParams = params }, } - gotErr := InitGenesis(ctx, m, captureTx, spec.src, txConfig) + gotErr := InitGenesis(ctx, m, captureTx, *spec.src, txConfig) if spec.expErr { require.Error(t, gotErr) return @@ -125,6 +128,35 @@ func TestDeliverGenTxs(t *testing.T) { } } +func TestExportGenesis(t *testing.T) { + ctx, example := CreateDefaultTestInput(t) + k := example.PoEKeeper + + storedAddr := make(map[types.PoEContractType]sdk.AccAddress) + types.IteratePoEContractTypes(func(tp types.PoEContractType) bool { + var addr sdk.AccAddress = rand.Bytes(address.Len) + k.SetPoEContractAddress(ctx, tp, addr) + storedAddr[tp] = addr + return false + }) + + // when + gs := ExportGenesis(ctx, k) + + // then + require.NotNil(t, gs) + expParams := types.DefaultParams() + expParams.MinDelegationAmounts = nil + assert.Equal(t, expParams, gs.Params) + require.Len(t, gs.GetImportDump().Contracts, len(storedAddr)) + for _, v := range gs.GetImportDump().Contracts { + assert.Equal(t, storedAddr[v.ContractType].String(), v.Address) + delete(storedAddr, v.ContractType) + } + // ensure no duplicates + assert.Empty(t, storedAddr) +} + func initBech32Prefixes() { const Bech32Prefix = "tgrade" config := sdk.GetConfig() diff --git a/x/poe/keeper/keeper.go b/x/poe/keeper/keeper.go index 16f1206b..d80164e4 100644 --- a/x/poe/keeper/keeper.go +++ b/x/poe/keeper/keeper.go @@ -53,7 +53,7 @@ func (k Keeper) SetPoEContractAddress(ctx sdk.Context, ctype types.PoEContractTy store.Set(poeContractAddressKey(ctype), contractAddr.Bytes()) } -// GetPoEContractAddress get the stored contract address for the given type +// GetPoEContractAddress get the stored contract address for the given type or returns an error when not exists (yet) func (k Keeper) GetPoEContractAddress(ctx sdk.Context, ctype types.PoEContractType) (sdk.AccAddress, error) { if err := ctype.ValidateBasic(); err != nil { return nil, sdkerrors.Wrap(err, "contract type") diff --git a/x/poe/keeper/poetesting/mock_contracts.go b/x/poe/keeper/poetesting/mock_contracts.go index b48b9e34..255e926b 100644 --- a/x/poe/keeper/poetesting/mock_contracts.go +++ b/x/poe/keeper/poetesting/mock_contracts.go @@ -13,6 +13,7 @@ import ( type DistributionContractMock struct { ValidatorOutstandingRewardFn func(ctx sdk.Context, addr sdk.AccAddress) (sdk.Coin, error) + AddressFn func() (sdk.AccAddress, error) } func (m DistributionContractMock) ValidatorOutstandingReward(ctx sdk.Context, addr sdk.AccAddress) (sdk.Coin, error) { @@ -22,14 +23,30 @@ func (m DistributionContractMock) ValidatorOutstandingReward(ctx sdk.Context, ad return m.ValidatorOutstandingRewardFn(ctx, addr) } +func (m DistributionContractMock) Address() (sdk.AccAddress, error) { + if m.AddressFn == nil { + panic("not expected to be called") + } + return m.AddressFn() +} + // var _ keeper.ValsetContract = ValsetContractMock{} type ValsetContractMock struct { - QueryValidatorFn func(ctx sdk.Context, opAddr sdk.AccAddress) (*stakingtypes.Validator, error) - ListValidatorsFn func(ctx sdk.Context, pagination *contract.Paginator) ([]stakingtypes.Validator, contract.PaginationCursor, error) - QueryConfigFn func(ctx sdk.Context) (*contract.ValsetConfigResponse, error) - ListValidatorSlashingFn func(ctx sdk.Context, opAddr sdk.AccAddress) ([]contract.ValidatorSlashing, error) - UpdateAdminFn func(ctx sdk.Context, new sdk.AccAddress, sender sdk.AccAddress) error + QueryValidatorFn func(ctx sdk.Context, opAddr sdk.AccAddress) (*stakingtypes.Validator, error) + ListValidatorsFn func(ctx sdk.Context, pagination *contract.Paginator) ([]stakingtypes.Validator, contract.PaginationCursor, error) + QueryConfigFn func(ctx sdk.Context) (*contract.ValsetConfigResponse, error) + ListValidatorSlashingFn func(ctx sdk.Context, opAddr sdk.AccAddress) ([]contract.ValidatorSlashing, error) + UpdateAdminFn func(ctx sdk.Context, new sdk.AccAddress, sender sdk.AccAddress) error + IterateActiveValidatorsFn func(ctx sdk.Context, callback func(c contract.ValidatorInfo) bool, pagination *contract.Paginator) error + AddressFn func() (sdk.AccAddress, error) +} + +func (m ValsetContractMock) IterateActiveValidators(ctx sdk.Context, callback func(c contract.ValidatorInfo) bool, pagination *contract.Paginator) error { + if m.IterateActiveValidatorsFn == nil { + panic("not expected to be called") + } + return m.IterateActiveValidatorsFn(ctx, callback, pagination) } func (m ValsetContractMock) UpdateAdmin(ctx sdk.Context, new sdk.AccAddress, sender sdk.AccAddress) error { @@ -67,12 +84,20 @@ func (m ValsetContractMock) ListValidatorSlashing(ctx sdk.Context, opAddr sdk.Ac return m.ListValidatorSlashingFn(ctx, opAddr) } +func (m ValsetContractMock) Address() (sdk.AccAddress, error) { + if m.AddressFn == nil { + panic("not expected to be called") + } + return m.AddressFn() +} + // var _ keeper.StakeContract = StakeContractMock{} type StakeContractMock struct { QueryStakingUnbondingPeriodFn func(ctx sdk.Context) (time.Duration, error) QueryStakingUnbondingFn func(ctx sdk.Context, opAddr sdk.AccAddress) ([]stakingtypes.UnbondingDelegationEntry, error) QueryStakedAmountFn func(ctx sdk.Context, opAddr sdk.AccAddress) (*sdk.Int, error) + AddressFn func() (sdk.AccAddress, error) } func (m StakeContractMock) QueryStakedAmount(ctx sdk.Context, opAddr sdk.AccAddress) (*sdk.Int, error) { @@ -94,12 +119,19 @@ func (m StakeContractMock) QueryStakingUnbonding(ctx sdk.Context, opAddr sdk.Acc } return m.QueryStakingUnbondingFn(ctx, opAddr) } +func (m StakeContractMock) Address() (sdk.AccAddress, error) { + if m.AddressFn == nil { + panic("not expected to be called") + } + return m.AddressFn() +} // var _ keeper.EngagementContract = EngagementContractMock{} type EngagementContractMock struct { UpdateAdminFn func(ctx sdk.Context, newAdmin, sender sdk.AccAddress) error QueryDelegatedFn func(ctx sdk.Context, ownerAddr sdk.AccAddress) (*contract.DelegatedResponse, error) + AddressFn func() (sdk.AccAddress, error) } func (m EngagementContractMock) UpdateAdmin(ctx sdk.Context, newAdmin, sender sdk.AccAddress) error { @@ -115,3 +147,10 @@ func (m EngagementContractMock) QueryDelegated(ctx sdk.Context, ownerAddr sdk.Ac } return m.QueryDelegatedFn(ctx, ownerAddr) } + +func (m EngagementContractMock) Address() (sdk.AccAddress, error) { + if m.AddressFn == nil { + panic("not expected to be called") + } + return m.AddressFn() +} diff --git a/x/poe/keeper/test_common.go b/x/poe/keeper/test_common.go index 346d1296..f92f149e 100644 --- a/x/poe/keeper/test_common.go +++ b/x/poe/keeper/test_common.go @@ -238,6 +238,7 @@ func createTestInput( &twasmKeeper, accountKeeper, ) + poeKeeper.setParams(ctx, types.DefaultParams()) ibcKeeper := ibckeeper.NewKeeper( appCodec, diff --git a/x/poe/module.go b/x/poe/module.go index e7def927..169e1b13 100644 --- a/x/poe/module.go +++ b/x/poe/module.go @@ -5,12 +5,13 @@ import ( "encoding/json" "fmt" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/module" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" @@ -56,8 +57,7 @@ func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) // DefaultGenesis returns default genesis state as raw bytes for the genutil // module. func (b AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - gs := types.DefaultGenesisState() - return cdc.MustMarshalJSON(&gs) + return cdc.MustMarshalJSON(types.DefaultGenesisState()) } // ValidateGenesis performs genesis state validation for the genutil module. @@ -109,6 +109,8 @@ type twasmKeeper interface { endBlockKeeper SetPrivileged(ctx sdk.Context, contractAddr sdk.AccAddress) error HasPrivilegedContract(ctx sdk.Context, contractAddr sdk.AccAddress, privilegeType twasmtypes.PrivilegeType) (bool, error) + IsPinnedCode(ctx sdk.Context, codeID uint64) bool + GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *wasmtypes.ContractInfo } // NewAppModule creates a new AppModule object @@ -162,44 +164,58 @@ func (am AppModule) EndBlock(ctx sdk.Context, block abci.RequestEndBlock) []abci func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { var genesisState types.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - if len(genesisState.GenTxs) == 0 { - panic(sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty gentx")) - } - if genesisState.SeedContracts { - if err := BootstrapPoEContracts(ctx, am.contractKeeper, am.twasmKeeper, am.poeKeeper, genesisState); err != nil { - panic(fmt.Sprintf("bootstrap PoE contracts: %+v", err)) + seedMode := genesisState.GetSeedContracts() != nil + if seedMode { + if len(genesisState.GetSeedContracts().GenTxs) == 0 { + panic(sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty gentx")) } - } else { - if err := verifyPoEContracts(ctx, am.contractKeeper, am.twasmKeeper, am.poeKeeper, genesisState); err != nil { - panic(fmt.Sprintf("verify PoE bootstrap contracts: %+v", err)) + if err := BootstrapPoEContracts(ctx, am.contractKeeper, am.twasmKeeper, am.poeKeeper, *genesisState.GetSeedContracts()); err != nil { + panic(fmt.Sprintf("bootstrap PoE contracts: %+v", err)) } } - if err := keeper.InitGenesis(ctx, am.poeKeeper, am.deliverTx, genesisState, am.txEncodingConfig); err != nil { panic(err) } + // verify PoE setup + if err := VerifyPoEContracts(ctx, am.twasmKeeper, am.poeKeeper); err != nil { + panic(fmt.Sprintf("verify PoE bootstrap contracts: %+v", err)) + } + addr, err := am.poeKeeper.GetPoEContractAddress(ctx, types.PoEContractTypeValset) if err != nil { panic(fmt.Sprintf("valset addr: %s", err)) } - switch ok, err := am.twasmKeeper.HasPrivilegedContract(ctx, addr, twasmtypes.PrivilegeTypeValidatorSetUpdate); { - case err != nil: - panic(fmt.Sprintf("valset contract: %s", err)) - case !ok: - panic(fmt.Sprintf("valset contract not registered for valdator updates: %s", addr.String())) + if seedMode { + // query validators from PoE for initial abci set + switch initialSet, err := contract.CallEndBlockWithValidatorUpdate(ctx, addr, am.twasmKeeper); { + case err != nil: + panic(fmt.Sprintf("poe sudo call: %s", err)) + case len(initialSet) == 0: + panic("initial valset must not be empty") + default: + return initialSet + } } - - // query validators from PoE for initial abci set - switch diff, err := contract.CallEndBlockWithValidatorUpdate(ctx, addr, am.twasmKeeper); { - case err != nil: - panic(fmt.Sprintf("poe sudo call: %s", err)) - case len(diff) == 0: - panic("initial valset must not be empty") - default: - return diff + // in dump import mode + // query and return the active validator set + var activeSet []abci.ValidatorUpdate + am.poeKeeper.ValsetContract(ctx).IterateActiveValidators(ctx, func(c contract.ValidatorInfo) bool { + pub, err := contract.ConvertToTendermintPubKey(c.ValidatorPubkey) + if err != nil { + panic(fmt.Sprintf("convert pubkey for %s", c.Operator)) + } + activeSet = append(activeSet, abci.ValidatorUpdate{ + PubKey: pub, + Power: int64(c.Power), + }) + return false + }, nil) + if len(activeSet) == 0 { // fal fast + panic("active valset must not be empty") } + return activeSet } // ExportGenesis returns the exported genesis state as raw bytes for the genutil diff --git a/x/poe/module_test.go b/x/poe/module_test.go index b6e0627f..f0c6ae2c 100644 --- a/x/poe/module_test.go +++ b/x/poe/module_test.go @@ -37,7 +37,7 @@ func TestInitGenesis(t *testing.T) { const numValidators = 15 mutator, myValidators := withRandomValidators(t, ctx, example, numValidators) gs := types.GenesisStateFixture(mutator) - adminAddr, _ := sdk.AccAddressFromBech32(gs.SystemAdminAddress) + adminAddr, _ := sdk.AccAddressFromBech32(gs.GetSeedContracts().SystemAdminAddress) example.Faucet.Fund(ctx, adminAddr, sdk.NewCoin(types.DefaultBondDenom, sdk.NewInt(100_000_000_000))) fundMembers := func(members []string, coins sdk.Int) { @@ -48,11 +48,11 @@ func TestInitGenesis(t *testing.T) { } } - fundMembers(gs.OversightCommunityMembers, sdk.NewInt(1_000_000)) - fundMembers(gs.ArbiterPoolMembers, sdk.NewInt(1_000_000)) + fundMembers(gs.GetSeedContracts().OversightCommunityMembers, sdk.NewInt(1_000_000)) + fundMembers(gs.GetSeedContracts().ArbiterPoolMembers, sdk.NewInt(1_000_000)) // when - genesisBz := example.EncodingConfig.Marshaler.MustMarshalJSON(&gs) + genesisBz := example.EncodingConfig.Marshaler.MustMarshalJSON(gs) gotValset := app.InitGenesis(ctx, example.EncodingConfig.Marshaler, genesisBz) // then valset diff matches @@ -168,8 +168,8 @@ func withRandomValidators(t *testing.T, ctx sdk.Context, example keeper.TestKeep collectValidators := make(validators, numValidators) return func(m *types.GenesisState) { f := fuzz.New() - m.GenTxs = make([]json.RawMessage, numValidators) - m.Engagement = make([]types.TG4Member, numValidators) + m.GetSeedContracts().GenTxs = make([]json.RawMessage, numValidators) + m.GetSeedContracts().Engagement = make([]types.TG4Member, numValidators) for i := 0; i < numValidators; i++ { var ( // power * engagement must be less than 10^18 (constraint is in the contract) power uint16 @@ -186,8 +186,8 @@ func withRandomValidators(t *testing.T, ctx sdk.Context, example keeper.TestKeep stakedAmount: stakedAmount, engagement: uint64(engagement), } - m.GenTxs[i] = genTx - m.Engagement[i] = types.TG4Member{Address: opAddr.String(), Points: uint64(engagement)} + m.GetSeedContracts().GenTxs[i] = genTx + m.GetSeedContracts().Engagement[i] = types.TG4Member{Address: opAddr.String(), Points: uint64(engagement)} example.AccountKeeper.NewAccountWithAddress(ctx, opAddr) example.Faucet.Fund(ctx, opAddr, sdk.NewCoin(types.DefaultBondDenom, sdk.NewIntFromUint64(stakedAmount))) } diff --git a/x/poe/types/genesis.go b/x/poe/types/genesis.go index 84492ac6..732a012f 100644 --- a/x/poe/types/genesis.go +++ b/x/poe/types/genesis.go @@ -1,7 +1,6 @@ package types import ( - "errors" "time" "github.com/cosmos/cosmos-sdk/types/address" @@ -15,160 +14,159 @@ import ( const DefaultBondDenom = "utgd" // DefaultGenesisState default values -func DefaultGenesisState() GenesisState { - return GenesisState{ - SeedContracts: true, - BondDenom: DefaultBondDenom, - StakeContractConfig: &StakeContractConfig{ - MinBond: 1, - TokensPerPoint: 1, - UnbondingPeriod: time.Hour * 21 * 24, - ClaimAutoreturnLimit: 20, - }, - ValsetContractConfig: &ValsetContractConfig{ - MinPoints: 1, - MaxValidators: 100, - EpochLength: 60 * time.Second, - EpochReward: sdk.NewCoin(DefaultBondDenom, sdk.NewInt(100_000)), - Scaling: 1, - FeePercentage: sdk.NewDec(50), - AutoUnjail: false, - DoubleSignSlashRatio: sdk.NewDec(50), - ValidatorRewardRatio: sdk.MustNewDecFromStr("47.5"), - EngagementRewardRatio: sdk.MustNewDecFromStr("47.5"), - CommunityPoolRewardRatio: sdk.MustNewDecFromStr("5"), - }, - EngagementContractConfig: &EngagementContractConfig{ - Halflife: 180 * 24 * time.Hour, - }, - OversightCommitteeContractConfig: &OversightCommitteeContractConfig{ - Name: "Oversight Community", - EscrowAmount: sdk.NewCoin(DefaultBondDenom, sdk.NewInt(1_000_000)), - VotingRules: VotingRules{ - VotingPeriod: 30, - Quorum: sdk.NewDec(51), - Threshold: sdk.NewDec(55), - AllowEndEarly: true, +func DefaultGenesisState() *GenesisState { + return &GenesisState{ + Params: DefaultParams(), + SetupMode: &GenesisState_SeedContracts{&SeedContracts{ + BondDenom: DefaultBondDenom, + StakeContractConfig: &StakeContractConfig{ + MinBond: 1, + TokensPerPoint: 1, + UnbondingPeriod: time.Hour * 21 * 24, + ClaimAutoreturnLimit: 20, }, - }, - CommunityPoolContractConfig: &CommunityPoolContractConfig{ - VotingRules: VotingRules{ - VotingPeriod: 21, - Quorum: sdk.NewDec(10), - Threshold: sdk.NewDec(60), - AllowEndEarly: true, + ValsetContractConfig: &ValsetContractConfig{ + MinPoints: 1, + MaxValidators: 100, + EpochLength: 60 * time.Second, + EpochReward: sdk.NewCoin(DefaultBondDenom, sdk.NewInt(100_000)), + Scaling: 1, + FeePercentage: sdk.NewDec(50), + AutoUnjail: false, + DoubleSignSlashRatio: sdk.NewDec(50), + ValidatorRewardRatio: sdk.MustNewDecFromStr("47.5"), + EngagementRewardRatio: sdk.MustNewDecFromStr("47.5"), + CommunityPoolRewardRatio: sdk.MustNewDecFromStr("5"), + VerifyValidators: true, }, - }, - ValidatorVotingContractConfig: &ValidatorVotingContractConfig{ - VotingRules: VotingRules{ - VotingPeriod: 14, - Quorum: sdk.NewDec(40), - Threshold: sdk.NewDec(66), - AllowEndEarly: true, + EngagementContractConfig: &EngagementContractConfig{ + Halflife: 180 * 24 * time.Hour, }, - }, - ArbiterPoolContractConfig: &ArbiterPoolContractConfig{ - Name: "Arbiter Pool", - EscrowAmount: sdk.NewCoin(DefaultBondDenom, sdk.NewInt(1_000_000)), - VotingRules: VotingRules{ - VotingPeriod: 30, - Quorum: sdk.NewDec(51), - Threshold: sdk.NewDec(55), - AllowEndEarly: true, + OversightCommitteeContractConfig: &OversightCommitteeContractConfig{ + Name: "Oversight Community", + EscrowAmount: sdk.NewCoin(DefaultBondDenom, sdk.NewInt(1_000_000)), + VotingRules: VotingRules{ + VotingPeriod: 30, + Quorum: sdk.NewDec(51), + Threshold: sdk.NewDec(55), + AllowEndEarly: true, + }, + }, + CommunityPoolContractConfig: &CommunityPoolContractConfig{ + VotingRules: VotingRules{ + VotingPeriod: 21, + Quorum: sdk.NewDec(10), + Threshold: sdk.NewDec(60), + AllowEndEarly: true, + }, + }, + ValidatorVotingContractConfig: &ValidatorVotingContractConfig{ + VotingRules: VotingRules{ + VotingPeriod: 14, + Quorum: sdk.NewDec(40), + Threshold: sdk.NewDec(66), + AllowEndEarly: true, + }, }, - DisputeCost: sdk.NewCoin(DefaultBondDenom, sdk.NewInt(1_000_000)), + ArbiterPoolContractConfig: &ArbiterPoolContractConfig{ + Name: "Arbiter Pool", + EscrowAmount: sdk.NewCoin(DefaultBondDenom, sdk.NewInt(1_000_000)), + VotingRules: VotingRules{ + VotingPeriod: 30, + Quorum: sdk.NewDec(51), + Threshold: sdk.NewDec(55), + AllowEndEarly: true, + }, + DisputeCost: sdk.NewCoin(DefaultBondDenom, sdk.NewInt(1_000_000)), + }, + SystemAdminAddress: sdk.AccAddress(rand.Bytes(address.Len)).String(), + }, }, - SystemAdminAddress: sdk.AccAddress(rand.Bytes(address.Len)).String(), - Params: DefaultParams(), } } +// ValidateGenesis validates genesis for PoE module func ValidateGenesis(g GenesisState, txJSONDecoder sdk.TxDecoder) error { - if g.SeedContracts { - if len(g.Contracts) != 0 { - return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "seed enabled but PoE contracts addresses provided") - } - if len(g.Engagement) == 0 { - return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty engagement group") - } - if g.EngagementContractConfig == nil { - return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty engagement contract config") - } - if err := g.EngagementContractConfig.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "engagement contract config") + if err := g.Params.Validate(); err != nil { + return sdkerrors.Wrap(err, "params") + } + switch { + case g.GetSeedContracts() != nil && g.GetImportDump() != nil: + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "both seed and import data setup") + case g.GetSeedContracts() == nil && g.GetImportDump() == nil: + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "neither seed or import data setup") + case g.GetSeedContracts() != nil: + if err := validateSeedContracts(g.GetSeedContracts(), txJSONDecoder); err != nil { + return sdkerrors.Wrap(err, "seed contracts") } - if err := sdk.ValidateDenom(g.BondDenom); err != nil { - return sdkerrors.Wrap(err, "bond denom") + case g.GetImportDump() != nil: + if err := g.GetImportDump().ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "import dump") } + } + return nil +} - if g.ValsetContractConfig == nil { - return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty valset contract config") - } - if err := g.ValsetContractConfig.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "valset contract config") - } +// validate SeedContract genesis type only +func validateSeedContracts(g *SeedContracts, txJSONDecoder sdk.TxDecoder) error { + if len(g.Engagement) == 0 { + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty engagement group") + } + if g.EngagementContractConfig == nil { + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty engagement contract config") + } + if err := g.EngagementContractConfig.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "engagement contract config") + } + if err := sdk.ValidateDenom(g.BondDenom); err != nil { + return sdkerrors.Wrap(err, "bond denom") + } - if g.StakeContractConfig == nil { - return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty stake contract config") - } - if err := g.StakeContractConfig.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "stake contract config") - } - if g.ValsetContractConfig.EpochReward.Denom != g.BondDenom { - return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "rewards not in bonded denom") - } + if g.ValsetContractConfig == nil { + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty valset contract config") + } + if err := g.ValsetContractConfig.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "valset contract config") + } - if g.OversightCommitteeContractConfig == nil { - return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty oversight committee contract config") - } - if err := g.OversightCommitteeContractConfig.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "oversight committee config") - } - if g.ArbiterPoolContractConfig == nil { - return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty arbiter pool contract config") - } - if err := g.ArbiterPoolContractConfig.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "arbiter pool config") - } - if g.OversightCommitteeContractConfig.EscrowAmount.Denom != g.BondDenom { - return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "escrow not in bonded denom") - } - if g.CommunityPoolContractConfig == nil { - return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty community pool contract config") - } - if err := g.CommunityPoolContractConfig.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "community pool config") - } - if g.ValidatorVotingContractConfig == nil { - return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty validator voting contract config") - } - if err := g.ValidatorVotingContractConfig.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "validator voting config") - } - } else { - return errors.New("not supported, yet") - //if len(g.Contracts) == 0 { - // return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "seed disabled but no PoE contract addresses provided") - //} - // todo (Alex): if we preserve state in the engagement contract then we need to ensure that there are no - // new members in the engagement group - // if we can reset state then the engagement group must not be empty - //if len(g.Engagement) != 0 { - // return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "engagement group set") - //} - //uniqueContractTypes := make(map[PoEContractType]struct{}, len(g.Contracts)) - //for i, v := range g.Contracts { - // if err := v.ValidateBasic(); err != nil { - // return sdkerrors.Wrapf(err, "contract %d", i) - // } - // if _, exists := uniqueContractTypes[v.ContractType]; exists { - // return sdkerrors.Wrapf(wasmtypes.ErrDuplicate, "contract type %s", v.ContractType.String()) - // } - //} - //if len(uniqueContractTypes) != len(PoEContractType_name)-1 { - // return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "PoE contract(s) missing") - //} + if g.StakeContractConfig == nil { + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty stake contract config") + } + if err := g.StakeContractConfig.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "stake contract config") + } + if g.ValsetContractConfig.EpochReward.Denom != g.BondDenom { + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "rewards not in bonded denom") + } + + if g.OversightCommitteeContractConfig == nil { + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty oversight committee contract config") + } + if err := g.OversightCommitteeContractConfig.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "oversight committee config") + } + if g.ArbiterPoolContractConfig == nil { + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty arbiter pool contract config") + } + if err := g.ArbiterPoolContractConfig.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "arbiter pool config") + } + if g.OversightCommitteeContractConfig.EscrowAmount.Denom != g.BondDenom { + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "escrow not in bonded denom") + } + if g.CommunityPoolContractConfig == nil { + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty community pool contract config") + } + if err := g.CommunityPoolContractConfig.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "community pool config") } + if g.ValidatorVotingContractConfig == nil { + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "empty validator voting contract config") + } + if err := g.ValidatorVotingContractConfig.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "validator voting config") + } + if _, err := sdk.AccAddressFromBech32(g.SystemAdminAddress); err != nil { return sdkerrors.Wrap(err, "system admin address") } @@ -183,7 +181,6 @@ func ValidateGenesis(g GenesisState, txJSONDecoder sdk.TxDecoder) error { } uniqueEngagementMembers[v.Address] = struct{}{} } - uniqueOperators := make(map[string]struct{}, len(g.GenTxs)) uniquePubKeys := make(map[string]struct{}, len(g.GenTxs)) for i, v := range g.GenTxs { @@ -243,7 +240,6 @@ func ValidateGenesis(g GenesisState, txJSONDecoder sdk.TxDecoder) error { } uniqueAPMembers[member] = struct{}{} } - return nil } @@ -413,3 +409,21 @@ func (c ArbiterPoolContractConfig) ValidateBasic() error { } return nil } + +// ValidateBasic ensure basic constraints +func (g ImportDump) ValidateBasic() error { + uniqueContractTypes := make(map[PoEContractType]struct{}, len(g.Contracts)) + for i, v := range g.Contracts { + if err := v.ValidateBasic(); err != nil { + return sdkerrors.Wrapf(err, "contract %d", i) + } + if _, exists := uniqueContractTypes[v.ContractType]; exists { + return sdkerrors.Wrapf(wasmtypes.ErrDuplicate, "contract type %s", v.ContractType.String()) + } + uniqueContractTypes[v.ContractType] = struct{}{} + } + if len(uniqueContractTypes) != len(PoEContractType_name)-1 { + return sdkerrors.Wrap(wasmtypes.ErrInvalidGenesis, "PoE contract(s) missing") + } + return nil +} diff --git a/x/poe/types/genesis.pb.go b/x/poe/types/genesis.pb.go index f43c5e1d..bfb6d1e1 100644 --- a/x/poe/types/genesis.pb.go +++ b/x/poe/types/genesis.pb.go @@ -36,31 +36,14 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type GenesisState struct { // params defines all the parameter of the module Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - // SeedContracts when enabled stores and instantiates the Proof of Engagement - // contracts on the chain. - SeedContracts bool `protobuf:"varint,2,opt,name=seed_contracts,json=seedContracts,proto3" json:"seed_contracts,omitempty"` - // GenTxs defines the genesis transactions to create a validator. - GenTxs []encoding_json.RawMessage `protobuf:"bytes,3,rep,name=gen_txs,json=genTxs,proto3,casttype=encoding/json.RawMessage" json:"gentxs" yaml:"gentxs"` - // SystemAdminAddress single address that is set as admin for the PoE - // contracts in seed mode. - SystemAdminAddress string `protobuf:"bytes,4,opt,name=system_admin_address,json=systemAdminAddress,proto3" json:"system_admin_address,omitempty"` - // Contracts Poe contract addresses and types when used with state dump in non - // seed mode. - Contracts []PoEContract `protobuf:"bytes,5,rep,name=contracts,proto3" json:"contracts,omitempty"` - // Engagement weighted members of the engagement group. Validators should be - // in here. - Engagement []TG4Member `protobuf:"bytes,6,rep,name=engagement,proto3" json:"engagement,omitempty"` - StakeContractConfig *StakeContractConfig `protobuf:"bytes,7,opt,name=stake_contract_config,json=stakeContractConfig,proto3" json:"stake_contract_config,omitempty"` - ValsetContractConfig *ValsetContractConfig `protobuf:"bytes,8,opt,name=valset_contract_config,json=valsetContractConfig,proto3" json:"valset_contract_config,omitempty"` - EngagementContractConfig *EngagementContractConfig `protobuf:"bytes,9,opt,name=engagement_contract_config,json=engagementContractConfig,proto3" json:"engagement_contract_config,omitempty"` - // BondDenom defines the bondable coin denomination. - BondDenom string `protobuf:"bytes,10,opt,name=bond_denom,json=bondDenom,proto3" json:"bond_denom,omitempty" yaml:"bond_denom"` - OversightCommitteeContractConfig *OversightCommitteeContractConfig `protobuf:"bytes,11,opt,name=oversight_committee_contract_config,json=oversightCommitteeContractConfig,proto3" json:"oversight_committee_contract_config,omitempty"` - CommunityPoolContractConfig *CommunityPoolContractConfig `protobuf:"bytes,12,opt,name=community_pool_contract_config,json=communityPoolContractConfig,proto3" json:"community_pool_contract_config,omitempty"` - ValidatorVotingContractConfig *ValidatorVotingContractConfig `protobuf:"bytes,13,opt,name=validator_voting_contract_config,json=validatorVotingContractConfig,proto3" json:"validator_voting_contract_config,omitempty"` - OversightCommunityMembers []string `protobuf:"bytes,14,rep,name=oversightCommunityMembers,proto3" json:"oversight_community_members,omitempty"` - ArbiterPoolMembers []string `protobuf:"bytes,15,rep,name=arbiterPoolMembers,proto3" json:"arbiter_pool_members,omitempty"` - ArbiterPoolContractConfig *ArbiterPoolContractConfig `protobuf:"bytes,16,opt,name=arbiter_pool_contract_config,json=arbiterPoolContractConfig,proto3" json:"arbiter_pool_contract_config,omitempty"` + // SetupMode defines which scenario to apply on a genesis import. + // Either it is a fresh chain that needs PoE contracts bootstrapped or + // the module state has to be restored from a previous state dump. + // + // Types that are valid to be assigned to SetupMode: + // *GenesisState_SeedContracts + // *GenesisState_ImportDump + SetupMode isGenesisState_SetupMode `protobuf_oneof:"setup_mode"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -96,6 +79,29 @@ func (m *GenesisState) XXX_DiscardUnknown() { var xxx_messageInfo_GenesisState proto.InternalMessageInfo +type isGenesisState_SetupMode interface { + isGenesisState_SetupMode() + MarshalTo([]byte) (int, error) + Size() int +} + +type GenesisState_SeedContracts struct { + SeedContracts *SeedContracts `protobuf:"bytes,2,opt,name=seed_contracts,json=seedContracts,proto3,oneof" json:"seed_contracts,omitempty"` +} +type GenesisState_ImportDump struct { + ImportDump *ImportDump `protobuf:"bytes,3,opt,name=import_dump,json=importDump,proto3,oneof" json:"import_dump,omitempty"` +} + +func (*GenesisState_SeedContracts) isGenesisState_SetupMode() {} +func (*GenesisState_ImportDump) isGenesisState_SetupMode() {} + +func (m *GenesisState) GetSetupMode() isGenesisState_SetupMode { + if m != nil { + return m.SetupMode + } + return nil +} + func (m *GenesisState) GetParams() Params { if m != nil { return m.Params @@ -103,105 +109,216 @@ func (m *GenesisState) GetParams() Params { return Params{} } -func (m *GenesisState) GetSeedContracts() bool { - if m != nil { - return m.SeedContracts +func (m *GenesisState) GetSeedContracts() *SeedContracts { + if x, ok := m.GetSetupMode().(*GenesisState_SeedContracts); ok { + return x.SeedContracts } - return false + return nil } -func (m *GenesisState) GetGenTxs() []encoding_json.RawMessage { - if m != nil { - return m.GenTxs +func (m *GenesisState) GetImportDump() *ImportDump { + if x, ok := m.GetSetupMode().(*GenesisState_ImportDump); ok { + return x.ImportDump } return nil } -func (m *GenesisState) GetSystemAdminAddress() string { - if m != nil { - return m.SystemAdminAddress +// XXX_OneofWrappers is for the internal use of the proto package. +func (*GenesisState) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*GenesisState_SeedContracts)(nil), + (*GenesisState_ImportDump)(nil), } - return "" } -func (m *GenesisState) GetContracts() []PoEContract { +// ImportDump has all module data for non seed mode. +type ImportDump struct { + // Contracts PoE contract addresses and types + Contracts []PoEContract `protobuf:"bytes,1,rep,name=contracts,proto3" json:"contracts,omitempty"` +} + +func (m *ImportDump) Reset() { *m = ImportDump{} } +func (m *ImportDump) String() string { return proto.CompactTextString(m) } +func (*ImportDump) ProtoMessage() {} +func (*ImportDump) Descriptor() ([]byte, []int) { + return fileDescriptor_a165193bab811d9d, []int{1} +} +func (m *ImportDump) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ImportDump) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ImportDump.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ImportDump) XXX_Merge(src proto.Message) { + xxx_messageInfo_ImportDump.Merge(m, src) +} +func (m *ImportDump) XXX_Size() int { + return m.Size() +} +func (m *ImportDump) XXX_DiscardUnknown() { + xxx_messageInfo_ImportDump.DiscardUnknown(m) +} + +var xxx_messageInfo_ImportDump proto.InternalMessageInfo + +func (m *ImportDump) GetContracts() []PoEContract { if m != nil { return m.Contracts } return nil } -func (m *GenesisState) GetEngagement() []TG4Member { +// SeedContracts contains the contract configuration and group members to setup +// all PoE contracts on chain. +type SeedContracts struct { + // GenTxs defines the genesis transactions to create a validator. + GenTxs []encoding_json.RawMessage `protobuf:"bytes,1,rep,name=gen_txs,json=genTxs,proto3,casttype=encoding/json.RawMessage" json:"gentxs" yaml:"gentxs"` + // SystemAdminAddress single address that is set as admin for the PoE + // contracts in seed mode. + SystemAdminAddress string `protobuf:"bytes,2,opt,name=system_admin_address,json=systemAdminAddress,proto3" json:"system_admin_address,omitempty"` + // Engagement weighted members of the engagement group. Validators should be + // in here. + Engagement []TG4Member `protobuf:"bytes,3,rep,name=engagement,proto3" json:"engagement,omitempty"` + StakeContractConfig *StakeContractConfig `protobuf:"bytes,4,opt,name=stake_contract_config,json=stakeContractConfig,proto3" json:"stake_contract_config,omitempty"` + ValsetContractConfig *ValsetContractConfig `protobuf:"bytes,5,opt,name=valset_contract_config,json=valsetContractConfig,proto3" json:"valset_contract_config,omitempty"` + EngagementContractConfig *EngagementContractConfig `protobuf:"bytes,6,opt,name=engagement_contract_config,json=engagementContractConfig,proto3" json:"engagement_contract_config,omitempty"` + // BondDenom defines the bondable coin denomination. + BondDenom string `protobuf:"bytes,7,opt,name=bond_denom,json=bondDenom,proto3" json:"bond_denom,omitempty" yaml:"bond_denom"` + OversightCommitteeContractConfig *OversightCommitteeContractConfig `protobuf:"bytes,8,opt,name=oversight_committee_contract_config,json=oversightCommitteeContractConfig,proto3" json:"oversight_committee_contract_config,omitempty"` + CommunityPoolContractConfig *CommunityPoolContractConfig `protobuf:"bytes,9,opt,name=community_pool_contract_config,json=communityPoolContractConfig,proto3" json:"community_pool_contract_config,omitempty"` + ValidatorVotingContractConfig *ValidatorVotingContractConfig `protobuf:"bytes,10,opt,name=validator_voting_contract_config,json=validatorVotingContractConfig,proto3" json:"validator_voting_contract_config,omitempty"` + OversightCommunityMembers []string `protobuf:"bytes,11,rep,name=oversightCommunityMembers,proto3" json:"oversight_community_members,omitempty"` + ArbiterPoolMembers []string `protobuf:"bytes,12,rep,name=arbiterPoolMembers,proto3" json:"arbiter_pool_members,omitempty"` + ArbiterPoolContractConfig *ArbiterPoolContractConfig `protobuf:"bytes,13,opt,name=arbiter_pool_contract_config,json=arbiterPoolContractConfig,proto3" json:"arbiter_pool_contract_config,omitempty"` +} + +func (m *SeedContracts) Reset() { *m = SeedContracts{} } +func (m *SeedContracts) String() string { return proto.CompactTextString(m) } +func (*SeedContracts) ProtoMessage() {} +func (*SeedContracts) Descriptor() ([]byte, []int) { + return fileDescriptor_a165193bab811d9d, []int{2} +} +func (m *SeedContracts) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SeedContracts) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SeedContracts.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SeedContracts) XXX_Merge(src proto.Message) { + xxx_messageInfo_SeedContracts.Merge(m, src) +} +func (m *SeedContracts) XXX_Size() int { + return m.Size() +} +func (m *SeedContracts) XXX_DiscardUnknown() { + xxx_messageInfo_SeedContracts.DiscardUnknown(m) +} + +var xxx_messageInfo_SeedContracts proto.InternalMessageInfo + +func (m *SeedContracts) GetGenTxs() []encoding_json.RawMessage { + if m != nil { + return m.GenTxs + } + return nil +} + +func (m *SeedContracts) GetSystemAdminAddress() string { + if m != nil { + return m.SystemAdminAddress + } + return "" +} + +func (m *SeedContracts) GetEngagement() []TG4Member { if m != nil { return m.Engagement } return nil } -func (m *GenesisState) GetStakeContractConfig() *StakeContractConfig { +func (m *SeedContracts) GetStakeContractConfig() *StakeContractConfig { if m != nil { return m.StakeContractConfig } return nil } -func (m *GenesisState) GetValsetContractConfig() *ValsetContractConfig { +func (m *SeedContracts) GetValsetContractConfig() *ValsetContractConfig { if m != nil { return m.ValsetContractConfig } return nil } -func (m *GenesisState) GetEngagementContractConfig() *EngagementContractConfig { +func (m *SeedContracts) GetEngagementContractConfig() *EngagementContractConfig { if m != nil { return m.EngagementContractConfig } return nil } -func (m *GenesisState) GetBondDenom() string { +func (m *SeedContracts) GetBondDenom() string { if m != nil { return m.BondDenom } return "" } -func (m *GenesisState) GetOversightCommitteeContractConfig() *OversightCommitteeContractConfig { +func (m *SeedContracts) GetOversightCommitteeContractConfig() *OversightCommitteeContractConfig { if m != nil { return m.OversightCommitteeContractConfig } return nil } -func (m *GenesisState) GetCommunityPoolContractConfig() *CommunityPoolContractConfig { +func (m *SeedContracts) GetCommunityPoolContractConfig() *CommunityPoolContractConfig { if m != nil { return m.CommunityPoolContractConfig } return nil } -func (m *GenesisState) GetValidatorVotingContractConfig() *ValidatorVotingContractConfig { +func (m *SeedContracts) GetValidatorVotingContractConfig() *ValidatorVotingContractConfig { if m != nil { return m.ValidatorVotingContractConfig } return nil } -func (m *GenesisState) GetOversightCommunityMembers() []string { +func (m *SeedContracts) GetOversightCommunityMembers() []string { if m != nil { return m.OversightCommunityMembers } return nil } -func (m *GenesisState) GetArbiterPoolMembers() []string { +func (m *SeedContracts) GetArbiterPoolMembers() []string { if m != nil { return m.ArbiterPoolMembers } return nil } -func (m *GenesisState) GetArbiterPoolContractConfig() *ArbiterPoolContractConfig { +func (m *SeedContracts) GetArbiterPoolContractConfig() *ArbiterPoolContractConfig { if m != nil { return m.ArbiterPoolContractConfig } @@ -220,7 +337,7 @@ func (m *StakeContractConfig) Reset() { *m = StakeContractConfig{} } func (m *StakeContractConfig) String() string { return proto.CompactTextString(m) } func (*StakeContractConfig) ProtoMessage() {} func (*StakeContractConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_a165193bab811d9d, []int{1} + return fileDescriptor_a165193bab811d9d, []int{3} } func (m *StakeContractConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -303,13 +420,20 @@ type ValsetContractConfig struct { // DoubleSignSlashRatio Validators who are caught double signing are jailed // forever and their bonded tokens are slashed based on this value. DoubleSignSlashRatio github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,11,opt,name=double_sign_slash_ratio,json=doubleSignSlashRatio,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"double_sign_slash_ratio"` + // When a validator joins the valset, verify they sign the first block since + // joining or jail them for a period otherwise. + // + // The verification happens every time the validator becomes an active + // validator, including when they are unjailed or when they just gain enough + // power to participate. + VerifyValidators bool `protobuf:"varint,12,opt,name=verify_validators,json=verifyValidators,proto3" json:"verify_validators,omitempty"` } func (m *ValsetContractConfig) Reset() { *m = ValsetContractConfig{} } func (m *ValsetContractConfig) String() string { return proto.CompactTextString(m) } func (*ValsetContractConfig) ProtoMessage() {} func (*ValsetContractConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_a165193bab811d9d, []int{2} + return fileDescriptor_a165193bab811d9d, []int{4} } func (m *ValsetContractConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -380,6 +504,13 @@ func (m *ValsetContractConfig) GetAutoUnjail() bool { return false } +func (m *ValsetContractConfig) GetVerifyValidators() bool { + if m != nil { + return m.VerifyValidators + } + return false +} + // EngagementContractConfig initial setup config type EngagementContractConfig struct { Halflife time.Duration `protobuf:"bytes,1,opt,name=halflife,proto3,stdduration" json:"halflife"` @@ -389,7 +520,7 @@ func (m *EngagementContractConfig) Reset() { *m = EngagementContractConf func (m *EngagementContractConfig) String() string { return proto.CompactTextString(m) } func (*EngagementContractConfig) ProtoMessage() {} func (*EngagementContractConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_a165193bab811d9d, []int{3} + return fileDescriptor_a165193bab811d9d, []int{5} } func (m *EngagementContractConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -442,7 +573,7 @@ func (m *OversightCommitteeContractConfig) Reset() { *m = OversightCommi func (m *OversightCommitteeContractConfig) String() string { return proto.CompactTextString(m) } func (*OversightCommitteeContractConfig) ProtoMessage() {} func (*OversightCommitteeContractConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_a165193bab811d9d, []int{4} + return fileDescriptor_a165193bab811d9d, []int{6} } func (m *OversightCommitteeContractConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -509,7 +640,7 @@ func (m *CommunityPoolContractConfig) Reset() { *m = CommunityPoolContra func (m *CommunityPoolContractConfig) String() string { return proto.CompactTextString(m) } func (*CommunityPoolContractConfig) ProtoMessage() {} func (*CommunityPoolContractConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_a165193bab811d9d, []int{5} + return fileDescriptor_a165193bab811d9d, []int{7} } func (m *CommunityPoolContractConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -555,7 +686,7 @@ func (m *ValidatorVotingContractConfig) Reset() { *m = ValidatorVotingCo func (m *ValidatorVotingContractConfig) String() string { return proto.CompactTextString(m) } func (*ValidatorVotingContractConfig) ProtoMessage() {} func (*ValidatorVotingContractConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_a165193bab811d9d, []int{6} + return fileDescriptor_a165193bab811d9d, []int{8} } func (m *ValidatorVotingContractConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -603,7 +734,7 @@ func (m *PoEContract) Reset() { *m = PoEContract{} } func (m *PoEContract) String() string { return proto.CompactTextString(m) } func (*PoEContract) ProtoMessage() {} func (*PoEContract) Descriptor() ([]byte, []int) { - return fileDescriptor_a165193bab811d9d, []int{7} + return fileDescriptor_a165193bab811d9d, []int{9} } func (m *PoEContract) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -657,7 +788,7 @@ func (m *TG4Member) Reset() { *m = TG4Member{} } func (m *TG4Member) String() string { return proto.CompactTextString(m) } func (*TG4Member) ProtoMessage() {} func (*TG4Member) Descriptor() ([]byte, []int) { - return fileDescriptor_a165193bab811d9d, []int{8} + return fileDescriptor_a165193bab811d9d, []int{10} } func (m *TG4Member) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -718,7 +849,7 @@ func (m *VotingRules) Reset() { *m = VotingRules{} } func (m *VotingRules) String() string { return proto.CompactTextString(m) } func (*VotingRules) ProtoMessage() {} func (*VotingRules) Descriptor() ([]byte, []int) { - return fileDescriptor_a165193bab811d9d, []int{9} + return fileDescriptor_a165193bab811d9d, []int{11} } func (m *VotingRules) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -781,7 +912,7 @@ func (m *ArbiterPoolContractConfig) Reset() { *m = ArbiterPoolContractCo func (m *ArbiterPoolContractConfig) String() string { return proto.CompactTextString(m) } func (*ArbiterPoolContractConfig) ProtoMessage() {} func (*ArbiterPoolContractConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_a165193bab811d9d, []int{10} + return fileDescriptor_a165193bab811d9d, []int{12} } func (m *ArbiterPoolContractConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -854,6 +985,8 @@ func (m *ArbiterPoolContractConfig) GetWaitingPeriod() time.Duration { func init() { proto.RegisterType((*GenesisState)(nil), "confio.poe.v1beta1.GenesisState") + proto.RegisterType((*ImportDump)(nil), "confio.poe.v1beta1.ImportDump") + proto.RegisterType((*SeedContracts)(nil), "confio.poe.v1beta1.SeedContracts") proto.RegisterType((*StakeContractConfig)(nil), "confio.poe.v1beta1.StakeContractConfig") proto.RegisterType((*ValsetContractConfig)(nil), "confio.poe.v1beta1.ValsetContractConfig") proto.RegisterType((*EngagementContractConfig)(nil), "confio.poe.v1beta1.EngagementContractConfig") @@ -869,105 +1002,110 @@ func init() { func init() { proto.RegisterFile("confio/poe/v1beta1/genesis.proto", fileDescriptor_a165193bab811d9d) } var fileDescriptor_a165193bab811d9d = []byte{ - // 1566 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0xbf, 0x6f, 0xdb, 0x46, - 0x1b, 0x36, 0x63, 0x47, 0x96, 0x4e, 0x96, 0x93, 0xef, 0xe2, 0x24, 0xb4, 0x1d, 0x8b, 0x82, 0x9c, - 0xe4, 0xd3, 0x17, 0x24, 0xd2, 0xe7, 0x7c, 0x06, 0xbe, 0xa2, 0x05, 0x5a, 0x58, 0xb6, 0x93, 0xa0, - 0x70, 0x5a, 0x83, 0x4e, 0x32, 0x24, 0x03, 0x71, 0x12, 0xcf, 0xd4, 0x25, 0xe4, 0x9d, 0xc2, 0x3b, - 0xc9, 0xd6, 0x56, 0xa0, 0x1d, 0x3b, 0x74, 0xe8, 0x50, 0x74, 0xe8, 0xd0, 0xb1, 0x7f, 0x40, 0xff, - 0x86, 0x8c, 0x19, 0x8b, 0x0e, 0x6c, 0x90, 0x2c, 0x85, 0xa6, 0x22, 0x63, 0xa7, 0xe2, 0x8e, 0x94, - 0x44, 0x49, 0x94, 0x7f, 0xa1, 0x53, 0x17, 0x9b, 0xbc, 0xbb, 0xe7, 0x79, 0x9f, 0xf7, 0xe5, 0xcb, - 0x7b, 0x8e, 0x02, 0x85, 0x3a, 0xa3, 0xfb, 0x84, 0x55, 0x9a, 0x0c, 0x57, 0xda, 0x6b, 0x35, 0x2c, - 0xd0, 0x5a, 0xc5, 0xc1, 0x14, 0x73, 0xc2, 0xcb, 0x4d, 0x9f, 0x09, 0x06, 0x61, 0xb8, 0xa2, 0xdc, - 0x64, 0xb8, 0x1c, 0xad, 0x58, 0x5a, 0x70, 0x98, 0xc3, 0xd4, 0x74, 0x45, 0x5e, 0x85, 0x2b, 0x97, - 0xf2, 0x75, 0xc6, 0x3d, 0xc6, 0x2b, 0x35, 0xc4, 0x07, 0x64, 0x75, 0x46, 0x68, 0x7c, 0xfe, 0x00, - 0x71, 0xaf, 0xa2, 0xfe, 0xb4, 0x47, 0x22, 0x2d, 0x5d, 0x4b, 0xd0, 0x22, 0xa3, 0x46, 0x68, 0x87, - 0x31, 0xc7, 0xc5, 0x15, 0x75, 0x57, 0x6b, 0xed, 0x57, 0xec, 0x96, 0x8f, 0x04, 0x61, 0x11, 0x7b, - 0xf1, 0xf7, 0x1c, 0x98, 0xbb, 0x1f, 0xf2, 0xed, 0x09, 0x24, 0x30, 0xfc, 0x00, 0xa4, 0x9a, 0xc8, - 0x47, 0x1e, 0xd7, 0xb5, 0x82, 0x56, 0xca, 0xde, 0x5d, 0x2a, 0x8f, 0x67, 0x52, 0xde, 0x55, 0x2b, - 0xaa, 0x33, 0xaf, 0x02, 0x63, 0xca, 0x8c, 0xd6, 0xc3, 0x1b, 0x60, 0x9e, 0x63, 0x6c, 0x5b, 0x75, - 0x46, 0x85, 0x8f, 0xea, 0x82, 0xeb, 0xe7, 0x0a, 0x5a, 0x29, 0x6d, 0xe6, 0xe4, 0xe8, 0x66, 0x6f, - 0x10, 0xee, 0x82, 0x59, 0x07, 0x53, 0x4b, 0x1c, 0x72, 0x7d, 0xba, 0x30, 0x5d, 0x9a, 0xab, 0xfe, - 0xbf, 0x1b, 0x18, 0x29, 0x07, 0x53, 0x71, 0xc8, 0xdf, 0x07, 0x46, 0xae, 0x83, 0x3c, 0xf7, 0xc3, - 0x62, 0x78, 0x5f, 0xfc, 0x33, 0x30, 0x74, 0x4c, 0xeb, 0xcc, 0x26, 0xd4, 0xa9, 0x3c, 0xe7, 0x8c, - 0x96, 0x4d, 0x74, 0xf0, 0x10, 0x73, 0x8e, 0x1c, 0x6c, 0x4a, 0xd0, 0xa3, 0x43, 0x0e, 0xff, 0x0b, - 0x16, 0x78, 0x87, 0x0b, 0xec, 0x59, 0xc8, 0xf6, 0x08, 0xb5, 0x90, 0x6d, 0xfb, 0x98, 0x73, 0x7d, - 0xa6, 0xa0, 0x95, 0x32, 0x26, 0x0c, 0xe7, 0x36, 0xe4, 0xd4, 0x46, 0x38, 0x03, 0x9f, 0x82, 0xcc, - 0x40, 0xe5, 0xf9, 0xc2, 0x74, 0x29, 0x7b, 0xd7, 0x48, 0xcc, 0x93, 0x6d, 0xf7, 0x84, 0x57, 0x97, - 0x65, 0xb2, 0xdd, 0xc0, 0xb8, 0xd4, 0x47, 0xde, 0x66, 0x1e, 0x11, 0xd8, 0x6b, 0x8a, 0x8e, 0x39, - 0xa0, 0x83, 0xcf, 0x00, 0xc0, 0xd4, 0x41, 0x0e, 0xf6, 0x30, 0x15, 0x7a, 0x4a, 0x91, 0xaf, 0x24, - 0x91, 0x3f, 0xba, 0xbf, 0xfe, 0x10, 0x7b, 0x35, 0xec, 0x57, 0xaf, 0x45, 0xd4, 0x0b, 0x03, 0x60, - 0x8c, 0x3b, 0x46, 0x07, 0xbf, 0xd0, 0xc0, 0x65, 0x2e, 0xd0, 0x0b, 0xdc, 0xaf, 0xb2, 0xa5, 0x98, - 0x1d, 0x7d, 0x56, 0x3d, 0xad, 0x7f, 0x27, 0x05, 0xda, 0x93, 0x80, 0x5e, 0x1e, 0x9b, 0x6a, 0x79, - 0x75, 0xb5, 0x1b, 0x18, 0x46, 0x22, 0x53, 0x2c, 0xf2, 0x25, 0x3e, 0x8e, 0x84, 0x5f, 0x69, 0xe0, - 0x4a, 0x1b, 0xb9, 0x1c, 0x8b, 0x31, 0x0d, 0x69, 0xa5, 0xa1, 0x94, 0xa4, 0xe1, 0x89, 0x42, 0x8c, - 0x88, 0xb8, 0xde, 0x0d, 0x8c, 0x42, 0x32, 0x57, 0x4c, 0xc5, 0x42, 0x3b, 0x01, 0x0b, 0xbf, 0xd5, - 0xc0, 0xd2, 0xa0, 0x30, 0x63, 0x52, 0x32, 0x4a, 0xca, 0xed, 0x24, 0x29, 0xdb, 0x7d, 0xd4, 0x88, - 0x9c, 0x52, 0x37, 0x30, 0xae, 0x4f, 0xe6, 0x8c, 0x49, 0xd2, 0xf1, 0x04, 0x0e, 0xb8, 0x0e, 0x40, - 0x8d, 0x51, 0xdb, 0xb2, 0x31, 0x65, 0x9e, 0x0e, 0x64, 0x07, 0x56, 0x2f, 0xbf, 0x0f, 0x8c, 0x7f, - 0x85, 0x6d, 0x3d, 0x98, 0x2b, 0x9a, 0x19, 0x79, 0xb3, 0x25, 0xaf, 0xe1, 0xcf, 0x1a, 0x58, 0x65, - 0x6d, 0xec, 0x73, 0xe2, 0x34, 0x64, 0x38, 0xcf, 0x23, 0x42, 0xe0, 0xf1, 0x87, 0x9c, 0x55, 0x59, - 0xad, 0x27, 0x65, 0xf5, 0x79, 0x0f, 0xbe, 0xd9, 0x43, 0x8f, 0x64, 0xb7, 0xd6, 0x0d, 0x8c, 0x3b, - 0x27, 0x08, 0x12, 0x4b, 0xb3, 0xc0, 0x8e, 0x21, 0x85, 0x3f, 0x6a, 0x20, 0x2f, 0x99, 0x5a, 0x94, - 0x88, 0x8e, 0xd5, 0x64, 0xcc, 0x1d, 0xd3, 0x3c, 0xa7, 0x34, 0x57, 0x92, 0x34, 0x6f, 0xf6, 0x90, - 0xbb, 0x8c, 0xb9, 0x23, 0x72, 0x6f, 0x77, 0x03, 0xa3, 0x74, 0x34, 0x75, 0x4c, 0xe9, 0x72, 0x7d, - 0x32, 0x15, 0xfc, 0x49, 0x03, 0xb2, 0xcb, 0x88, 0x8d, 0x04, 0xf3, 0xad, 0x36, 0x13, 0x84, 0x3a, - 0x63, 0x32, 0x73, 0x4a, 0xe6, 0xda, 0x84, 0xde, 0x0d, 0xb1, 0x4f, 0x14, 0x74, 0x44, 0x68, 0xb9, - 0x1b, 0x18, 0xb7, 0x8e, 0xa3, 0x8f, 0x49, 0x5d, 0x69, 0x1f, 0x45, 0x07, 0x1d, 0xb0, 0x38, 0x54, - 0x75, 0x95, 0x54, 0xb8, 0x4f, 0x70, 0x7d, 0xbe, 0x30, 0x5d, 0xca, 0x54, 0xff, 0xd3, 0x0d, 0x8c, - 0x1b, 0xc3, 0x4f, 0x32, 0x2c, 0x92, 0x17, 0x2e, 0x8b, 0x05, 0x9b, 0xcc, 0x05, 0x4d, 0x00, 0x91, - 0x5f, 0x23, 0x02, 0xfb, 0xb2, 0x64, 0xbd, 0x08, 0x17, 0x54, 0x84, 0x62, 0x37, 0x30, 0xf2, 0xd1, - 0x6c, 0x58, 0xfa, 0x71, 0xea, 0x04, 0x34, 0xfc, 0x5e, 0x03, 0xd7, 0x86, 0x60, 0xa3, 0x55, 0xbe, - 0xa8, 0xaa, 0x7c, 0x27, 0xa9, 0xca, 0x1b, 0x03, 0xba, 0x91, 0x0a, 0xdf, 0xea, 0x06, 0xc6, 0xcd, - 0xa3, 0x68, 0xe3, 0x09, 0xa3, 0x49, 0x34, 0xc5, 0x37, 0x1a, 0xb8, 0x94, 0xb0, 0x15, 0xc2, 0x45, - 0x90, 0x96, 0xae, 0x21, 0xdf, 0x46, 0xe5, 0x79, 0x33, 0xe6, 0xac, 0x47, 0x68, 0x95, 0x51, 0x1b, - 0x96, 0xc0, 0x45, 0xc1, 0x5e, 0x60, 0xca, 0xad, 0xa6, 0x0a, 0x4d, 0xa8, 0x50, 0xa6, 0x36, 0x63, - 0xce, 0x87, 0xe3, 0xbb, 0x32, 0x12, 0xa1, 0x02, 0x7e, 0x06, 0x2e, 0xb6, 0xa8, 0xa4, 0x90, 0x0f, - 0xbf, 0x89, 0x7d, 0xc2, 0x6c, 0x7d, 0x5a, 0x25, 0xbb, 0x58, 0x0e, 0x2d, 0xb8, 0xdc, 0xb3, 0xe0, - 0xf2, 0x56, 0x64, 0xc1, 0xd5, 0xb4, 0xdc, 0xf7, 0xbf, 0xfb, 0xcd, 0xd0, 0xcc, 0x0b, 0x7d, 0xf0, - 0xae, 0xc2, 0xc2, 0x75, 0x70, 0xa5, 0xee, 0x22, 0xe2, 0x59, 0xa8, 0x25, 0x98, 0x8f, 0x45, 0xcb, - 0xa7, 0x96, 0x4b, 0x3c, 0x22, 0x94, 0xab, 0xe5, 0xcc, 0x05, 0x35, 0xbb, 0xd1, 0x9f, 0xdc, 0x91, - 0x73, 0xc5, 0x1f, 0x52, 0x60, 0x21, 0x69, 0xa7, 0x85, 0x2b, 0x00, 0xc8, 0x1c, 0x55, 0x06, 0x3c, - 0xca, 0x32, 0xe3, 0x11, 0xaa, 0xc4, 0x2b, 0xeb, 0xf6, 0xd0, 0xa1, 0xd5, 0xef, 0xcc, 0xd0, 0xba, - 0x73, 0x66, 0xce, 0x43, 0x87, 0xfd, 0xee, 0xe7, 0xf0, 0x1e, 0x98, 0xc3, 0x4d, 0x56, 0x6f, 0x58, - 0x2e, 0xa6, 0x8e, 0x68, 0x9c, 0x26, 0xc1, 0xac, 0x02, 0xee, 0x28, 0x1c, 0xac, 0xf6, 0x78, 0x7c, - 0x7c, 0x80, 0x7c, 0x5b, 0xa5, 0x24, 0x79, 0xc2, 0x93, 0x50, 0x59, 0x9e, 0x84, 0x62, 0x7b, 0x04, - 0xa1, 0xd1, 0x41, 0x23, 0xe4, 0x30, 0x15, 0x06, 0xea, 0x60, 0x96, 0xd7, 0x91, 0x4b, 0xa8, 0xa3, - 0x9f, 0x57, 0x5a, 0x7b, 0xb7, 0xf0, 0x31, 0x98, 0xdf, 0xc7, 0x58, 0x3e, 0x84, 0x3a, 0xa6, 0x02, - 0x39, 0x58, 0x4f, 0xa9, 0x6d, 0xb8, 0x2c, 0x49, 0x7e, 0x0d, 0x8c, 0x9b, 0x0e, 0x11, 0x8d, 0x56, - 0xad, 0x5c, 0x67, 0x5e, 0x25, 0x3a, 0x7b, 0x85, 0xff, 0xee, 0x70, 0xfb, 0x45, 0x45, 0x74, 0x9a, - 0x98, 0x97, 0xb7, 0x70, 0xdd, 0xcc, 0xed, 0x63, 0xbc, 0xdb, 0x27, 0x81, 0x1e, 0x58, 0x1e, 0xd9, - 0x8e, 0x42, 0xf5, 0x96, 0xca, 0x55, 0xf9, 0xef, 0xe9, 0x63, 0xe8, 0x43, 0xfb, 0x56, 0x98, 0x9a, - 0x29, 0xf9, 0xe0, 0x3e, 0xb8, 0x1a, 0xb3, 0xa2, 0xa1, 0x50, 0xe9, 0x33, 0x85, 0xba, 0x3c, 0xa0, - 0x8b, 0xc7, 0xb1, 0x95, 0x9b, 0x47, 0x9b, 0xd7, 0x50, 0x98, 0xcc, 0x99, 0xc2, 0x2c, 0xf4, 0xd9, - 0xe2, 0x51, 0x0c, 0x90, 0x95, 0x8d, 0x6c, 0xb5, 0xe8, 0x73, 0x44, 0x5c, 0xe5, 0x8b, 0x69, 0x13, - 0xc8, 0xa1, 0xc7, 0x6a, 0x04, 0x62, 0x70, 0xd5, 0x66, 0xad, 0x9a, 0x8b, 0x2d, 0x4e, 0x1c, 0x6a, - 0x71, 0x17, 0xf1, 0x46, 0xa4, 0x23, 0x7b, 0x36, 0x1d, 0x21, 0xdd, 0x1e, 0x71, 0xe8, 0x9e, 0x24, - 0x53, 0x3a, 0x8a, 0xcf, 0x80, 0x3e, 0xc9, 0xfe, 0xe1, 0x27, 0x20, 0xdd, 0x40, 0xee, 0xbe, 0x4b, - 0xf6, 0x71, 0x74, 0xf6, 0x3d, 0x51, 0x67, 0xf7, 0x41, 0xc5, 0x2f, 0xcf, 0x81, 0xc2, 0x71, 0x36, - 0x0c, 0x21, 0x98, 0xa1, 0xc8, 0x0b, 0x23, 0x64, 0x4c, 0x75, 0x0d, 0xb7, 0x40, 0x0e, 0xf3, 0xba, - 0xcf, 0x0e, 0x2c, 0xe4, 0xb1, 0x56, 0xb4, 0xc7, 0x9c, 0xe0, 0x85, 0x98, 0x0b, 0x51, 0x1b, 0x0a, - 0x04, 0x1f, 0x80, 0xb9, 0xc8, 0x7c, 0xfc, 0x96, 0x8b, 0x79, 0xf4, 0x76, 0x26, 0x9e, 0x6b, 0x43, - 0xe7, 0x31, 0xe5, 0xb2, 0xde, 0xbb, 0xd5, 0x1e, 0x0c, 0xc1, 0x8f, 0xc0, 0x92, 0x8d, 0x69, 0xc7, - 0x72, 0x09, 0x8f, 0x9d, 0x82, 0x86, 0x8f, 0xd5, 0x57, 0xe5, 0x8a, 0x1d, 0xc2, 0xfb, 0x55, 0x8c, - 0xce, 0xd6, 0x45, 0x07, 0x2c, 0x1f, 0xe1, 0xeb, 0x63, 0x2a, 0xb5, 0xb3, 0xaa, 0x2c, 0x12, 0xb0, - 0x72, 0xa4, 0x33, 0xff, 0x8d, 0xa1, 0x5e, 0x82, 0x6c, 0xec, 0x53, 0x00, 0x3e, 0x00, 0xb9, 0x7e, - 0x55, 0x64, 0xc7, 0x29, 0xe6, 0xf9, 0xbb, 0xab, 0xc7, 0x7c, 0x42, 0x3c, 0xea, 0x34, 0xb1, 0x39, - 0x57, 0x8f, 0xdd, 0xc9, 0x5d, 0xac, 0x57, 0xd6, 0x73, 0xaa, 0xac, 0xbd, 0xdb, 0xe2, 0x13, 0x90, - 0xe9, 0x7f, 0x20, 0xc0, 0x1b, 0x83, 0x65, 0xaa, 0x6f, 0xaa, 0xd9, 0x6e, 0x60, 0xf4, 0x86, 0xfa, - 0x18, 0x58, 0x04, 0xa9, 0x68, 0x87, 0x57, 0x26, 0x55, 0x05, 0xf2, 0xcb, 0x2a, 0x1c, 0x31, 0xa3, - 0xff, 0xc5, 0x3f, 0x34, 0x90, 0x8d, 0x65, 0x0b, 0x57, 0x41, 0x2e, 0x2a, 0x52, 0xe4, 0x5a, 0x9a, - 0xda, 0x4d, 0xa3, 0xca, 0x45, 0x6e, 0x74, 0x0f, 0xa4, 0x5e, 0xb6, 0x98, 0xdf, 0xf2, 0x42, 0x95, - 0xa7, 0x7e, 0x19, 0x23, 0x34, 0xdc, 0x01, 0x19, 0xd1, 0xf0, 0x31, 0x6f, 0x30, 0x37, 0xb4, 0xc7, - 0xd3, 0x53, 0x0d, 0x08, 0xe0, 0x4d, 0x70, 0x01, 0xb9, 0x2e, 0x3b, 0xb0, 0x30, 0xb5, 0x2d, 0x8c, - 0x7c, 0xb7, 0xa3, 0x7a, 0x33, 0x6d, 0xe6, 0xd4, 0xf0, 0x36, 0xb5, 0xb7, 0xe5, 0x60, 0xf1, 0xeb, - 0x69, 0xb0, 0x38, 0xf1, 0x74, 0xf1, 0x8f, 0x7f, 0x21, 0xa5, 0xdb, 0xda, 0x84, 0x37, 0x5b, 0x42, - 0x1e, 0xf5, 0xb9, 0x50, 0x76, 0x79, 0x12, 0xb7, 0x8d, 0x40, 0x9b, 0x8c, 0x0b, 0xf8, 0x29, 0x98, - 0x3f, 0x40, 0x24, 0xde, 0x26, 0xa9, 0x93, 0xef, 0x90, 0xb9, 0x08, 0x1a, 0x36, 0x53, 0xf5, 0xe3, - 0x57, 0x6f, 0xf3, 0xda, 0xeb, 0xb7, 0x79, 0xed, 0xcd, 0xdb, 0xbc, 0xf6, 0xcd, 0xbb, 0xfc, 0xd4, - 0xeb, 0x77, 0xf9, 0xa9, 0x5f, 0xde, 0xe5, 0xa7, 0x9e, 0x5e, 0x1f, 0xea, 0x01, 0xf5, 0xab, 0x86, - 0x70, 0x7c, 0x64, 0xe3, 0xca, 0xa1, 0xfa, 0x79, 0x43, 0x75, 0x41, 0x2d, 0xa5, 0x62, 0xfd, 0xef, - 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4f, 0x97, 0xf4, 0x79, 0x85, 0x11, 0x00, 0x00, + // 1642 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0xcf, 0x6f, 0xdb, 0xc8, + 0x15, 0x36, 0xd7, 0xae, 0x63, 0x3d, 0x49, 0xde, 0xec, 0xc4, 0xd9, 0xc8, 0x4e, 0x22, 0xba, 0xcc, + 0x8f, 0xba, 0xdb, 0x44, 0x6a, 0xd2, 0x00, 0x2d, 0x5a, 0xa0, 0x85, 0x65, 0x67, 0x37, 0x5d, 0x64, + 0x5b, 0x83, 0xc9, 0xe6, 0xb0, 0x7b, 0x20, 0x46, 0xe2, 0x98, 0x9a, 0x0d, 0x39, 0xc3, 0xe5, 0x0c, + 0x65, 0xeb, 0x56, 0xa0, 0x3d, 0xf6, 0xd0, 0x43, 0x0f, 0x45, 0x8f, 0x3d, 0x16, 0x3d, 0xf7, 0x6f, + 0x58, 0xa0, 0x97, 0x3d, 0x16, 0x3d, 0xb0, 0x8b, 0x04, 0xbd, 0xe8, 0x54, 0xe4, 0xd8, 0x53, 0x31, + 0x33, 0x94, 0x44, 0x49, 0x94, 0x9d, 0x04, 0x3d, 0xf5, 0x62, 0x93, 0x33, 0xf3, 0x7d, 0xef, 0x7b, + 0x8f, 0x8f, 0xef, 0x3d, 0x0a, 0x76, 0x7b, 0x9c, 0x1d, 0x53, 0xde, 0x8e, 0x39, 0x69, 0x0f, 0xee, + 0x75, 0x89, 0xc4, 0xf7, 0xda, 0x01, 0x61, 0x44, 0x50, 0xd1, 0x8a, 0x13, 0x2e, 0x39, 0x42, 0xe6, + 0x44, 0x2b, 0xe6, 0xa4, 0x95, 0x9f, 0xd8, 0xd9, 0x0a, 0x78, 0xc0, 0xf5, 0x76, 0x5b, 0x5d, 0x99, + 0x93, 0x3b, 0xcd, 0x1e, 0x17, 0x11, 0x17, 0xed, 0x2e, 0x16, 0x53, 0xb2, 0x1e, 0xa7, 0xac, 0xb8, + 0x7f, 0x82, 0x45, 0xd4, 0xd6, 0x7f, 0x06, 0x73, 0x96, 0x76, 0xae, 0x95, 0x68, 0x51, 0x56, 0x73, + 0x74, 0xc0, 0x79, 0x10, 0x92, 0xb6, 0xbe, 0xeb, 0xa6, 0xc7, 0x6d, 0x3f, 0x4d, 0xb0, 0xa4, 0x3c, + 0x67, 0x77, 0xfe, 0x65, 0x41, 0xed, 0x23, 0xc3, 0xf7, 0x44, 0x62, 0x49, 0xd0, 0x8f, 0x60, 0x3d, + 0xc6, 0x09, 0x8e, 0x44, 0xc3, 0xda, 0xb5, 0xf6, 0xaa, 0xf7, 0x77, 0x5a, 0x8b, 0x9e, 0xb4, 0x8e, + 0xf4, 0x89, 0xce, 0xda, 0x57, 0x99, 0xbd, 0xe2, 0xe6, 0xe7, 0xd1, 0xc7, 0xb0, 0x29, 0x08, 0xf1, + 0xbd, 0x1e, 0x67, 0x32, 0xc1, 0x3d, 0x29, 0x1a, 0xef, 0x68, 0x86, 0x6f, 0x97, 0x31, 0x3c, 0x21, + 0xc4, 0x3f, 0x18, 0x1f, 0x7c, 0xb4, 0xe2, 0xd6, 0x45, 0x71, 0x01, 0xed, 0x43, 0x95, 0x46, 0x31, + 0x4f, 0xa4, 0xe7, 0xa7, 0x51, 0xdc, 0x58, 0xd5, 0x44, 0xcd, 0x32, 0xa2, 0x9f, 0xeb, 0x63, 0x87, + 0x69, 0x14, 0x3f, 0x5a, 0x71, 0x81, 0x4e, 0xee, 0x3a, 0x35, 0x00, 0x41, 0x64, 0x1a, 0x7b, 0x11, + 0xf7, 0x89, 0xd3, 0x07, 0x98, 0x9e, 0x44, 0x9f, 0x41, 0x65, 0xaa, 0xd2, 0xda, 0x5d, 0xdd, 0xab, + 0xde, 0xb7, 0x4b, 0xfd, 0xe4, 0x0f, 0xc7, 0x9a, 0x3a, 0x57, 0x95, 0xb3, 0xa3, 0xcc, 0xbe, 0x34, + 0x41, 0xde, 0xe1, 0x11, 0x95, 0x24, 0x8a, 0xe5, 0xd0, 0x9d, 0xd2, 0x39, 0x7f, 0xa9, 0x41, 0x7d, + 0xc6, 0x3b, 0x74, 0x04, 0x17, 0x02, 0xc2, 0x3c, 0x79, 0x6a, 0x6c, 0xd5, 0x3a, 0x3f, 0x1c, 0x65, + 0xf6, 0x7a, 0x40, 0x98, 0x3c, 0x15, 0xaf, 0x32, 0xbb, 0x3e, 0xc4, 0x51, 0xf8, 0x63, 0xc7, 0xdc, + 0x3b, 0xff, 0xc9, 0xec, 0x06, 0x61, 0x3d, 0xee, 0x53, 0x16, 0xb4, 0xbf, 0x10, 0x9c, 0xb5, 0x5c, + 0x7c, 0xf2, 0x09, 0x11, 0x02, 0x07, 0xc4, 0x55, 0xa0, 0xa7, 0xa7, 0x02, 0x7d, 0x1f, 0xb6, 0xc4, + 0x50, 0x48, 0x12, 0x79, 0xd8, 0x8f, 0x28, 0xf3, 0xb0, 0xef, 0x27, 0x44, 0x98, 0x80, 0x57, 0x5c, + 0x64, 0xf6, 0xf6, 0xd5, 0xd6, 0xbe, 0xd9, 0x41, 0x9f, 0x03, 0x10, 0x16, 0xe0, 0x80, 0x44, 0x84, + 0xc9, 0xc6, 0xaa, 0x76, 0xf9, 0x7a, 0x99, 0xcb, 0x4f, 0x3f, 0x7a, 0xf0, 0x09, 0x89, 0xba, 0x24, + 0xe9, 0x5c, 0xcb, 0x1d, 0xde, 0x9a, 0x02, 0x0b, 0x1e, 0x17, 0xe8, 0xd0, 0xaf, 0x2c, 0xb8, 0x2c, + 0x24, 0x7e, 0x4e, 0x26, 0xcf, 0xde, 0xd3, 0xcc, 0x41, 0x63, 0x4d, 0x3f, 0xb8, 0xef, 0x94, 0x66, + 0x80, 0x02, 0x8c, 0x83, 0x74, 0xa0, 0x8f, 0x77, 0x6e, 0x8c, 0x32, 0xdb, 0x2e, 0x65, 0x2a, 0x58, + 0xbe, 0x24, 0x16, 0x91, 0xe8, 0x37, 0x16, 0xbc, 0x3f, 0xc0, 0xa1, 0x20, 0x72, 0x41, 0xc3, 0xb7, + 0xb4, 0x86, 0xbd, 0x32, 0x0d, 0xcf, 0x34, 0x62, 0x4e, 0xc4, 0xcd, 0x51, 0x66, 0xef, 0x96, 0x73, + 0x15, 0x54, 0x6c, 0x0d, 0x4a, 0xb0, 0xe8, 0xf7, 0x16, 0xec, 0x4c, 0x03, 0xb3, 0x20, 0x65, 0x5d, + 0x4b, 0xb9, 0x53, 0x26, 0xe5, 0xe1, 0x04, 0x35, 0x27, 0x67, 0x6f, 0x94, 0xd9, 0x37, 0x97, 0x73, + 0x16, 0x24, 0x35, 0xc8, 0x12, 0x0e, 0xf4, 0x00, 0xa0, 0xcb, 0x99, 0xef, 0xf9, 0x84, 0xf1, 0xa8, + 0x71, 0x41, 0x65, 0x49, 0xe7, 0xf2, 0xab, 0xcc, 0x7e, 0xcf, 0xa4, 0xde, 0x74, 0xcf, 0x71, 0x2b, + 0xea, 0xe6, 0x50, 0x5d, 0xa3, 0xbf, 0x5a, 0x70, 0x83, 0x0f, 0x48, 0x22, 0x68, 0xd0, 0x57, 0xe6, + 0xa2, 0x88, 0x4a, 0x49, 0x16, 0x1f, 0xf2, 0x86, 0xf6, 0xea, 0x41, 0x99, 0x57, 0xbf, 0x1c, 0xc3, + 0x0f, 0xc6, 0xe8, 0x39, 0xef, 0xee, 0x8d, 0x32, 0xfb, 0xee, 0x6b, 0x18, 0x29, 0xb8, 0xb9, 0xcb, + 0xcf, 0x21, 0x45, 0x7f, 0xb2, 0xa0, 0xa9, 0x98, 0x52, 0x46, 0xe5, 0xd0, 0x8b, 0x39, 0x0f, 0x17, + 0x34, 0x57, 0xb4, 0xe6, 0x76, 0x99, 0xe6, 0x83, 0x31, 0xf2, 0x88, 0xf3, 0x70, 0x4e, 0xee, 0x9d, + 0x51, 0x66, 0xef, 0x9d, 0x4d, 0x5d, 0x50, 0x7a, 0xb5, 0xb7, 0x9c, 0x0a, 0xfd, 0xd9, 0x02, 0x95, + 0x65, 0xd4, 0xc7, 0x92, 0x27, 0xde, 0x80, 0x4b, 0xca, 0x82, 0x05, 0x99, 0xa0, 0x65, 0xde, 0x5b, + 0x92, 0xbb, 0x06, 0xfb, 0x4c, 0x43, 0xe7, 0x84, 0xb6, 0x46, 0x99, 0xfd, 0xc1, 0x79, 0xf4, 0x05, + 0xa9, 0xd7, 0x07, 0x67, 0xd1, 0xa1, 0x00, 0xb6, 0x67, 0xa2, 0xae, 0x9d, 0x32, 0x75, 0x42, 0x34, + 0xaa, 0xbb, 0xab, 0x7b, 0x95, 0xce, 0x77, 0x47, 0x99, 0x7d, 0x6b, 0xf6, 0x49, 0x9a, 0x20, 0x45, + 0xe6, 0x58, 0xc1, 0xd8, 0x72, 0x2e, 0xe4, 0x02, 0xc2, 0x49, 0x97, 0x4a, 0x92, 0xa8, 0x90, 0x8d, + 0x2d, 0xd4, 0xb4, 0x05, 0x67, 0x94, 0xd9, 0xcd, 0x7c, 0xd7, 0x84, 0x7e, 0x91, 0xba, 0x04, 0x8d, + 0xfe, 0x68, 0xc1, 0xb5, 0x19, 0xd8, 0x7c, 0x94, 0xeb, 0x3a, 0xca, 0x77, 0xcb, 0xa2, 0xbc, 0x3f, + 0xa5, 0x9b, 0x8b, 0xf0, 0x07, 0xa3, 0xcc, 0xbe, 0x7d, 0x16, 0x6d, 0xd1, 0x61, 0xbc, 0x8c, 0xc6, + 0xf9, 0xc6, 0x82, 0x4b, 0x25, 0xa5, 0x10, 0x6d, 0xc3, 0x86, 0xaa, 0xec, 0xea, 0x6d, 0xd4, 0x9d, + 0x78, 0xcd, 0xbd, 0x10, 0x51, 0xd6, 0xe1, 0xcc, 0x47, 0x7b, 0x70, 0x51, 0xf2, 0xe7, 0x84, 0x09, + 0x2f, 0xd6, 0xa6, 0x29, 0x93, 0xba, 0xf2, 0xaf, 0xb9, 0x9b, 0x66, 0xfd, 0x48, 0x59, 0xa2, 0x4c, + 0xa2, 0x5f, 0xc0, 0xc5, 0x94, 0x29, 0x0a, 0xf5, 0xf0, 0x63, 0x92, 0x50, 0xee, 0xe7, 0xbd, 0x74, + 0xbb, 0x65, 0x06, 0x83, 0xd6, 0x78, 0x30, 0x68, 0x1d, 0xe6, 0x83, 0x41, 0x67, 0x43, 0xd5, 0xfd, + 0x3f, 0xfc, 0xd3, 0xb6, 0xdc, 0x77, 0x27, 0xe0, 0x23, 0x8d, 0x45, 0x0f, 0xe0, 0xfd, 0x5e, 0x88, + 0x69, 0xe4, 0xe1, 0x54, 0xf2, 0x84, 0xc8, 0x34, 0x61, 0x5e, 0x48, 0x23, 0x2a, 0x75, 0xa1, 0xaf, + 0xbb, 0x5b, 0x7a, 0x77, 0x7f, 0xb2, 0xf9, 0x58, 0xed, 0x39, 0x7f, 0x5b, 0x87, 0xad, 0xb2, 0x4a, + 0x8b, 0xae, 0x03, 0x28, 0x1f, 0xb5, 0x07, 0x22, 0xf7, 0xb2, 0x12, 0x51, 0xa6, 0xc5, 0x0b, 0x74, + 0x0b, 0x36, 0x23, 0x7c, 0xea, 0x4d, 0x32, 0xd3, 0xf4, 0xb7, 0xba, 0x5b, 0x8f, 0xf0, 0xe9, 0x24, + 0xfb, 0x05, 0xfa, 0x10, 0x6a, 0x24, 0xe6, 0xbd, 0xbe, 0x17, 0x12, 0x16, 0xc8, 0xfe, 0x9b, 0x38, + 0x58, 0xd5, 0xc0, 0xc7, 0x1a, 0x87, 0x3a, 0x63, 0x9e, 0x84, 0x9c, 0xe0, 0xc4, 0xcf, 0x7b, 0xd7, + 0x76, 0xcb, 0xcc, 0x67, 0x2d, 0x35, 0x9f, 0x15, 0x6a, 0x04, 0x65, 0xf9, 0xf8, 0x63, 0x38, 0x5c, + 0x8d, 0x41, 0x0d, 0xb8, 0x20, 0x7a, 0x38, 0xa4, 0xcc, 0xb4, 0x9d, 0xba, 0x3b, 0xbe, 0x45, 0x9f, + 0xc2, 0xe6, 0x31, 0x21, 0xea, 0x21, 0xf4, 0x08, 0x93, 0x38, 0x20, 0xba, 0x19, 0x54, 0x3a, 0x2d, + 0x45, 0xf2, 0x8f, 0xcc, 0xbe, 0x1d, 0x50, 0xd9, 0x4f, 0xbb, 0xad, 0x1e, 0x8f, 0xda, 0xf9, 0x44, + 0x68, 0xfe, 0xdd, 0x15, 0xfe, 0xf3, 0xb6, 0x1c, 0xc6, 0x44, 0xb4, 0x0e, 0x49, 0xcf, 0xad, 0x1f, + 0x13, 0x72, 0x34, 0x21, 0x41, 0x11, 0x5c, 0x9d, 0x2b, 0x47, 0x46, 0xbd, 0xa7, 0x7d, 0xcd, 0x4b, + 0xfd, 0x9b, 0xda, 0x68, 0xcc, 0xd4, 0x2d, 0xe3, 0x9a, 0xab, 0xf8, 0xd0, 0x31, 0x5c, 0x29, 0xb4, + 0xa2, 0x19, 0x53, 0x1b, 0x6f, 0x65, 0xea, 0xf2, 0x94, 0xae, 0x68, 0xc7, 0xd7, 0xdd, 0x3c, 0x2f, + 0x5e, 0x33, 0x66, 0x2a, 0x6f, 0x65, 0x66, 0x6b, 0xc2, 0x56, 0xb4, 0x62, 0x43, 0x55, 0x25, 0xb2, + 0x97, 0xb2, 0x2f, 0x30, 0x0d, 0x75, 0xb1, 0xdd, 0x70, 0x41, 0x2d, 0x7d, 0xaa, 0x57, 0x10, 0x81, + 0x2b, 0x3e, 0x4f, 0xbb, 0x21, 0xf1, 0x04, 0x0d, 0x98, 0x27, 0x42, 0x2c, 0xfa, 0xb9, 0x8e, 0xea, + 0xdb, 0xe9, 0x30, 0x74, 0x4f, 0x68, 0xc0, 0x9e, 0x28, 0x32, 0xa3, 0xe3, 0x7b, 0xf0, 0xde, 0x80, + 0x24, 0xf4, 0x78, 0x58, 0xcc, 0xf5, 0x9a, 0x56, 0x73, 0xd1, 0x6c, 0x4c, 0xd3, 0xdd, 0xf9, 0x1c, + 0x1a, 0xcb, 0x66, 0x05, 0xf4, 0x33, 0xd8, 0xe8, 0xe3, 0xf0, 0x38, 0xa4, 0xc7, 0x24, 0x1f, 0xdf, + 0x5f, 0xeb, 0x35, 0x98, 0x80, 0x9c, 0x5f, 0xbf, 0x03, 0xbb, 0xe7, 0xf5, 0x6c, 0x84, 0x60, 0x8d, + 0xe1, 0xc8, 0x58, 0xa8, 0xb8, 0xfa, 0x1a, 0x1d, 0x42, 0x9d, 0x88, 0x5e, 0xc2, 0x4f, 0x3c, 0x1c, + 0xf1, 0x34, 0x2f, 0x48, 0xaf, 0xf1, 0xf6, 0xd4, 0x0c, 0x6a, 0x5f, 0x83, 0xd0, 0x23, 0xa8, 0xe5, + 0x9d, 0x2a, 0x49, 0x43, 0x22, 0xf2, 0x57, 0xb9, 0x74, 0x34, 0x37, 0x6d, 0xca, 0x55, 0xc7, 0xc6, + 0x2f, 0xe2, 0x60, 0xba, 0x84, 0x7e, 0x02, 0x3b, 0x3e, 0x61, 0x43, 0x2f, 0xa4, 0xa2, 0x30, 0x32, + 0x8d, 0xe7, 0xe4, 0x35, 0xad, 0xfc, 0x8a, 0x3a, 0xf1, 0x98, 0x8a, 0x49, 0x14, 0xf3, 0x61, 0xd9, + 0x09, 0xe0, 0xea, 0x19, 0x43, 0xc0, 0x82, 0x4a, 0xeb, 0x6d, 0x55, 0x3a, 0x14, 0xae, 0x9f, 0xd9, + 0xc6, 0xff, 0x87, 0xa6, 0xbe, 0x84, 0x6a, 0xe1, 0x6b, 0x06, 0x3d, 0x82, 0xfa, 0x24, 0x2a, 0x2a, + 0x3d, 0x35, 0xf3, 0xe6, 0xfd, 0x1b, 0xe7, 0x7c, 0x05, 0x3d, 0x1d, 0xc6, 0xc4, 0xad, 0xf5, 0x0a, + 0x77, 0xaa, 0xe4, 0xcd, 0x7e, 0x7e, 0x8c, 0x6f, 0x9d, 0x67, 0x50, 0x99, 0x7c, 0x4d, 0xa0, 0x5b, + 0xd3, 0x63, 0x3a, 0x6f, 0x3a, 0xd5, 0x51, 0x66, 0x8f, 0x97, 0x26, 0x18, 0xe4, 0xc0, 0x7a, 0xde, + 0x0e, 0x74, 0x47, 0xeb, 0x80, 0xfa, 0x54, 0x32, 0x2b, 0x6e, 0xfe, 0xdf, 0xf9, 0xb7, 0x05, 0xd5, + 0x82, 0xb7, 0xe8, 0x06, 0xd4, 0xf3, 0x20, 0xe5, 0x2d, 0xce, 0xd2, 0xa5, 0x37, 0x8f, 0x5c, 0xde, + 0xba, 0x3e, 0x84, 0xf5, 0x2f, 0x53, 0x9e, 0xa4, 0x91, 0x51, 0xf9, 0xc6, 0x6f, 0x6e, 0x8e, 0x46, + 0x8f, 0xa1, 0x22, 0xfb, 0x09, 0x11, 0x7d, 0x1e, 0x9a, 0x5e, 0xfa, 0xe6, 0x54, 0x53, 0x02, 0x74, + 0x1b, 0xde, 0xc5, 0x61, 0xc8, 0x4f, 0x3c, 0xc2, 0x7c, 0x8f, 0xe0, 0x24, 0x1c, 0xea, 0xdc, 0xdc, + 0x70, 0xeb, 0x7a, 0xf9, 0x21, 0xf3, 0x1f, 0xaa, 0x45, 0xe7, 0xb7, 0xab, 0xb0, 0xbd, 0x74, 0x14, + 0xf9, 0xbf, 0x7f, 0x21, 0x55, 0x6b, 0xf6, 0xa9, 0x88, 0x53, 0xa9, 0xbe, 0x0b, 0x84, 0xcc, 0x3f, + 0xe9, 0xce, 0x6f, 0xcd, 0x39, 0xe8, 0x80, 0x0b, 0x89, 0x3e, 0x86, 0xcd, 0x13, 0x4c, 0x8b, 0x69, + 0xb2, 0xfe, 0xfa, 0x15, 0xb2, 0x9e, 0x43, 0x4d, 0x32, 0x75, 0x7e, 0xfa, 0xd5, 0x8b, 0xa6, 0xf5, + 0xf5, 0x8b, 0xa6, 0xf5, 0xcd, 0x8b, 0xa6, 0xf5, 0xbb, 0x97, 0xcd, 0x95, 0xaf, 0x5f, 0x36, 0x57, + 0xfe, 0xfe, 0xb2, 0xb9, 0xf2, 0xd9, 0xcd, 0x99, 0x1c, 0xd0, 0x3f, 0xcc, 0xc8, 0x20, 0xc1, 0x3e, + 0x69, 0x9f, 0xea, 0x5f, 0x68, 0x74, 0x16, 0x74, 0xd7, 0xb5, 0xad, 0x1f, 0xfc, 0x37, 0x00, 0x00, + 0xff, 0xff, 0x4d, 0x5c, 0x87, 0x35, 0x48, 0x12, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -986,6 +1124,127 @@ func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { } func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SetupMode != nil { + { + size := m.SetupMode.Size() + i -= size + if _, err := m.SetupMode.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *GenesisState_SeedContracts) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState_SeedContracts) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.SeedContracts != nil { + { + size, err := m.SeedContracts.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *GenesisState_ImportDump) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState_ImportDump) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ImportDump != nil { + { + size, err := m.ImportDump.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} +func (m *ImportDump) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ImportDump) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ImportDump) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Contracts) > 0 { + for iNdEx := len(m.Contracts) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Contracts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *SeedContracts) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SeedContracts) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SeedContracts) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1000,9 +1259,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x82 + dAtA[i] = 0x6a } if len(m.ArbiterPoolMembers) > 0 { for iNdEx := len(m.ArbiterPoolMembers) - 1; iNdEx >= 0; iNdEx-- { @@ -1010,7 +1267,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.ArbiterPoolMembers[iNdEx]) i = encodeVarintGenesis(dAtA, i, uint64(len(m.ArbiterPoolMembers[iNdEx]))) i-- - dAtA[i] = 0x7a + dAtA[i] = 0x62 } } if len(m.OversightCommunityMembers) > 0 { @@ -1019,7 +1276,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.OversightCommunityMembers[iNdEx]) i = encodeVarintGenesis(dAtA, i, uint64(len(m.OversightCommunityMembers[iNdEx]))) i-- - dAtA[i] = 0x72 + dAtA[i] = 0x5a } } if m.ValidatorVotingContractConfig != nil { @@ -1032,7 +1289,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x6a + dAtA[i] = 0x52 } if m.CommunityPoolContractConfig != nil { { @@ -1044,7 +1301,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x62 + dAtA[i] = 0x4a } if m.OversightCommitteeContractConfig != nil { { @@ -1056,14 +1313,14 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x5a + dAtA[i] = 0x42 } if len(m.BondDenom) > 0 { i -= len(m.BondDenom) copy(dAtA[i:], m.BondDenom) i = encodeVarintGenesis(dAtA, i, uint64(len(m.BondDenom))) i-- - dAtA[i] = 0x52 + dAtA[i] = 0x3a } if m.EngagementContractConfig != nil { { @@ -1075,7 +1332,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x4a + dAtA[i] = 0x32 } if m.ValsetContractConfig != nil { { @@ -1087,7 +1344,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x42 + dAtA[i] = 0x2a } if m.StakeContractConfig != nil { { @@ -1099,7 +1356,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x3a + dAtA[i] = 0x22 } if len(m.Engagement) > 0 { for iNdEx := len(m.Engagement) - 1; iNdEx >= 0; iNdEx-- { @@ -1112,21 +1369,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x32 - } - } - if len(m.Contracts) > 0 { - for iNdEx := len(m.Contracts) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Contracts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a + dAtA[i] = 0x1a } } if len(m.SystemAdminAddress) > 0 { @@ -1134,7 +1377,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.SystemAdminAddress) i = encodeVarintGenesis(dAtA, i, uint64(len(m.SystemAdminAddress))) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x12 } if len(m.GenTxs) > 0 { for iNdEx := len(m.GenTxs) - 1; iNdEx >= 0; iNdEx-- { @@ -1142,29 +1385,9 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.GenTxs[iNdEx]) i = encodeVarintGenesis(dAtA, i, uint64(len(m.GenTxs[iNdEx]))) i-- - dAtA[i] = 0x1a + dAtA[i] = 0xa } } - if m.SeedContracts { - i-- - if m.SeedContracts { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x10 - } - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -1193,12 +1416,12 @@ func (m *StakeContractConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x20 } - n9, err9 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.UnbondingPeriod):]) - if err9 != nil { - return 0, err9 + n11, err11 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.UnbondingPeriod):]) + if err11 != nil { + return 0, err11 } - i -= n9 - i = encodeVarintGenesis(dAtA, i, uint64(n9)) + i -= n11 + i = encodeVarintGenesis(dAtA, i, uint64(n11)) i-- dAtA[i] = 0x1a if m.TokensPerPoint != 0 { @@ -1234,6 +1457,16 @@ func (m *ValsetContractConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.VerifyValidators { + i-- + if m.VerifyValidators { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x60 + } { size := m.DoubleSignSlashRatio.Size() i -= size @@ -1309,12 +1542,12 @@ func (m *ValsetContractConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x22 - n11, err11 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.EpochLength, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.EpochLength):]) - if err11 != nil { - return 0, err11 + n13, err13 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.EpochLength, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.EpochLength):]) + if err13 != nil { + return 0, err13 } - i -= n11 - i = encodeVarintGenesis(dAtA, i, uint64(n11)) + i -= n13 + i = encodeVarintGenesis(dAtA, i, uint64(n13)) i-- dAtA[i] = 0x1a if m.MaxValidators != 0 { @@ -1350,12 +1583,12 @@ func (m *EngagementContractConfig) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l - n12, err12 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Halflife, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.Halflife):]) - if err12 != nil { - return 0, err12 + n14, err14 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Halflife, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.Halflife):]) + if err14 != nil { + return 0, err14 } - i -= n12 - i = encodeVarintGenesis(dAtA, i, uint64(n12)) + i -= n14 + i = encodeVarintGenesis(dAtA, i, uint64(n14)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -1632,12 +1865,12 @@ func (m *ArbiterPoolContractConfig) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l - n17, err17 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.WaitingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.WaitingPeriod):]) - if err17 != nil { - return 0, err17 + n19, err19 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.WaitingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.WaitingPeriod):]) + if err19 != nil { + return 0, err19 } - i -= n17 - i = encodeVarintGenesis(dAtA, i, uint64(n17)) + i -= n19 + i = encodeVarintGenesis(dAtA, i, uint64(n19)) i-- dAtA[i] = 0x32 { @@ -1684,31 +1917,79 @@ func (m *ArbiterPoolContractConfig) MarshalToSizedBuffer(dAtA []byte) (int, erro i-- dAtA[i] = 0xa } - return len(dAtA) - i, nil + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + if m.SetupMode != nil { + n += m.SetupMode.Size() + } + return n +} + +func (m *GenesisState_SeedContracts) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SeedContracts != nil { + l = m.SeedContracts.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} +func (m *GenesisState_ImportDump) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ImportDump != nil { + l = m.ImportDump.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} +func (m *ImportDump) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Contracts) > 0 { + for _, e := range m.Contracts { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n } -func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { - offset -= sovGenesis(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *GenesisState) Size() (n int) { +func (m *SeedContracts) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = m.Params.Size() - n += 1 + l + sovGenesis(uint64(l)) - if m.SeedContracts { - n += 2 - } if len(m.GenTxs) > 0 { for _, b := range m.GenTxs { l = len(b) @@ -1719,12 +2000,6 @@ func (m *GenesisState) Size() (n int) { if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } - if len(m.Contracts) > 0 { - for _, e := range m.Contracts { - l = e.Size() - n += 1 + l + sovGenesis(uint64(l)) - } - } if len(m.Engagement) > 0 { for _, e := range m.Engagement { l = e.Size() @@ -1773,7 +2048,7 @@ func (m *GenesisState) Size() (n int) { } if m.ArbiterPoolContractConfig != nil { l = m.ArbiterPoolContractConfig.Size() - n += 2 + l + sovGenesis(uint64(l)) + n += 1 + l + sovGenesis(uint64(l)) } return n } @@ -1830,6 +2105,9 @@ func (m *ValsetContractConfig) Size() (n int) { } l = m.DoubleSignSlashRatio.Size() n += 1 + l + sovGenesis(uint64(l)) + if m.VerifyValidators { + n += 2 + } return n } @@ -2032,10 +2310,10 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 2: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SeedContracts", wireType) } - var v int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -2045,17 +2323,32 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - m.SeedContracts = bool(v != 0) + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SeedContracts{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.SetupMode = &GenesisState_SeedContracts{v} + iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GenTxs", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ImportDump", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -2065,29 +2358,82 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenesis } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenesis } if postIndex > l { return io.ErrUnexpectedEOF } - m.GenTxs = append(m.GenTxs, make([]byte, postIndex-iNdEx)) - copy(m.GenTxs[len(m.GenTxs)-1], dAtA[iNdEx:postIndex]) + v := &ImportDump{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.SetupMode = &GenesisState_ImportDump{v} iNdEx = postIndex - case 4: + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ImportDump) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ImportDump: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ImportDump: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SystemAdminAddress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Contracts", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -2097,29 +2443,81 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenesis } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenesis } if postIndex > l { return io.ErrUnexpectedEOF } - m.SystemAdminAddress = string(dAtA[iNdEx:postIndex]) + m.Contracts = append(m.Contracts, PoEContract{}) + if err := m.Contracts[len(m.Contracts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 5: + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SeedContracts) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SeedContracts: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SeedContracts: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Contracts", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GenTxs", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -2129,27 +2527,57 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthGenesis } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthGenesis } if postIndex > l { return io.ErrUnexpectedEOF } - m.Contracts = append(m.Contracts, PoEContract{}) - if err := m.Contracts[len(m.Contracts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.GenTxs = append(m.GenTxs, make([]byte, postIndex-iNdEx)) + copy(m.GenTxs[len(m.GenTxs)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SystemAdminAddress", wireType) } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SystemAdminAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Engagement", wireType) } @@ -2183,7 +2611,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 7: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field StakeContractConfig", wireType) } @@ -2219,7 +2647,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 8: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ValsetContractConfig", wireType) } @@ -2255,7 +2683,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 9: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field EngagementContractConfig", wireType) } @@ -2291,7 +2719,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 10: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field BondDenom", wireType) } @@ -2323,7 +2751,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } m.BondDenom = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 11: + case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field OversightCommitteeContractConfig", wireType) } @@ -2359,7 +2787,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 12: + case 9: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CommunityPoolContractConfig", wireType) } @@ -2395,7 +2823,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 13: + case 10: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ValidatorVotingContractConfig", wireType) } @@ -2431,7 +2859,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 14: + case 11: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field OversightCommunityMembers", wireType) } @@ -2463,7 +2891,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } m.OversightCommunityMembers = append(m.OversightCommunityMembers, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 15: + case 12: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ArbiterPoolMembers", wireType) } @@ -2495,7 +2923,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } m.ArbiterPoolMembers = append(m.ArbiterPoolMembers, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 16: + case 13: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ArbiterPoolContractConfig", wireType) } @@ -3034,6 +3462,26 @@ func (m *ValsetContractConfig) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field VerifyValidators", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.VerifyValidators = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/poe/types/genesis_test.go b/x/poe/types/genesis_test.go index 30cf3e2e..b8617486 100644 --- a/x/poe/types/genesis_test.go +++ b/x/poe/types/genesis_test.go @@ -18,7 +18,7 @@ func TestValidateGenesis(t *testing.T) { require.NoError(t, err) txConfig := MakeEncodingConfig(t).TxConfig specs := map[string]struct { - source GenesisState + source *GenesisState expErr bool }{ "all good": { @@ -26,13 +26,13 @@ func TestValidateGenesis(t *testing.T) { }, "seed with empty engagement group": { source: GenesisStateFixture(func(m *GenesisState) { - m.Engagement = []TG4Member{} + m.GetSeedContracts().Engagement = []TG4Member{} }), expErr: true, }, "seed with duplicates in engagement group": { source: GenesisStateFixture(func(m *GenesisState) { - m.Engagement = []TG4Member{ + m.GetSeedContracts().Engagement = []TG4Member{ {Address: anyAccAddr.String(), Points: 1}, {Address: anyAccAddr.String(), Points: 2}, } @@ -41,7 +41,7 @@ func TestValidateGenesis(t *testing.T) { }, "seed with invalid addr in engagement group": { source: GenesisStateFixture(func(m *GenesisState) { - m.Engagement = []TG4Member{ + m.GetSeedContracts().Engagement = []TG4Member{ {Address: "invalid", Points: 1}, } }), @@ -49,7 +49,7 @@ func TestValidateGenesis(t *testing.T) { }, "seed with invalid weight in engagement group": { source: GenesisStateFixture(func(m *GenesisState) { - m.Engagement = []TG4Member{ + m.GetSeedContracts().Engagement = []TG4Member{ {Address: RandomAccAddress().String(), Points: 0}, } }), @@ -57,38 +57,38 @@ func TestValidateGenesis(t *testing.T) { }, "seed with legacy contracts": { source: GenesisStateFixture(func(m *GenesisState) { - m.Contracts = []PoEContract{{ContractType: PoEContractTypeValset, Address: RandomAccAddress().String()}} + m.SetupMode = &GenesisState_ImportDump{&ImportDump{Contracts: []PoEContract{{ContractType: PoEContractTypeValset, Address: RandomAccAddress().String()}}}} }), expErr: true, }, "empty bond denum": { source: GenesisStateFixture(func(m *GenesisState) { - m.BondDenom = "" + m.GetSeedContracts().BondDenom = "" }), expErr: true, }, "invalid bond denum": { source: GenesisStateFixture(func(m *GenesisState) { - m.BondDenom = "&&&" + m.GetSeedContracts().BondDenom = "&&&" }), expErr: true, }, "empty system admin": { source: GenesisStateFixture(func(m *GenesisState) { - m.SystemAdminAddress = "" + m.GetSeedContracts().SystemAdminAddress = "" }), expErr: true, }, "invalid system admin": { source: GenesisStateFixture(func(m *GenesisState) { - m.SystemAdminAddress = "invalid" + m.GetSeedContracts().SystemAdminAddress = "invalid" }), expErr: true, }, "valid gentx": { source: GenesisStateFixture(func(m *GenesisState) { - m.GenTxs = []json.RawMessage{myGenTx} - m.Engagement = append(m.Engagement, TG4Member{ + m.GetSeedContracts().GenTxs = []json.RawMessage{myGenTx} + m.GetSeedContracts().Engagement = append(m.GetSeedContracts().Engagement, TG4Member{ Address: myOperatorAddr.String(), Points: 11, }) @@ -96,8 +96,8 @@ func TestValidateGenesis(t *testing.T) { }, "duplicate gentx": { source: GenesisStateFixture(func(m *GenesisState) { - m.GenTxs = []json.RawMessage{myGenTx, myGenTx} - m.Engagement = append(m.Engagement, TG4Member{ + m.GetSeedContracts().GenTxs = []json.RawMessage{myGenTx, myGenTx} + m.GetSeedContracts().Engagement = append(m.GetSeedContracts().Engagement, TG4Member{ Address: myOperatorAddr.String(), Points: 11, }) @@ -106,97 +106,97 @@ func TestValidateGenesis(t *testing.T) { }, "validator not in engagement group": { source: GenesisStateFixture(func(m *GenesisState) { - m.GenTxs = []json.RawMessage{myGenTx} + m.GetSeedContracts().GenTxs = []json.RawMessage{myGenTx} }), expErr: true, }, "invalid gentx json": { source: GenesisStateFixture(func(m *GenesisState) { - m.GenTxs = []json.RawMessage{[]byte("invalid")} + m.GetSeedContracts().GenTxs = []json.RawMessage{[]byte("invalid")} }), expErr: true, }, "engagement contract not set": { source: GenesisStateFixture(func(m *GenesisState) { - m.EngagementContractConfig = nil + m.GetSeedContracts().EngagementContractConfig = nil }), expErr: true, }, "invalid engagement contract config": { source: GenesisStateFixture(func(m *GenesisState) { - m.EngagementContractConfig.Halflife = time.Nanosecond + m.GetSeedContracts().EngagementContractConfig.Halflife = time.Nanosecond }), expErr: true, }, "valset contract config not set": { source: GenesisStateFixture(func(m *GenesisState) { - m.ValsetContractConfig = nil + m.GetSeedContracts().ValsetContractConfig = nil }), expErr: true, }, "invalid valset contract config": { source: GenesisStateFixture(func(m *GenesisState) { - m.ValsetContractConfig.MaxValidators = 0 + m.GetSeedContracts().ValsetContractConfig.MaxValidators = 0 }), expErr: true, }, "invalid valset contract denom": { source: GenesisStateFixture(func(m *GenesisState) { - m.ValsetContractConfig.EpochReward = sdk.NewCoin("alx", m.ValsetContractConfig.EpochReward.Amount) + m.GetSeedContracts().ValsetContractConfig.EpochReward = sdk.NewCoin("alx", m.GetSeedContracts().ValsetContractConfig.EpochReward.Amount) }), expErr: true, }, "stake contract config not set": { source: GenesisStateFixture(func(m *GenesisState) { - m.StakeContractConfig = nil + m.GetSeedContracts().StakeContractConfig = nil }), expErr: true, }, "invalid stake contract config": { source: GenesisStateFixture(func(m *GenesisState) { - m.StakeContractConfig.UnbondingPeriod = 0 + m.GetSeedContracts().StakeContractConfig.UnbondingPeriod = 0 }), expErr: true, }, "oversight committee contract config not set": { source: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig = nil + m.GetSeedContracts().OversightCommitteeContractConfig = nil }), expErr: true, }, "invalid oversight committee contract config": { source: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.Name = "" + m.GetSeedContracts().OversightCommitteeContractConfig.Name = "" }), expErr: true, }, "invalid oversight committee contract denom": { source: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.EscrowAmount = sdk.NewCoin("alx", m.OversightCommitteeContractConfig.EscrowAmount.Amount) + m.GetSeedContracts().OversightCommitteeContractConfig.EscrowAmount = sdk.NewCoin("alx", m.GetSeedContracts().OversightCommitteeContractConfig.EscrowAmount.Amount) }), expErr: true, }, "community pool contract config not set": { source: GenesisStateFixture(func(m *GenesisState) { - m.CommunityPoolContractConfig = nil + m.GetSeedContracts().CommunityPoolContractConfig = nil }), expErr: true, }, "invalid community pool contract config": { source: GenesisStateFixture(func(m *GenesisState) { - m.CommunityPoolContractConfig.VotingRules.VotingPeriod = 0 + m.GetSeedContracts().CommunityPoolContractConfig.VotingRules.VotingPeriod = 0 }), expErr: true, }, "validator voting contract config not set": { source: GenesisStateFixture(func(m *GenesisState) { - m.ValidatorVotingContractConfig = nil + m.GetSeedContracts().ValidatorVotingContractConfig = nil }), expErr: true, }, "invalid validator voting contract config": { source: GenesisStateFixture(func(m *GenesisState) { - m.ValidatorVotingContractConfig.VotingRules.VotingPeriod = 0 + m.GetSeedContracts().ValidatorVotingContractConfig.VotingRules.VotingPeriod = 0 }), expErr: true, }, @@ -205,8 +205,8 @@ func TestValidateGenesis(t *testing.T) { genTx1, opAddr1, _ := RandomGenTX(t, 101, func(m *MsgCreateValidator) { m.Pubkey = myPk }) - m.GenTxs = []json.RawMessage{myGenTx, genTx1} - m.Engagement = []TG4Member{ + m.GetSeedContracts().GenTxs = []json.RawMessage{myGenTx, genTx1} + m.GetSeedContracts().Engagement = []TG4Member{ {Address: myOperatorAddr.String(), Points: 1}, {Address: opAddr1.String(), Points: 2}, } @@ -215,58 +215,58 @@ func TestValidateGenesis(t *testing.T) { }, "empty oversight community members": { source: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommunityMembers = nil + m.GetSeedContracts().OversightCommunityMembers = nil }), expErr: true, }, "duplicate oversight community members": { source: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommunityMembers = append(m.OversightCommunityMembers, m.OversightCommunityMembers[0]) + m.GetSeedContracts().OversightCommunityMembers = append(m.GetSeedContracts().OversightCommunityMembers, m.GetSeedContracts().OversightCommunityMembers[0]) }), expErr: true, }, "invalid oc members address": { source: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommunityMembers = append(m.OversightCommunityMembers, "invalid address") + m.GetSeedContracts().OversightCommunityMembers = append(m.GetSeedContracts().OversightCommunityMembers, "invalid address") }), expErr: true, }, "empty arbiter pool members": { source: GenesisStateFixture(func(m *GenesisState) { - m.ArbiterPoolMembers = nil + m.GetSeedContracts().ArbiterPoolMembers = nil }), expErr: true, }, "duplicate arbiter pool members": { source: GenesisStateFixture(func(m *GenesisState) { - m.ArbiterPoolMembers = append(m.ArbiterPoolMembers, m.ArbiterPoolMembers[0]) + m.GetSeedContracts().ArbiterPoolMembers = append(m.GetSeedContracts().ArbiterPoolMembers, m.GetSeedContracts().ArbiterPoolMembers[0]) }), expErr: true, }, "invalid ap members address": { source: GenesisStateFixture(func(m *GenesisState) { - m.ArbiterPoolMembers = append(m.ArbiterPoolMembers, "invalid address") + m.GetSeedContracts().ArbiterPoolMembers = append(m.GetSeedContracts().ArbiterPoolMembers, "invalid address") }), expErr: true, }, "arbiter pool contract config not set": { source: GenesisStateFixture(func(m *GenesisState) { - m.ArbiterPoolContractConfig = nil + m.GetSeedContracts().ArbiterPoolContractConfig = nil }), expErr: true, }, "invalid arbiter pool contract config": { source: GenesisStateFixture(func(m *GenesisState) { - m.ArbiterPoolContractConfig.DenyListContractAddress = "invalid address" + m.GetSeedContracts().ArbiterPoolContractConfig.DenyListContractAddress = "invalid address" }), expErr: true, }, } for name, spec := range specs { t.Run(name, func(t *testing.T) { - gotErr := ValidateGenesis(spec.source, txConfig.TxJSONDecoder()) + gotErr := ValidateGenesis(*spec.source, txConfig.TxJSONDecoder()) if spec.expErr { require.Error(t, gotErr) return @@ -282,17 +282,17 @@ func TestValidateEngagementContractConfig(t *testing.T) { expErr bool }{ "default": { - src: DefaultGenesisState().EngagementContractConfig, + src: DefaultGenesisState().GetSeedContracts().EngagementContractConfig, }, "halflife empty": { src: GenesisStateFixture(func(m *GenesisState) { - m.EngagementContractConfig.Halflife = 0 - }).EngagementContractConfig, + m.GetSeedContracts().EngagementContractConfig.Halflife = 0 + }).GetSeedContracts().EngagementContractConfig, }, "halflife contains elements < second": { src: GenesisStateFixture(func(m *GenesisState) { - m.EngagementContractConfig.Halflife = time.Minute + time.Millisecond - }).EngagementContractConfig, + m.GetSeedContracts().EngagementContractConfig.Halflife = time.Minute + time.Millisecond + }).GetSeedContracts().EngagementContractConfig, expErr: true, }, } @@ -314,24 +314,24 @@ func TestValidateValsetContractConfig(t *testing.T) { expErr bool }{ "default": { - src: *DefaultGenesisState().ValsetContractConfig, + src: *DefaultGenesisState().GetSeedContracts().ValsetContractConfig, }, "max validators empty": { src: *GenesisStateFixture( - func(m *GenesisState) { m.ValsetContractConfig.MaxValidators = 0 }, - ).ValsetContractConfig, + func(m *GenesisState) { m.GetSeedContracts().ValsetContractConfig.MaxValidators = 0 }, + ).GetSeedContracts().ValsetContractConfig, expErr: true, }, "scaling empty": { src: *GenesisStateFixture( - func(m *GenesisState) { m.ValsetContractConfig.Scaling = 0 }, - ).ValsetContractConfig, + func(m *GenesisState) { m.GetSeedContracts().ValsetContractConfig.Scaling = 0 }, + ).GetSeedContracts().ValsetContractConfig, expErr: true, }, "epoch length empty": { src: *GenesisStateFixture( - func(m *GenesisState) { m.ValsetContractConfig.EpochLength = 0 }, - ).ValsetContractConfig, + func(m *GenesisState) { m.GetSeedContracts().ValsetContractConfig.EpochLength = 0 }, + ).GetSeedContracts().ValsetContractConfig, expErr: true, }, "fee percentage at min": { @@ -340,9 +340,9 @@ func TestValidateValsetContractConfig(t *testing.T) { const min_fee_percentage = "0.0000000000000001" val, err := sdk.NewDecFromStr(min_fee_percentage) require.NoError(t, err) - m.ValsetContractConfig.FeePercentage = val + m.GetSeedContracts().ValsetContractConfig.FeePercentage = val }, - ).ValsetContractConfig, + ).GetSeedContracts().ValsetContractConfig, }, "fee percentage below min": { src: *GenesisStateFixture( @@ -350,76 +350,76 @@ func TestValidateValsetContractConfig(t *testing.T) { const min_fee_percentage = "0.00000000000000009" val, err := sdk.NewDecFromStr(min_fee_percentage) require.NoError(t, err) - m.ValsetContractConfig.FeePercentage = val + m.GetSeedContracts().ValsetContractConfig.FeePercentage = val }, - ).ValsetContractConfig, + ).GetSeedContracts().ValsetContractConfig, expErr: true, }, "validator rewards ratio zero": { src: *GenesisStateFixture( func(m *GenesisState) { - m.ValsetContractConfig.ValidatorRewardRatio = sdk.ZeroDec() - m.ValsetContractConfig.CommunityPoolRewardRatio = sdk.MustNewDecFromStr("52.5") + m.GetSeedContracts().ValsetContractConfig.ValidatorRewardRatio = sdk.ZeroDec() + m.GetSeedContracts().ValsetContractConfig.CommunityPoolRewardRatio = sdk.MustNewDecFromStr("52.5") }, - ).ValsetContractConfig, + ).GetSeedContracts().ValsetContractConfig, }, "validator rewards ratio 100": { src: *GenesisStateFixture( func(m *GenesisState) { - m.ValsetContractConfig.ValidatorRewardRatio = sdk.NewDec(100) - m.ValsetContractConfig.CommunityPoolRewardRatio = sdk.ZeroDec() - m.ValsetContractConfig.EngagementRewardRatio = sdk.ZeroDec() + m.GetSeedContracts().ValsetContractConfig.ValidatorRewardRatio = sdk.NewDec(100) + m.GetSeedContracts().ValsetContractConfig.CommunityPoolRewardRatio = sdk.ZeroDec() + m.GetSeedContracts().ValsetContractConfig.EngagementRewardRatio = sdk.ZeroDec() }, - ).ValsetContractConfig, + ).GetSeedContracts().ValsetContractConfig, }, "validator rewards ratio > 100": { src: *GenesisStateFixture( func(m *GenesisState) { - m.ValsetContractConfig.ValidatorRewardRatio = sdk.NewDec(101) - m.ValsetContractConfig.CommunityPoolRewardRatio = sdk.ZeroDec() - m.ValsetContractConfig.EngagementRewardRatio = sdk.ZeroDec() + m.GetSeedContracts().ValsetContractConfig.ValidatorRewardRatio = sdk.NewDec(101) + m.GetSeedContracts().ValsetContractConfig.CommunityPoolRewardRatio = sdk.ZeroDec() + m.GetSeedContracts().ValsetContractConfig.EngagementRewardRatio = sdk.ZeroDec() }, - ).ValsetContractConfig, + ).GetSeedContracts().ValsetContractConfig, expErr: true, }, "engagement rewards ratio > 100": { src: *GenesisStateFixture( func(m *GenesisState) { - m.ValsetContractConfig.EngagementRewardRatio = sdk.NewDec(101) - m.ValsetContractConfig.CommunityPoolRewardRatio = sdk.ZeroDec() - m.ValsetContractConfig.ValidatorRewardRatio = sdk.ZeroDec() + m.GetSeedContracts().ValsetContractConfig.EngagementRewardRatio = sdk.NewDec(101) + m.GetSeedContracts().ValsetContractConfig.CommunityPoolRewardRatio = sdk.ZeroDec() + m.GetSeedContracts().ValsetContractConfig.ValidatorRewardRatio = sdk.ZeroDec() }, - ).ValsetContractConfig, + ).GetSeedContracts().ValsetContractConfig, expErr: true, }, "community pool rewards ratio > 100": { src: *GenesisStateFixture( func(m *GenesisState) { - m.ValsetContractConfig.CommunityPoolRewardRatio = sdk.NewDec(101) - m.ValsetContractConfig.EngagementRewardRatio = sdk.ZeroDec() - m.ValsetContractConfig.ValidatorRewardRatio = sdk.ZeroDec() + m.GetSeedContracts().ValsetContractConfig.CommunityPoolRewardRatio = sdk.NewDec(101) + m.GetSeedContracts().ValsetContractConfig.EngagementRewardRatio = sdk.ZeroDec() + m.GetSeedContracts().ValsetContractConfig.ValidatorRewardRatio = sdk.ZeroDec() }, - ).ValsetContractConfig, + ).GetSeedContracts().ValsetContractConfig, expErr: true, }, "total rewards ratio > 100": { src: *GenesisStateFixture( func(m *GenesisState) { - m.ValsetContractConfig.CommunityPoolRewardRatio = sdk.MustNewDecFromStr("49") - m.ValsetContractConfig.EngagementRewardRatio = sdk.MustNewDecFromStr("49") - m.ValsetContractConfig.ValidatorRewardRatio = sdk.MustNewDecFromStr("3") + m.GetSeedContracts().ValsetContractConfig.CommunityPoolRewardRatio = sdk.MustNewDecFromStr("49") + m.GetSeedContracts().ValsetContractConfig.EngagementRewardRatio = sdk.MustNewDecFromStr("49") + m.GetSeedContracts().ValsetContractConfig.ValidatorRewardRatio = sdk.MustNewDecFromStr("3") }, - ).ValsetContractConfig, + ).GetSeedContracts().ValsetContractConfig, expErr: true, }, "total rewards ratio < 100": { src: *GenesisStateFixture( func(m *GenesisState) { - m.ValsetContractConfig.CommunityPoolRewardRatio = sdk.MustNewDecFromStr("10") - m.ValsetContractConfig.EngagementRewardRatio = sdk.MustNewDecFromStr("10") - m.ValsetContractConfig.ValidatorRewardRatio = sdk.MustNewDecFromStr("10") + m.GetSeedContracts().ValsetContractConfig.CommunityPoolRewardRatio = sdk.MustNewDecFromStr("10") + m.GetSeedContracts().ValsetContractConfig.EngagementRewardRatio = sdk.MustNewDecFromStr("10") + m.GetSeedContracts().ValsetContractConfig.ValidatorRewardRatio = sdk.MustNewDecFromStr("10") }, - ).ValsetContractConfig, + ).GetSeedContracts().ValsetContractConfig, expErr: true, }, } @@ -440,36 +440,40 @@ func TestValidateStakeContractConfig(t *testing.T) { expErr bool }{ "default": { - src: *DefaultGenesisState().StakeContractConfig, + src: *DefaultGenesisState().GetSeedContracts().StakeContractConfig, }, "min bond empty": { src: *GenesisStateFixture( - func(m *GenesisState) { m.StakeContractConfig.MinBond = 0 }, - ).StakeContractConfig, + func(m *GenesisState) { m.GetSeedContracts().StakeContractConfig.MinBond = 0 }, + ).GetSeedContracts().StakeContractConfig, expErr: true, }, "tokens per weight empty": { src: *GenesisStateFixture( - func(m *GenesisState) { m.StakeContractConfig.TokensPerPoint = 0 }, - ).StakeContractConfig, + func(m *GenesisState) { m.GetSeedContracts().StakeContractConfig.TokensPerPoint = 0 }, + ).GetSeedContracts().StakeContractConfig, expErr: true, }, "unbonding period empty": { src: *GenesisStateFixture( - func(m *GenesisState) { m.StakeContractConfig.UnbondingPeriod = 0 }, - ).StakeContractConfig, + func(m *GenesisState) { m.GetSeedContracts().StakeContractConfig.UnbondingPeriod = 0 }, + ).GetSeedContracts().StakeContractConfig, expErr: true, }, "unbonding period below min": { src: *GenesisStateFixture( - func(m *GenesisState) { m.StakeContractConfig.UnbondingPeriod = time.Second - time.Nanosecond }, - ).StakeContractConfig, + func(m *GenesisState) { + m.GetSeedContracts().StakeContractConfig.UnbondingPeriod = time.Second - time.Nanosecond + }, + ).GetSeedContracts().StakeContractConfig, expErr: true, }, "not convertable to seconds": { src: *GenesisStateFixture( - func(m *GenesisState) { m.StakeContractConfig.UnbondingPeriod = time.Second + time.Nanosecond }, - ).StakeContractConfig, + func(m *GenesisState) { + m.GetSeedContracts().StakeContractConfig.UnbondingPeriod = time.Second + time.Nanosecond + }, + ).GetSeedContracts().StakeContractConfig, expErr: true, }, } @@ -491,36 +495,36 @@ func TestValidateOversightCommitteeContractConfig(t *testing.T) { expErr bool }{ "default": { - src: *DefaultGenesisState().OversightCommitteeContractConfig, + src: *DefaultGenesisState().GetSeedContracts().OversightCommitteeContractConfig, }, "name empty": { src: *GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.Name = "" - }).OversightCommitteeContractConfig, + m.GetSeedContracts().OversightCommitteeContractConfig.Name = "" + }).GetSeedContracts().OversightCommitteeContractConfig, expErr: true, }, "name too long": { src: *GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.Name = strings.Repeat("a", 101) - }).OversightCommitteeContractConfig, + m.GetSeedContracts().OversightCommitteeContractConfig.Name = strings.Repeat("a", 101) + }).GetSeedContracts().OversightCommitteeContractConfig, expErr: true, }, "escrow amount too low": { src: *GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.EscrowAmount = sdk.NewCoin(DefaultBondDenom, sdk.NewInt(999_999)) - }).OversightCommitteeContractConfig, + m.GetSeedContracts().OversightCommitteeContractConfig.EscrowAmount = sdk.NewCoin(DefaultBondDenom, sdk.NewInt(999_999)) + }).GetSeedContracts().OversightCommitteeContractConfig, expErr: true, }, "voting rules invalid": { src: *GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.VotingRules.VotingPeriod = 0 - }).OversightCommitteeContractConfig, + m.GetSeedContracts().OversightCommitteeContractConfig.VotingRules.VotingPeriod = 0 + }).GetSeedContracts().OversightCommitteeContractConfig, expErr: true, }, "deny contract address not an address": { src: *GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.DenyListContractAddress = "not-an-address" - }).OversightCommitteeContractConfig, + m.GetSeedContracts().OversightCommitteeContractConfig.DenyListContractAddress = "not-an-address" + }).GetSeedContracts().OversightCommitteeContractConfig, expErr: true, }, } @@ -542,74 +546,74 @@ func TestValidateVotingRules(t *testing.T) { expErr bool }{ "default oc": { - src: DefaultGenesisState().OversightCommitteeContractConfig.VotingRules, + src: DefaultGenesisState().GetSeedContracts().OversightCommitteeContractConfig.VotingRules, }, "default community pool": { - src: DefaultGenesisState().CommunityPoolContractConfig.VotingRules, + src: DefaultGenesisState().GetSeedContracts().CommunityPoolContractConfig.VotingRules, }, "default validator voting": { - src: DefaultGenesisState().ValidatorVotingContractConfig.VotingRules, + src: DefaultGenesisState().GetSeedContracts().ValidatorVotingContractConfig.VotingRules, }, "voting period empty": { src: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.VotingRules.VotingPeriod = 0 - }).OversightCommitteeContractConfig.VotingRules, + m.GetSeedContracts().OversightCommitteeContractConfig.VotingRules.VotingPeriod = 0 + }).GetSeedContracts().OversightCommitteeContractConfig.VotingRules, expErr: true, }, "quorum empty": { src: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.VotingRules.Quorum = sdk.Dec{} - }).OversightCommitteeContractConfig.VotingRules, + m.GetSeedContracts().OversightCommitteeContractConfig.VotingRules.Quorum = sdk.Dec{} + }).GetSeedContracts().OversightCommitteeContractConfig.VotingRules, expErr: true, }, "quorum at min": { src: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.VotingRules.Quorum = sdk.OneDec() - }).OversightCommitteeContractConfig.VotingRules, + m.GetSeedContracts().OversightCommitteeContractConfig.VotingRules.Quorum = sdk.OneDec() + }).GetSeedContracts().OversightCommitteeContractConfig.VotingRules, }, "quorum less than min": { src: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.VotingRules.Quorum = sdk.ZeroDec() - }).OversightCommitteeContractConfig.VotingRules, + m.GetSeedContracts().OversightCommitteeContractConfig.VotingRules.Quorum = sdk.ZeroDec() + }).GetSeedContracts().OversightCommitteeContractConfig.VotingRules, expErr: true, }, "quorum at max": { src: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.VotingRules.Quorum = sdk.NewDec(100) - }).OversightCommitteeContractConfig.VotingRules, + m.GetSeedContracts().OversightCommitteeContractConfig.VotingRules.Quorum = sdk.NewDec(100) + }).GetSeedContracts().OversightCommitteeContractConfig.VotingRules, }, "quorum greater max": { src: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.VotingRules.Quorum = sdk.NewDec(101) - }).OversightCommitteeContractConfig.VotingRules, + m.GetSeedContracts().OversightCommitteeContractConfig.VotingRules.Quorum = sdk.NewDec(101) + }).GetSeedContracts().OversightCommitteeContractConfig.VotingRules, expErr: true, }, "threshold empty": { src: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.VotingRules.Threshold = sdk.Dec{} - }).OversightCommitteeContractConfig.VotingRules, + m.GetSeedContracts().OversightCommitteeContractConfig.VotingRules.Threshold = sdk.Dec{} + }).GetSeedContracts().OversightCommitteeContractConfig.VotingRules, expErr: true, }, "threshold at min": { src: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.VotingRules.Threshold = sdk.NewDec(50) - }).OversightCommitteeContractConfig.VotingRules, + m.GetSeedContracts().OversightCommitteeContractConfig.VotingRules.Threshold = sdk.NewDec(50) + }).GetSeedContracts().OversightCommitteeContractConfig.VotingRules, }, "threshold lower min": { src: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.VotingRules.Threshold = sdk.NewDec(49) - }).OversightCommitteeContractConfig.VotingRules, + m.GetSeedContracts().OversightCommitteeContractConfig.VotingRules.Threshold = sdk.NewDec(49) + }).GetSeedContracts().OversightCommitteeContractConfig.VotingRules, expErr: true, }, "threshold at max": { src: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.VotingRules.Threshold = sdk.NewDec(100) - }).OversightCommitteeContractConfig.VotingRules, + m.GetSeedContracts().OversightCommitteeContractConfig.VotingRules.Threshold = sdk.NewDec(100) + }).GetSeedContracts().OversightCommitteeContractConfig.VotingRules, }, "threshold greater max": { src: GenesisStateFixture(func(m *GenesisState) { - m.OversightCommitteeContractConfig.VotingRules.Threshold = sdk.NewDec(101) - }).OversightCommitteeContractConfig.VotingRules, + m.GetSeedContracts().OversightCommitteeContractConfig.VotingRules.Threshold = sdk.NewDec(101) + }).GetSeedContracts().OversightCommitteeContractConfig.VotingRules, expErr: true, }, } @@ -632,42 +636,42 @@ func TestValidateArbiterPoolContractConfig(t *testing.T) { expErr bool }{ "default": { - src: *DefaultGenesisState().ArbiterPoolContractConfig, + src: *(DefaultGenesisState().GetSeedContracts()).ArbiterPoolContractConfig, }, "name empty": { src: *GenesisStateFixture(func(m *GenesisState) { - m.ArbiterPoolContractConfig.Name = "" - }).ArbiterPoolContractConfig, + m.GetSeedContracts().ArbiterPoolContractConfig.Name = "" + }).GetSeedContracts().ArbiterPoolContractConfig, expErr: true, }, "name too long": { src: *GenesisStateFixture(func(m *GenesisState) { - m.ArbiterPoolContractConfig.Name = strings.Repeat("a", 101) - }).ArbiterPoolContractConfig, + m.GetSeedContracts().ArbiterPoolContractConfig.Name = strings.Repeat("a", 101) + }).GetSeedContracts().ArbiterPoolContractConfig, expErr: true, }, "escrow amount too low": { src: *GenesisStateFixture(func(m *GenesisState) { - m.ArbiterPoolContractConfig.EscrowAmount = sdk.NewCoin(DefaultBondDenom, sdk.NewInt(999_999)) - }).ArbiterPoolContractConfig, + m.GetSeedContracts().ArbiterPoolContractConfig.EscrowAmount = sdk.NewCoin(DefaultBondDenom, sdk.NewInt(999_999)) + }).GetSeedContracts().ArbiterPoolContractConfig, expErr: true, }, "voting rules invalid": { src: *GenesisStateFixture(func(m *GenesisState) { - m.ArbiterPoolContractConfig.VotingRules.VotingPeriod = 0 - }).ArbiterPoolContractConfig, + m.GetSeedContracts().ArbiterPoolContractConfig.VotingRules.VotingPeriod = 0 + }).GetSeedContracts().ArbiterPoolContractConfig, expErr: true, }, "deny contract address not an address": { src: *GenesisStateFixture(func(m *GenesisState) { - m.ArbiterPoolContractConfig.DenyListContractAddress = "not-an-address" - }).ArbiterPoolContractConfig, + m.GetSeedContracts().ArbiterPoolContractConfig.DenyListContractAddress = "not-an-address" + }).GetSeedContracts().ArbiterPoolContractConfig, expErr: true, }, "not convertible to seconds": { src: *GenesisStateFixture(func(m *GenesisState) { - m.ArbiterPoolContractConfig.WaitingPeriod = time.Second + time.Nanosecond - }).ArbiterPoolContractConfig, + m.GetSeedContracts().ArbiterPoolContractConfig.WaitingPeriod = time.Second + time.Nanosecond + }).GetSeedContracts().ArbiterPoolContractConfig, expErr: true, }, } diff --git a/x/poe/types/genesisio.go b/x/poe/types/genesisio.go index f8434308..b5194a8e 100644 --- a/x/poe/types/genesisio.go +++ b/x/poe/types/genesisio.go @@ -3,6 +3,8 @@ package types import ( "encoding/json" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -33,7 +35,10 @@ func SetGenTxsInAppGenesisState( genTxsBz = append(genTxsBz, txBz) } - genesisState.GenTxs = genTxsBz + if genesisState.GetSeedContracts() == nil { + return nil, sdkerrors.ErrNotSupported.Wrap("in state dump import mode") + } + genesisState.GetSeedContracts().GenTxs = genTxsBz return SetGenesisStateInAppState(cdc, appGenesisState, genesisState), nil } diff --git a/x/poe/types/test_fixtures.go b/x/poe/types/test_fixtures.go index 99244e9b..2a158ca1 100644 --- a/x/poe/types/test_fixtures.go +++ b/x/poe/types/test_fixtures.go @@ -33,18 +33,18 @@ func MsgUpdateValidatorFixture(mutators ...func(m *MsgUpdateValidator)) *MsgUpda return r } -func GenesisStateFixture(mutators ...func(m *GenesisState)) GenesisState { +func GenesisStateFixture(mutators ...func(m *GenesisState)) *GenesisState { r := DefaultGenesisState() - r.Engagement = []TG4Member{{ + r.GetSeedContracts().Engagement = []TG4Member{{ Address: RandomAccAddress().String(), Points: 10, }} - r.OversightCommunityMembers = []string{RandomAccAddress().String(), RandomAccAddress().String()} - r.ArbiterPoolMembers = []string{RandomAccAddress().String(), RandomAccAddress().String()} + r.GetSeedContracts().OversightCommunityMembers = []string{RandomAccAddress().String(), RandomAccAddress().String()} + r.GetSeedContracts().ArbiterPoolMembers = []string{RandomAccAddress().String(), RandomAccAddress().String()} for _, m := range mutators { - m(&r) + m(r) } return r } @@ -56,7 +56,7 @@ func SetGenesisOCMembersMutator(members ...sdk.AccAddress) func(m *GenesisState) for i, v := range members { oc[i] = v.String() } - m.OversightCommunityMembers = oc + m.GetSeedContracts().OversightCommunityMembers = oc } } diff --git a/x/twasm/client/cli/genesisio.go b/x/twasm/client/cli/genesisio.go index 5a383171..dc0600af 100644 --- a/x/twasm/client/cli/genesisio.go +++ b/x/twasm/client/cli/genesisio.go @@ -34,7 +34,13 @@ func NewGenesisIO() *GenesisIO { // and marshals the modified state back into the genesis file func (x GenesisIO) AlterWasmModuleState(cmd *cobra.Command, callback func(state *wasmtypes.GenesisState, appState map[string]json.RawMessage) error) error { return x.AlterTWasmModuleState(cmd, func(state *types.GenesisState, appState map[string]json.RawMessage) error { - return callback(&state.Wasm, appState) + wasmState := state.RawWasmState() + if err := callback(&wasmState, appState); err != nil { + return err + } + // update genesis messages as they can be modified + state.GenMsgs = wasmState.GenMsgs + return nil }) } @@ -98,12 +104,13 @@ func (d GenesisReader) ReadTWasmGenesis(cmd *cobra.Command) (*TWasmGenesisData, clientCtx := client.GetClientContextFromCmd(cmd) clientCtx.Codec.MustUnmarshalJSON(appState[types.ModuleName], &twasmGenesisState) } + wasmState := twasmGenesisState.RawWasmState() return &TWasmGenesisData{ GenesisData: wasmcli.NewGenesisData( genFile, genDoc, appState, - &twasmGenesisState.Wasm, + &wasmState, ), twasmModuleState: twasmGenesisState, }, nil diff --git a/x/twasm/contract/callback_msgs.go b/x/twasm/contract/callback_msgs.go index ed406e6c..03e7dd1d 100644 --- a/x/twasm/contract/callback_msgs.go +++ b/x/twasm/contract/callback_msgs.go @@ -1,5 +1,9 @@ package contract +import ( + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" +) + // TgradeSudoMsg callback message sent to a contract. // See https://github.com/confio/tgrade-contracts/blob/main/packages/bindings/src/sudo.rs type TgradeSudoMsg struct { @@ -7,11 +11,16 @@ type TgradeSudoMsg struct { BeginBlock *BeginBlock `json:"begin_block,omitempty"` // This will be delivered every block if the contract is currently registered for End Block - /// Block height and time is already in Env + // Block height and time is already in Env EndBlock *struct{} `json:"end_block,omitempty"` - /// This will be delivered after everything. - /// The data in the Response is (JSON?) encoded diff to the validator set + // This will be delivered after everything. + // The data in the Response is (JSON?) encoded diff to the validator set EndWithValidatorUpdate *struct{} `json:"end_with_validator_update,omitempty"` + + // Export dump state for genesis export + Export *struct{} `json:"export,omitempty"` + // Import genesis state + Import *wasmtypes.RawContractMessage `json:"import,omitempty"` } // PrivilegeChangeMsg is called on a contract when it is made privileged or demoted diff --git a/x/twasm/keeper/genesis.go b/x/twasm/keeper/genesis.go index cf598187..71e77ef2 100644 --- a/x/twasm/keeper/genesis.go +++ b/x/twasm/keeper/genesis.go @@ -1,12 +1,17 @@ package keeper import ( + "encoding/json" + "fmt" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" abci "github.com/tendermint/tendermint/abci/types" + "github.com/confio/tgrade/x/twasm/contract" + "github.com/confio/tgrade/x/twasm/types" ) @@ -26,15 +31,13 @@ func InitGenesis( data types.GenesisState, msgHandler sdk.Handler, ) ([]abci.ValidatorUpdate, error) { - // todo: stakingKeeper should talk with contract - result, err := wasmkeeper.InitGenesis(ctx, &keeper.Keeper, data.Wasm, noopValsetUpdater{}, msgHandler) + result, err := wasmkeeper.InitGenesis(ctx, &keeper.Keeper, data.RawWasmState(), noopValsetUpdater{}, msgHandler) if err != nil { return nil, sdkerrors.Wrap(err, "wasm") } - // import callbacks from dumped contract infos - importedCallbackContracts := make(map[string]struct{}) - for i, m := range data.Wasm.Contracts { + // import privileges from dumped contract infos + for i, m := range data.Contracts { info := m.ContractInfo var d types.TgradeContractDetails if err := info.ReadExtension(&d); err != nil { @@ -51,15 +54,25 @@ func InitGenesis( if err := keeper.importPrivileged(ctx, addr, info.CodeID, d); err != nil { return nil, sdkerrors.Wrapf(err, "privilege registration for contract: %s", m.ContractAddress) } - importedCallbackContracts[m.ContractAddress] = struct{}{} + + // import custom state when privilege set + if d.HasRegisteredPrivilege(types.PrivilegeStateExporterImporter) { + model := m.GetCustomModel() + if model == nil { + return nil, sdkerrors.Wrapf(wasmtypes.ErrInvalidGenesis, "custom state model not set for %s", m.ContractAddress) + } + bz, err := json.Marshal(contract.TgradeSudoMsg{Import: &model.Msg}) + if err != nil { + return nil, sdkerrors.Wrapf(err, "marshal state import for %s", m.ContractAddress) + } + if _, err = keeper.Keeper.Sudo(ctx, addr, bz); err != nil { + return nil, sdkerrors.Wrapf(err, "init custom state for %s", m.ContractAddress) + } + } } // set privileged for i, a := range data.PrivilegedContractAddresses { - if _, ok := importedCallbackContracts[a]; ok { - delete(importedCallbackContracts, a) - continue // done via import already - } // handle new genesis message contract addr, err := sdk.AccAddressFromBech32(a) if err != nil { @@ -76,21 +89,55 @@ func InitGenesis( return nil, sdkerrors.Wrapf(err, "pin code with ID %d", codeID) } } - - // sanity check that we do not have a callback imported without a privileged flag missing - if len(importedCallbackContracts) != 0 { - return nil, sdkerrors.Wrapf(wasmtypes.ErrInvalidGenesis, "unprivileged contracts with system callbacks: %#v", importedCallbackContracts) - } return result, nil } // ExportGenesis returns a GenesisState for a given context and keeper. func ExportGenesis(ctx sdk.Context, keeper *Keeper) *types.GenesisState { - var genState types.GenesisState - genState.Wasm = *wasmkeeper.ExportGenesis(ctx, &keeper.Keeper) - keeper.IteratePrivileged(ctx, func(contract sdk.AccAddress) bool { - genState.PrivilegedContractAddresses = append(genState.PrivilegedContractAddresses, contract.String()) - return false - }) + wasmState := wasmkeeper.ExportGenesis(ctx, &keeper.Keeper) + contracts := make([]types.Contract, len(wasmState.Contracts)) + for i, v := range wasmState.Contracts { + contracts[i] = types.Contract{ + ContractAddress: v.ContractAddress, + ContractInfo: v.ContractInfo, + } + + var details types.TgradeContractDetails + if err := v.ContractInfo.ReadExtension(&details); err != nil { + panic(fmt.Sprintf("read contract info extension for %s", v.ContractAddress)) + } + if !details.HasRegisteredPrivilege(types.PrivilegeStateExporterImporter) { + contracts[i].ContractState = &types.Contract_KvModel{KvModel: &types.KVModel{Models: v.ContractState}} + continue + } + c, err := sdk.AccAddressFromBech32(v.ContractAddress) + if err != nil { + panic(fmt.Sprintf("address %s: %s", v.ContractAddress, err)) + } + bz, err := json.Marshal(contract.TgradeSudoMsg{Export: &struct{}{}}) + if err != nil { + panic(sdkerrors.Wrapf(err, "marshal state export for %s", c.String())) + } + got, err := keeper.Keeper.Sudo(ctx, c, bz) + if err != nil { + panic(sdkerrors.Wrapf(err, "export custom state for %s with %q", c.String(), string(bz))) + } + contracts[i].ContractState = &types.Contract_CustomModel{CustomModel: &types.CustomModel{Msg: got}} + } + + genState := types.GenesisState{ + Params: wasmState.Params, + Codes: wasmState.Codes, + Contracts: contracts, + Sequences: wasmState.Sequences, + GenMsgs: wasmState.GenMsgs, + } + + // pinned is stored in code info + // privileges are stored contract info + // no need to store them again in the genesis fields + // + // note: when a privileged contract address is added to the genesis.privileged_contract_addresses then + // the sudo promote call is executed again so that the contract can register additional privileges return &genState } diff --git a/x/twasm/keeper/genesis_test.go b/x/twasm/keeper/genesis_test.go index b4ab1843..3d3b5f9c 100644 --- a/x/twasm/keeper/genesis_test.go +++ b/x/twasm/keeper/genesis_test.go @@ -3,8 +3,11 @@ package keeper import ( "crypto/sha256" "encoding/json" + "errors" "testing" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" "github.com/CosmWasm/wasmd/x/wasm/keeper/wasmtesting" @@ -20,6 +23,10 @@ import ( ) func TestInitGenesis(t *testing.T) { + type vmCalls struct { + pinCalled bool + sudoCalled bool + } noopMock := NewWasmVMMock(func(m *wasmtesting.MockWasmer) { m.PinFn = func(checksum cosmwasm.Checksum) error { return nil } m.SudoFn = func(codeID cosmwasm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store cosmwasm.KVStore, goapi cosmwasm.GoAPI, querier cosmwasm.Querier, gasMeter cosmwasm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) { @@ -38,16 +45,18 @@ func TestInitGenesis(t *testing.T) { wasmvm *wasmtesting.MockWasmer expCallbackReg []registeredCallback expErr bool + expVmCalls vmCalls }{ "pin WASM code": { state: types.GenesisStateFixture(t, func(state *types.GenesisState) { - state.Wasm.Codes = append(state.Wasm.Codes, + state.Codes = append(state.Codes, wasmtypes.CodeFixture(func(c *wasmtypes.Code) { c.CodeID = 5 }), wasmtypes.CodeFixture(func(c *wasmtypes.Code) { c.CodeID = 7 }), ) state.PinnedCodeIDs = []uint64{5, 7} }), - wasmvm: noopMock, + wasmvm: noopMock, + expVmCalls: vmCalls{true, true}, }, "privileged contract": { state: types.GenesisStateFixture(t), @@ -69,7 +78,7 @@ func TestInitGenesis(t *testing.T) { "privilege set for dumped contract": { state: types.GenesisStateFixture(t, func(state *types.GenesisState) { state.PrivilegedContractAddresses = []string{genContractAddress(2, 2).String()} - state.Wasm.Contracts[1] = wasmtypes.ContractFixture(func(contract *wasmtypes.Contract) { + state.Contracts[1] = types.ContractFixture(t, func(contract *types.Contract) { contract.ContractAddress = genContractAddress(2, 2).String() err := contract.ContractInfo.SetExtension(&types.TgradeContractDetails{ RegisteredPrivileges: []types.RegisteredPrivilege{{Position: 1, PrivilegeType: "begin_blocker"}}, @@ -84,9 +93,9 @@ func TestInitGenesis(t *testing.T) { "privilege set for gen msg contract": { state: types.GenesisStateFixture(t, func(state *types.GenesisState) { state.PrivilegedContractAddresses = []string{genContractAddress(2, 1).String()} - state.Wasm.Contracts = nil - state.Wasm.Sequences = []wasmtypes.Sequence{{IDKey: wasmtypes.KeyLastCodeID, Value: 3}} - state.Wasm.GenMsgs = []wasmtypes.GenesisState_GenMsgs{ + state.Contracts = nil + state.Sequences = []wasmtypes.Sequence{{IDKey: wasmtypes.KeyLastCodeID, Value: 3}} + state.GenMsgs = []wasmtypes.GenesisState_GenMsgs{ {Sum: &wasmtypes.GenesisState_GenMsgs_InstantiateContract{ InstantiateContract: wasmtypes.MsgInstantiateContractFixture( func(msg *wasmtypes.MsgInstantiateContract) { @@ -110,17 +119,87 @@ func TestInitGenesis(t *testing.T) { }), expCallbackReg: []registeredCallback{{pos: 1, cbt: types.PrivilegeTypeEndBlock, addr: genContractAddress(2, 1)}}, }, - "privileges set from dump but not privileged anymore": { + "privileges set from dump": { state: types.GenesisStateFixture(t, func(state *types.GenesisState) { state.PrivilegedContractAddresses = nil - err := state.Wasm.Contracts[1].ContractInfo.SetExtension(&types.TgradeContractDetails{ + state.Contracts[1].ContractAddress = genContractAddress(2, 2).String() + err := state.Contracts[1].ContractInfo.SetExtension(&types.TgradeContractDetails{ RegisteredPrivileges: []types.RegisteredPrivilege{{Position: 1, PrivilegeType: "begin_blocker"}}, }) require.NoError(t, err) }), + wasmvm: noopMock, + expCallbackReg: []registeredCallback{{pos: 1, cbt: types.PrivilegeTypeBeginBlock, addr: genContractAddress(2, 2)}}, + }, + "invalid contract details from dump": { + state: types.GenesisStateFixture(t, func(state *types.GenesisState) { + state.PrivilegedContractAddresses = nil + var err error + state.Contracts[1].ContractInfo.Extension, err = codectypes.NewAnyWithValue(&types.TgradeContractDetails{ + RegisteredPrivileges: []types.RegisteredPrivilege{{Position: 1, PrivilegeType: "non-existing-privilege"}}, + }) + require.NoError(t, err) + }), + wasmvm: noopMock, + expErr: true, + }, + "no contract details in dump": { + state: types.GenesisStateFixture(t, func(state *types.GenesisState) { + state.PrivilegedContractAddresses = nil + require.NoError(t, state.Contracts[1].ContractInfo.SetExtension(nil)) + }), + wasmvm: noopMock, + }, + "privileged state importer contract imports from dump": { + state: types.GenesisStateFixture(t, func(state *types.GenesisState) { + state.PrivilegedContractAddresses = nil + state.Contracts[1].ContractAddress = genContractAddress(2, 2).String() + state.Contracts[1].ContractState = &types.Contract_CustomModel{CustomModel: &types.CustomModel{Msg: wasmtypes.RawContractMessage(`{"my":"state"}`)}} + err := state.Contracts[1].ContractInfo.SetExtension(&types.TgradeContractDetails{ + RegisteredPrivileges: []types.RegisteredPrivilege{{Position: 1, PrivilegeType: "state_exporter_importer"}}, + }) + require.NoError(t, err) + }), + wasmvm: NewWasmVMMock(func(m *wasmtesting.MockWasmer) { + m.PinFn = func(checksum cosmwasm.Checksum) error { return nil } + m.SudoFn = func(codeID cosmwasm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store cosmwasm.KVStore, goapi cosmwasm.GoAPI, querier cosmwasm.Querier, gasMeter cosmwasm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) { + return &wasmvmtypes.Response{}, 0, nil + } + }), + expCallbackReg: []registeredCallback{{pos: 1, cbt: types.PrivilegeStateExporterImporter, addr: genContractAddress(2, 2)}}, + }, + "privileged state importer contract imports from dump with custom model removed": { + state: types.GenesisStateFixture(t, func(state *types.GenesisState) { + state.PrivilegedContractAddresses = nil + state.Contracts[1].ContractAddress = genContractAddress(2, 2).String() + state.Contracts[1].ContractState = &types.Contract_CustomModel{} + err := state.Contracts[1].ContractInfo.SetExtension(&types.TgradeContractDetails{ + RegisteredPrivileges: []types.RegisteredPrivilege{{Position: 1, PrivilegeType: "state_exporter_importer"}}, + }) + require.NoError(t, err) + }), wasmvm: noopMock, expErr: true, }, + "privileged state importer contract imports fails on sudo call with custom msg": { + state: types.GenesisStateFixture(t, func(state *types.GenesisState) { + state.PrivilegedContractAddresses = nil + state.Contracts[0].ContractAddress = genContractAddress(2, 2).String() + state.Contracts[0].ContractState = &types.Contract_CustomModel{CustomModel: &types.CustomModel{Msg: wasmtypes.RawContractMessage(`{"my":"state"}`)}} + err := state.Contracts[0].ContractInfo.SetExtension(&types.TgradeContractDetails{ + RegisteredPrivileges: []types.RegisteredPrivilege{{Position: 1, PrivilegeType: "state_exporter_importer"}}, + }) + require.NoError(t, err) + state.Contracts = []types.Contract{state.Contracts[0]} + }), + wasmvm: NewWasmVMMock(func(m *wasmtesting.MockWasmer) { + m.PinFn = func(checksum cosmwasm.Checksum) error { return nil } + m.SudoFn = func(codeID cosmwasm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store cosmwasm.KVStore, goapi cosmwasm.GoAPI, querier cosmwasm.Querier, gasMeter cosmwasm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) { + return &wasmvmtypes.Response{}, 0, errors.New("testing error") + } + }), + expErr: true, + }, } for name, spec := range specs { t.Run(name, func(t *testing.T) { @@ -149,15 +228,15 @@ func TestInitGenesis(t *testing.T) { assert.True(t, k.IsPinnedCode(ctx, id)) } - var allCallbacks int + var allRegisteredCallbacksCount int for _, n := range types.AllPrivilegeTypeNames() { cb := *types.PrivilegeTypeFrom(n) k.IteratePrivilegedContractsByType(ctx, cb, func(prio uint8, contractAddr sdk.AccAddress) bool { - allCallbacks++ + allRegisteredCallbacksCount++ return false }) } - require.Equal(t, len(spec.expCallbackReg), allCallbacks) + require.Equal(t, len(spec.expCallbackReg), allRegisteredCallbacksCount) for _, x := range spec.expCallbackReg { gotAddr := k.getPrivilegedContract(ctx, x.cbt, x.pos) assert.Equal(t, x.addr, gotAddr) @@ -168,7 +247,7 @@ func TestInitGenesis(t *testing.T) { func TestExportGenesis(t *testing.T) { wasmCodes := make(map[string]cosmwasm.WasmCode) - mock := NewWasmVMMock(func(m *wasmtesting.MockWasmer) { + noopVMMock := NewWasmVMMock(func(m *wasmtesting.MockWasmer) { m.CreateFn = func(code cosmwasm.WasmCode) (cosmwasm.Checksum, error) { hash := sha256.Sum256(code) wasmCodes[string(hash[:])] = code @@ -186,34 +265,98 @@ func TestExportGenesis(t *testing.T) { }) specs := map[string]struct { - state types.GenesisState - expErr bool + srcState types.GenesisState + expState types.GenesisState + alterState func(ctx sdk.Context, keepers TestKeepers) + expErr bool + mockVM *wasmtesting.MockWasmer }{ "export with privileged contract": { - state: types.GenesisStateFixture(t), + srcState: types.DeterministicGenesisStateFixture(t, func(state *types.GenesisState) { + state.PrivilegedContractAddresses = []string{genContractAddress(1, 1).String()} + }), + alterState: func(ctx sdk.Context, keepers TestKeepers) { + priv := types.PrivilegeTypeBeginBlock + setContractPrivilege(t, ctx, keepers, genContractAddress(1, 1), priv) + }, + expState: types.DeterministicGenesisStateFixture(t, func(state *types.GenesisState) { + state.PrivilegedContractAddresses = nil + state.Contracts[1].ContractAddress = genContractAddress(1, 1).String() + err := state.Contracts[1].ContractInfo.SetExtension(&types.TgradeContractDetails{ + RegisteredPrivileges: []types.RegisteredPrivilege{{Position: 1, PrivilegeType: "begin_blocker"}}, + }) + require.NoError(t, err) + }), + mockVM: noopVMMock, + }, + "privileged state exporter contract": { + srcState: types.DeterministicGenesisStateFixture(t, func(state *types.GenesisState) { + state.PrivilegedContractAddresses = []string{genContractAddress(1, 1).String()} + }), + expState: types.DeterministicGenesisStateFixture(t, func(state *types.GenesisState) { + state.PrivilegedContractAddresses = nil + state.Contracts[1].ContractState = &types.Contract_CustomModel{CustomModel: &types.CustomModel{Msg: wasmtypes.RawContractMessage(`{"my":"state"}`)}} + err := state.Contracts[1].ContractInfo.SetExtension(&types.TgradeContractDetails{ + RegisteredPrivileges: []types.RegisteredPrivilege{{Position: 1, PrivilegeType: "state_exporter_importer"}}, + }) + require.NoError(t, err) + }), + alterState: func(ctx sdk.Context, keepers TestKeepers) { + priv := types.PrivilegeStateExporterImporter + setContractPrivilege(t, ctx, keepers, genContractAddress(1, 1), priv) + }, + mockVM: NewWasmVMMock(func(m *wasmtesting.MockWasmer) { + m.CreateFn = noopVMMock.CreateFn + m.PinFn = noopVMMock.PinFn + m.GetCodeFn = noopVMMock.GetCodeFn + m.SudoFn = func(codeID cosmwasm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store cosmwasm.KVStore, goapi cosmwasm.GoAPI, querier cosmwasm.Querier, gasMeter cosmwasm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) { + // return tgrade message with exported state + return &wasmvmtypes.Response{ + Data: []byte(`{"my":"state"}`), + }, 0, nil + } + }), }, "export without privileged contracts": { - state: types.GenesisStateFixture(t, func(state *types.GenesisState) { + srcState: types.DeterministicGenesisStateFixture(t, func(state *types.GenesisState) { + state.PrivilegedContractAddresses = nil + }), + expState: types.DeterministicGenesisStateFixture(t, func(state *types.GenesisState) { state.PrivilegedContractAddresses = nil }), + mockVM: noopVMMock, }, } for name, spec := range specs { t.Run(name, func(t *testing.T) { - ctx, keepers := CreateDefaultTestInput(t, wasmkeeper.WithWasmEngine(mock)) + ctx, keepers := CreateDefaultTestInput(t, wasmkeeper.WithWasmEngine(spec.mockVM)) k := keepers.TWasmKeeper msgHandler := wasm.NewHandler(wasmkeeper.NewDefaultPermissionKeeper(k)) - _, err := InitGenesis(ctx, k, spec.state, msgHandler) + _, err := InitGenesis(ctx, k, spec.srcState, msgHandler) require.NoError(t, err) + if spec.alterState != nil { + spec.alterState(ctx, keepers) + } // when & then newState := ExportGenesis(ctx, k) - assert.Equal(t, spec.state, *newState) + assert.Equal(t, spec.expState, *newState) }) } } +func setContractPrivilege(t *testing.T, ctx sdk.Context, keepers TestKeepers, contractAddr sdk.AccAddress, priv types.PrivilegeType) { + t.Helper() + var details types.TgradeContractDetails + contractInfo := keepers.TWasmKeeper.GetContractInfo(ctx, contractAddr) + require.NoError(t, contractInfo.ReadExtension(&details)) + pos, err := keepers.TWasmKeeper.appendToPrivilegedContracts(ctx, priv, contractAddr) + require.NoError(t, err) + details.AddRegisteredPrivilege(priv, pos) + require.NoError(t, keepers.TWasmKeeper.setContractDetails(ctx, contractAddr, &details)) +} + // genContractAddress generates a contract address as wasmd keeper does func genContractAddress(codeID, instanceID uint64) sdk.AccAddress { return wasmkeeper.BuildContractAddress(codeID, instanceID) diff --git a/x/twasm/module.go b/x/twasm/module.go index 034ad741..3d3aec6f 100644 --- a/x/twasm/module.go +++ b/x/twasm/module.go @@ -58,9 +58,7 @@ func (AppModuleBasic) Name() string { // module. func (b AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { return cdc.MustMarshalJSON(&types.GenesisState{ - Wasm: wasmtypes.GenesisState{ - Params: wasmtypes.DefaultParams(), - }, + Params: wasmtypes.DefaultParams(), }) } diff --git a/x/twasm/types/codec.go b/x/twasm/types/codec.go index d63c38b3..7a8eba97 100644 --- a/x/twasm/types/codec.go +++ b/x/twasm/types/codec.go @@ -13,6 +13,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { wasmtypes.RegisterLegacyAminoCodec(cdc) cdc.RegisterConcrete(&PromoteToPrivilegedContractProposal{}, "twasm/PromoteToPrivilegedContractProposal", nil) cdc.RegisterConcrete(&DemotePrivilegedContractProposal{}, "twasm/DemotePrivilegedContractProposal", nil) + cdc.RegisterConcrete(&TgradeContractDetails{}, "twasm/TgradeContractDetails", nil) } @@ -27,8 +28,6 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { (*wasmtypes.ContractInfoExtension)(nil), &TgradeContractDetails{}, ) - - //msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } var ( diff --git a/x/twasm/types/contract_extension.go b/x/twasm/types/contract_extension.go index 588357f4..0606aa3a 100644 --- a/x/twasm/types/contract_extension.go +++ b/x/twasm/types/contract_extension.go @@ -7,7 +7,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -//AddRegisteredPrivilege add privilege type to list +// AddRegisteredPrivilege add privilege type to list func (d *TgradeContractDetails) AddRegisteredPrivilege(t PrivilegeType, pos uint8) { d.RegisteredPrivileges = append(d.RegisteredPrivileges, RegisteredPrivilege{ PrivilegeType: t.String(), @@ -28,7 +28,7 @@ func (d *TgradeContractDetails) RemoveRegisteredPrivilege(t PrivilegeType, pos u } } -// HasRegisteredPrivilege returs true when given type was registered by this contract +// HasRegisteredPrivilege returns true when given type was registered by this contract func (d *TgradeContractDetails) HasRegisteredPrivilege(c PrivilegeType) bool { for _, v := range d.RegisteredPrivileges { if v.PrivilegeType == c.String() { diff --git a/x/twasm/types/genesis.go b/x/twasm/types/genesis.go index c8330273..2e63767b 100644 --- a/x/twasm/types/genesis.go +++ b/x/twasm/types/genesis.go @@ -2,16 +2,20 @@ package types import ( wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) +// defined via in protobuf package structure. Note the leading `/` +const tgradeExtType = "/confio.twasm.v1beta1.TgradeContractDetails" + func (g GenesisState) ValidateBasic() error { - if err := g.Wasm.ValidateBasic(); err != nil { + wasmState := g.RawWasmState() + if err := wasmState.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "wasm") } - const tgradeExtType = "confio.twasm.v1beta1.TgradeContractDetails" - for _, c := range g.Wasm.Contracts { + for _, c := range wasmState.Contracts { if c.ContractInfo.Extension != nil { if tgradeExtType != c.ContractInfo.Extension.TypeUrl { return sdkerrors.Wrapf(wasmtypes.ErrInvalidGenesis, "invalid extension type: %s, contract %s", c.ContractInfo.Extension.TypeUrl, c.ContractAddress) @@ -39,7 +43,7 @@ func (g GenesisState) ValidateBasic() error { uniquePinnedCodeIDs[code] = struct{}{} } - genesisCodes, err := getAllCodes(&g.Wasm) + genesisCodes, err := getAllCodes(&wasmState) if err != nil { return sdkerrors.Wrapf(wasmtypes.ErrInvalid, "genesis codes: %s", err.Error()) } @@ -50,7 +54,7 @@ func (g GenesisState) ValidateBasic() error { return sdkerrors.Wrapf(wasmtypes.ErrInvalidGenesis, "%d pinned codeIDs not found in genesis codeIDs", len(uniquePinnedCodeIDs)) } - genesisContracts := getAllContracts(&g.Wasm) + genesisContracts := getAllContracts(&wasmState) for _, contract := range genesisContracts { delete(uniqueAddr, contract.ContractAddress) } @@ -60,3 +64,46 @@ func (g GenesisState) ValidateBasic() error { return nil } + +// RawWasmState convert to wasm genesis state for vanilla import. +// Custom data models for privileged contracts are not included +func (g GenesisState) RawWasmState() wasmtypes.GenesisState { + contracts := make([]wasmtypes.Contract, len(g.Contracts)) + for i, v := range g.Contracts { + var s []wasmtypes.Model + if m := v.GetKvModel(); m != nil { + s = m.Models + } + contracts[i] = wasmtypes.Contract{ + ContractAddress: v.ContractAddress, + ContractInfo: v.ContractInfo, + ContractState: s, + } + } + return wasmtypes.GenesisState{ + Params: g.Params, + Codes: g.Codes, + Contracts: contracts, + Sequences: g.Sequences, + GenMsgs: g.GenMsgs, + } +} + +var _ codectypes.UnpackInterfacesMessage = GenesisState{} + +// UnpackInterfaces implements codectypes.UnpackInterfaces +func (m GenesisState) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + for _, v := range m.Contracts { + if err := v.UnpackInterfaces(unpacker); err != nil { + return err + } + } + return nil +} + +var _ codectypes.UnpackInterfacesMessage = &Contract{} + +// UnpackInterfaces implements codectypes.UnpackInterfaces +func (m *Contract) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + return m.ContractInfo.UnpackInterfaces(unpacker) +} diff --git a/x/twasm/types/genesis.pb.go b/x/twasm/types/genesis.pb.go index 269f6c6e..585f8f05 100644 --- a/x/twasm/types/genesis.pb.go +++ b/x/twasm/types/genesis.pb.go @@ -9,6 +9,7 @@ import ( math "math" math_bits "math/bits" + github_com_CosmWasm_wasmd_x_wasm_types "github.com/CosmWasm/wasmd/x/wasm/types" types "github.com/CosmWasm/wasmd/x/wasm/types" _ "github.com/cosmos/cosmos-sdk/types" _ "github.com/gogo/protobuf/gogoproto" @@ -27,9 +28,21 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type GenesisState struct { - Wasm types.GenesisState `protobuf:"bytes,1,opt,name=wasm,proto3" json:"wasm_genesis,omitempty"` - PrivilegedContractAddresses []string `protobuf:"bytes,2,rep,name=privileged_contract_addresses,json=privilegedContractAddresses,proto3" json:"privileged_contract_addresses,omitempty"` - PinnedCodeIDs []uint64 `protobuf:"varint,3,rep,packed,name=pinned_code_ids,json=pinnedCodeIds,proto3" json:"pinned_code_ids,omitempty"` + // Params sdk type Params for wasmd + Params types.Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // Codes has all stored wasm codes and metadata + Codes []types.Code `protobuf:"bytes,2,rep,name=codes,proto3" json:"codes,omitempty"` + // Contracts contains all instantiated contracts, state and metadata + Contracts []Contract `protobuf:"bytes,3,rep,name=contracts,proto3" json:"contracts,omitempty"` + // Sequences names and values + Sequences []types.Sequence `protobuf:"bytes,4,rep,name=sequences,proto3" json:"sequences,omitempty"` + // GenMsgs has wasmd sdk type messages to execute in the genesis phase + GenMsgs []types.GenesisState_GenMsgs `protobuf:"bytes,5,rep,name=gen_msgs,json=genMsgs,proto3" json:"gen_msgs,omitempty"` + // PrivilegedContractAddresses is a list of contract addresses that can have + // special permissions + PrivilegedContractAddresses []string `protobuf:"bytes,6,rep,name=privileged_contract_addresses,json=privilegedContractAddresses,proto3" json:"privileged_contract_addresses,omitempty"` + // PinnedCodeIDs has codeInfo ids for wasm codes that are pinned in cache + PinnedCodeIDs []uint64 `protobuf:"varint,7,rep,packed,name=pinned_code_ids,json=pinnedCodeIds,proto3" json:"pinned_code_ids,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -65,11 +78,39 @@ func (m *GenesisState) XXX_DiscardUnknown() { var xxx_messageInfo_GenesisState proto.InternalMessageInfo -func (m *GenesisState) GetWasm() types.GenesisState { +func (m *GenesisState) GetParams() types.Params { if m != nil { - return m.Wasm + return m.Params } - return types.GenesisState{} + return types.Params{} +} + +func (m *GenesisState) GetCodes() []types.Code { + if m != nil { + return m.Codes + } + return nil +} + +func (m *GenesisState) GetContracts() []Contract { + if m != nil { + return m.Contracts + } + return nil +} + +func (m *GenesisState) GetSequences() []types.Sequence { + if m != nil { + return m.Sequences + } + return nil +} + +func (m *GenesisState) GetGenMsgs() []types.GenesisState_GenMsgs { + if m != nil { + return m.GenMsgs + } + return nil } func (m *GenesisState) GetPrivilegedContractAddresses() []string { @@ -86,8 +127,207 @@ func (m *GenesisState) GetPinnedCodeIDs() []uint64 { return nil } +// Contract struct encompasses ContractAddress, ContractInfo, and ContractState +type Contract struct { + ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` + ContractInfo types.ContractInfo `protobuf:"bytes,2,opt,name=contract_info,json=contractInfo,proto3" json:"contract_info"` + // ContractSate is one of default wasmd Model or custom state model + // + // Types that are valid to be assigned to ContractState: + // *Contract_KvModel + // *Contract_CustomModel + ContractState isContract_ContractState `protobuf_oneof:"contract_state"` +} + +func (m *Contract) Reset() { *m = Contract{} } +func (m *Contract) String() string { return proto.CompactTextString(m) } +func (*Contract) ProtoMessage() {} +func (*Contract) Descriptor() ([]byte, []int) { + return fileDescriptor_89c4cd47eb0533ed, []int{1} +} +func (m *Contract) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Contract) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Contract.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Contract) XXX_Merge(src proto.Message) { + xxx_messageInfo_Contract.Merge(m, src) +} +func (m *Contract) XXX_Size() int { + return m.Size() +} +func (m *Contract) XXX_DiscardUnknown() { + xxx_messageInfo_Contract.DiscardUnknown(m) +} + +var xxx_messageInfo_Contract proto.InternalMessageInfo + +type isContract_ContractState interface { + isContract_ContractState() + MarshalTo([]byte) (int, error) + Size() int +} + +type Contract_KvModel struct { + KvModel *KVModel `protobuf:"bytes,3,opt,name=kv_model,json=kvModel,proto3,oneof" json:"kv_model,omitempty"` +} +type Contract_CustomModel struct { + CustomModel *CustomModel `protobuf:"bytes,4,opt,name=custom_model,json=customModel,proto3,oneof" json:"custom_model,omitempty"` +} + +func (*Contract_KvModel) isContract_ContractState() {} +func (*Contract_CustomModel) isContract_ContractState() {} + +func (m *Contract) GetContractState() isContract_ContractState { + if m != nil { + return m.ContractState + } + return nil +} + +func (m *Contract) GetContractAddress() string { + if m != nil { + return m.ContractAddress + } + return "" +} + +func (m *Contract) GetContractInfo() types.ContractInfo { + if m != nil { + return m.ContractInfo + } + return types.ContractInfo{} +} + +func (m *Contract) GetKvModel() *KVModel { + if x, ok := m.GetContractState().(*Contract_KvModel); ok { + return x.KvModel + } + return nil +} + +func (m *Contract) GetCustomModel() *CustomModel { + if x, ok := m.GetContractState().(*Contract_CustomModel); ok { + return x.CustomModel + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Contract) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Contract_KvModel)(nil), + (*Contract_CustomModel)(nil), + } +} + +// KVModel is a wrapper around the wasmd default key value model. +type KVModel struct { + Models []types.Model `protobuf:"bytes,1,rep,name=models,proto3" json:"models"` +} + +func (m *KVModel) Reset() { *m = KVModel{} } +func (m *KVModel) String() string { return proto.CompactTextString(m) } +func (*KVModel) ProtoMessage() {} +func (*KVModel) Descriptor() ([]byte, []int) { + return fileDescriptor_89c4cd47eb0533ed, []int{2} +} +func (m *KVModel) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *KVModel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_KVModel.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *KVModel) XXX_Merge(src proto.Message) { + xxx_messageInfo_KVModel.Merge(m, src) +} +func (m *KVModel) XXX_Size() int { + return m.Size() +} +func (m *KVModel) XXX_DiscardUnknown() { + xxx_messageInfo_KVModel.DiscardUnknown(m) +} + +var xxx_messageInfo_KVModel proto.InternalMessageInfo + +func (m *KVModel) GetModels() []types.Model { + if m != nil { + return m.Models + } + return nil +} + +// CustomModel contains the raw json data for a contract to seed its state on +// import +type CustomModel struct { + // Msg json encoded message to be passed to the contract on import + Msg github_com_CosmWasm_wasmd_x_wasm_types.RawContractMessage `protobuf:"bytes,5,opt,name=msg,proto3,casttype=github.com/CosmWasm/wasmd/x/wasm/types.RawContractMessage" json:"msg,omitempty"` +} + +func (m *CustomModel) Reset() { *m = CustomModel{} } +func (m *CustomModel) String() string { return proto.CompactTextString(m) } +func (*CustomModel) ProtoMessage() {} +func (*CustomModel) Descriptor() ([]byte, []int) { + return fileDescriptor_89c4cd47eb0533ed, []int{3} +} +func (m *CustomModel) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CustomModel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CustomModel.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CustomModel) XXX_Merge(src proto.Message) { + xxx_messageInfo_CustomModel.Merge(m, src) +} +func (m *CustomModel) XXX_Size() int { + return m.Size() +} +func (m *CustomModel) XXX_DiscardUnknown() { + xxx_messageInfo_CustomModel.DiscardUnknown(m) +} + +var xxx_messageInfo_CustomModel proto.InternalMessageInfo + +func (m *CustomModel) GetMsg() github_com_CosmWasm_wasmd_x_wasm_types.RawContractMessage { + if m != nil { + return m.Msg + } + return nil +} + func init() { proto.RegisterType((*GenesisState)(nil), "confio.twasm.v1beta1.GenesisState") + proto.RegisterType((*Contract)(nil), "confio.twasm.v1beta1.Contract") + proto.RegisterType((*KVModel)(nil), "confio.twasm.v1beta1.KVModel") + proto.RegisterType((*CustomModel)(nil), "confio.twasm.v1beta1.CustomModel") } func init() { @@ -95,29 +335,49 @@ func init() { } var fileDescriptor_89c4cd47eb0533ed = []byte{ - // 340 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0xd1, 0x41, 0x4a, 0xf3, 0x40, - 0x14, 0x07, 0xf0, 0xa4, 0x2d, 0x1f, 0x7c, 0xd1, 0x22, 0x84, 0x22, 0xb5, 0xe2, 0xa4, 0x74, 0xa1, - 0x05, 0x65, 0x42, 0xf5, 0x02, 0x9a, 0x0a, 0xe2, 0x4e, 0x2a, 0xb8, 0x70, 0x13, 0x26, 0x99, 0x67, - 0x1c, 0x30, 0x79, 0x21, 0x33, 0x56, 0x7b, 0x0b, 0xef, 0xe1, 0x45, 0xba, 0xec, 0xd2, 0x55, 0x90, - 0x74, 0xd7, 0x53, 0x48, 0xa7, 0xa9, 0x8d, 0x2e, 0xdc, 0x85, 0xbc, 0xdf, 0xfc, 0xff, 0xc3, 0x3c, - 0xab, 0x17, 0x62, 0xf2, 0x20, 0xd0, 0x55, 0x2f, 0x4c, 0xc6, 0xee, 0x78, 0x10, 0x80, 0x62, 0x03, - 0x37, 0x82, 0x04, 0xa4, 0x90, 0x34, 0xcd, 0x50, 0xa1, 0xdd, 0x5a, 0x19, 0xaa, 0x0d, 0x2d, 0x4d, - 0xa7, 0x15, 0x61, 0x84, 0x1a, 0xb8, 0xcb, 0xaf, 0x95, 0xed, 0x90, 0x10, 0x65, 0x8c, 0xd2, 0x0d, - 0x98, 0x84, 0xef, 0xb8, 0x10, 0x45, 0x52, 0x9d, 0xeb, 0xae, 0xb2, 0xf0, 0x67, 0x57, 0xef, 0xbd, - 0x66, 0x6d, 0x5f, 0xad, 0xfe, 0xdc, 0x2a, 0xa6, 0xc0, 0x1e, 0x59, 0x8d, 0xa5, 0x6c, 0x9b, 0x5d, - 0xb3, 0xbf, 0x75, 0x4a, 0xe8, 0xfa, 0x3c, 0x2d, 0x2f, 0x43, 0xab, 0xda, 0x23, 0xd3, 0xdc, 0x31, - 0x16, 0xb9, 0xb3, 0xbb, 0x9c, 0xfa, 0x65, 0xf4, 0x09, 0xc6, 0x42, 0x41, 0x9c, 0xaa, 0xc9, 0x48, - 0x67, 0xd9, 0x68, 0x1d, 0xa4, 0x99, 0x18, 0x8b, 0x27, 0x88, 0x80, 0xfb, 0x21, 0x26, 0x2a, 0x63, - 0xa1, 0xf2, 0x19, 0xe7, 0x19, 0x48, 0x09, 0xb2, 0x5d, 0xeb, 0xd6, 0xfb, 0xff, 0xbd, 0xe3, 0x45, - 0xee, 0x1c, 0xfd, 0x09, 0x2b, 0xc9, 0xfb, 0x1b, 0x38, 0x2c, 0xdd, 0xc5, 0x9a, 0xd9, 0x77, 0xd6, - 0x4e, 0x2a, 0x92, 0x44, 0x67, 0x70, 0xf0, 0x05, 0x97, 0xed, 0x7a, 0xb7, 0xde, 0x6f, 0x78, 0xb4, - 0xc8, 0x9d, 0xe6, 0x8d, 0x1e, 0x0d, 0x91, 0xc3, 0xf5, 0xa5, 0x5c, 0xe4, 0xce, 0xde, 0x2f, 0x5b, - 0x69, 0x69, 0xa6, 0x1b, 0xcb, 0xa5, 0x77, 0x3e, 0x2d, 0x88, 0x39, 0x2b, 0x88, 0xf9, 0x59, 0x10, - 0xf3, 0x6d, 0x4e, 0x8c, 0xd9, 0x9c, 0x18, 0x1f, 0x73, 0x62, 0xdc, 0x1f, 0x46, 0x42, 0x3d, 0x3e, - 0x07, 0x34, 0xc4, 0xd8, 0x5d, 0xaf, 0x38, 0xca, 0x18, 0x07, 0xf7, 0xb5, 0xdc, 0xb5, 0x9a, 0xa4, - 0x20, 0x83, 0x7f, 0xfa, 0xd9, 0xcf, 0xbe, 0x02, 0x00, 0x00, 0xff, 0xff, 0x76, 0x2e, 0x7e, 0x8e, - 0x08, 0x02, 0x00, 0x00, + // 659 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0x5f, 0x4f, 0xd3, 0x50, + 0x14, 0xc0, 0x37, 0x36, 0x36, 0x76, 0x37, 0x84, 0x5c, 0x89, 0x94, 0x21, 0xdd, 0xdc, 0x03, 0xce, + 0x68, 0xda, 0x80, 0xd1, 0x44, 0x13, 0x13, 0x2c, 0xfe, 0x23, 0x86, 0x48, 0x46, 0xc4, 0x68, 0xa2, + 0x4b, 0x77, 0x7b, 0xb9, 0x36, 0xd0, 0xde, 0xba, 0x73, 0x19, 0xf0, 0x2d, 0x7c, 0xf2, 0x33, 0xf1, + 0xc8, 0xa3, 0x4f, 0x8b, 0x19, 0x0f, 0x26, 0x7c, 0x04, 0x9f, 0x4c, 0x6f, 0x6f, 0xbb, 0x42, 0xa7, + 0x6f, 0x6d, 0xcf, 0xef, 0xfc, 0xce, 0xbd, 0x67, 0x67, 0x07, 0xb5, 0x08, 0xf7, 0xf7, 0x5d, 0x6e, + 0x8a, 0x63, 0x1b, 0x3c, 0x73, 0xb0, 0xd6, 0xa3, 0xc2, 0x5e, 0x33, 0x19, 0xf5, 0x29, 0xb8, 0x60, + 0x04, 0x7d, 0x2e, 0x38, 0x5e, 0x88, 0x18, 0x43, 0x32, 0x86, 0x62, 0xea, 0x0b, 0x8c, 0x33, 0x2e, + 0x01, 0x33, 0x7c, 0x8a, 0xd8, 0xba, 0x4e, 0x38, 0x78, 0x1c, 0xcc, 0x9e, 0x0d, 0x34, 0xd1, 0x11, + 0xee, 0xfa, 0xe9, 0xb8, 0xac, 0xa5, 0x0a, 0x5e, 0xad, 0x55, 0xbf, 0x9d, 0x89, 0x8b, 0xd3, 0x80, + 0xc6, 0xd1, 0xa5, 0x6c, 0xf4, 0x24, 0x0a, 0xb5, 0x7e, 0x17, 0x51, 0xed, 0x75, 0xa4, 0xda, 0x15, + 0xb6, 0xa0, 0xf8, 0x31, 0x2a, 0x05, 0x76, 0xdf, 0xf6, 0x40, 0xcb, 0x37, 0xf3, 0xed, 0xea, 0xba, + 0x66, 0xc4, 0xc9, 0x86, 0xba, 0x87, 0xb1, 0x23, 0xe3, 0x56, 0xf1, 0x6c, 0xd8, 0xc8, 0x75, 0x14, + 0x8d, 0x5f, 0xa2, 0x69, 0xc2, 0x1d, 0x0a, 0xda, 0x54, 0xb3, 0xd0, 0xae, 0xae, 0xdf, 0xca, 0xa6, + 0x6d, 0x72, 0x87, 0x5a, 0x8b, 0x61, 0xd2, 0xe5, 0xb0, 0x31, 0x27, 0xe1, 0x07, 0xdc, 0x73, 0x05, + 0xf5, 0x02, 0x71, 0xda, 0x89, 0xb2, 0xf1, 0x47, 0x54, 0x21, 0xdc, 0x17, 0x7d, 0x9b, 0x08, 0xd0, + 0x0a, 0x52, 0xa5, 0x1b, 0x93, 0x1a, 0x69, 0x6c, 0x2a, 0xcc, 0x5a, 0x56, 0xca, 0x9b, 0x49, 0x62, + 0x4a, 0x3b, 0xb6, 0xe1, 0xf7, 0xa8, 0x02, 0xf4, 0xdb, 0x11, 0xf5, 0x09, 0x05, 0xad, 0x28, 0xd5, + 0xf5, 0xec, 0x29, 0x77, 0x15, 0x32, 0xd6, 0x26, 0x49, 0x69, 0x6d, 0xf2, 0x11, 0x7f, 0x46, 0x33, + 0x8c, 0xfa, 0x5d, 0x0f, 0x18, 0x68, 0xd3, 0xd2, 0xba, 0x9a, 0xb5, 0xa6, 0x5b, 0x1c, 0xbe, 0x6c, + 0x03, 0x03, 0xab, 0xae, 0x2a, 0xe0, 0x38, 0x3f, 0x55, 0xa0, 0xcc, 0x22, 0x08, 0x73, 0xb4, 0x12, + 0xf4, 0xdd, 0x81, 0x7b, 0x48, 0x19, 0x75, 0xba, 0xf1, 0x6d, 0xba, 0xb6, 0xe3, 0xf4, 0x29, 0x00, + 0x05, 0xad, 0xd4, 0x2c, 0xb4, 0x2b, 0xd6, 0xfd, 0xcb, 0x61, 0xe3, 0xee, 0x7f, 0xc1, 0x94, 0x7c, + 0x79, 0x0c, 0xc6, 0x5d, 0x7c, 0x1e, 0x63, 0x78, 0x0f, 0xcd, 0x05, 0xae, 0xef, 0x4b, 0x87, 0x43, + 0xbb, 0xae, 0x03, 0x5a, 0xb9, 0x59, 0x68, 0x17, 0x2d, 0x63, 0x34, 0x6c, 0xcc, 0xee, 0xc8, 0x50, + 0xf8, 0x53, 0x6e, 0xbd, 0x80, 0xcb, 0x61, 0x63, 0xe9, 0x1a, 0x9b, 0xaa, 0x32, 0x1b, 0x8c, 0x59, + 0x07, 0x5a, 0x3f, 0xa6, 0xd0, 0x4c, 0x5c, 0x0d, 0xdf, 0x43, 0xf3, 0xd7, 0x4f, 0x28, 0xe7, 0xad, + 0xd2, 0x99, 0x23, 0x57, 0x4f, 0x84, 0xb7, 0xd0, 0x6c, 0x82, 0xba, 0xfe, 0x3e, 0xd7, 0xa6, 0xe4, + 0x5c, 0xea, 0x93, 0x06, 0x2c, 0xc2, 0xb6, 0xfc, 0x7d, 0xae, 0xa6, 0xb3, 0x46, 0x52, 0xdf, 0xf0, + 0x53, 0x34, 0x73, 0x30, 0xe8, 0x7a, 0xdc, 0xa1, 0x87, 0x5a, 0x41, 0x5a, 0x56, 0x26, 0xcf, 0xd6, + 0xdb, 0xbd, 0xed, 0x10, 0x7a, 0x93, 0xeb, 0x94, 0x0f, 0x06, 0xf2, 0x11, 0xbf, 0x42, 0x35, 0x72, + 0x04, 0x82, 0x7b, 0x2a, 0xbf, 0x28, 0xf3, 0xef, 0xfc, 0x63, 0x36, 0x25, 0x19, 0x3b, 0xaa, 0x64, + 0xfc, 0x6a, 0xcd, 0xa3, 0x1b, 0xc9, 0x75, 0x20, 0x1c, 0x87, 0xd6, 0x06, 0x2a, 0xab, 0x7a, 0xf8, + 0x11, 0x2a, 0x49, 0x7b, 0xd8, 0x8c, 0x70, 0x92, 0x16, 0xb3, 0x97, 0x8c, 0x2c, 0xea, 0xbf, 0x17, + 0xc1, 0xad, 0x2f, 0xa8, 0x9a, 0xaa, 0x88, 0xdf, 0xa1, 0x82, 0x07, 0x4c, 0x9b, 0x6e, 0xe6, 0xdb, + 0x35, 0xeb, 0xd9, 0x9f, 0x61, 0xe3, 0x09, 0x73, 0xc5, 0xd7, 0xa3, 0x9e, 0x41, 0xb8, 0x67, 0x6e, + 0x72, 0xf0, 0x3e, 0xc4, 0xab, 0xc0, 0x31, 0x4f, 0xa2, 0x95, 0x10, 0x6d, 0x8b, 0x8e, 0x7d, 0x1c, + 0xf7, 0x70, 0x9b, 0x02, 0xd8, 0x8c, 0x76, 0x42, 0x93, 0xb5, 0x71, 0x36, 0xd2, 0xf3, 0xe7, 0x23, + 0x3d, 0xff, 0x6b, 0xa4, 0xe7, 0xbf, 0x5f, 0xe8, 0xb9, 0xf3, 0x0b, 0x3d, 0xf7, 0xf3, 0x42, 0xcf, + 0x7d, 0x5a, 0x4d, 0x99, 0xe3, 0x95, 0xc8, 0xfa, 0xb6, 0x43, 0xcd, 0x13, 0xb5, 0x1b, 0xa5, 0xb9, + 0x57, 0x92, 0xdb, 0xe6, 0xe1, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x74, 0x37, 0x09, 0x76, 0x38, + 0x05, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -156,7 +416,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], dAtA2[:j1]) i = encodeVarintGenesis(dAtA, i, uint64(j1)) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x3a } if len(m.PrivilegedContractAddresses) > 0 { for iNdEx := len(m.PrivilegedContractAddresses) - 1; iNdEx >= 0; iNdEx-- { @@ -164,11 +424,67 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.PrivilegedContractAddresses[iNdEx]) i = encodeVarintGenesis(dAtA, i, uint64(len(m.PrivilegedContractAddresses[iNdEx]))) i-- + dAtA[i] = 0x32 + } + } + if len(m.GenMsgs) > 0 { + for iNdEx := len(m.GenMsgs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.GenMsgs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if len(m.Sequences) > 0 { + for iNdEx := len(m.Sequences) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Sequences[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.Contracts) > 0 { + for iNdEx := len(m.Contracts) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Contracts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.Codes) > 0 { + for iNdEx := len(m.Codes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Codes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- dAtA[i] = 0x12 } } { - size, err := m.Wasm.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -180,6 +496,164 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Contract) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Contract) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Contract) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ContractState != nil { + { + size := m.ContractState.Size() + i -= size + if _, err := m.ContractState.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + { + size, err := m.ContractInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.ContractAddress) > 0 { + i -= len(m.ContractAddress) + copy(dAtA[i:], m.ContractAddress) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.ContractAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Contract_KvModel) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Contract_KvModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.KvModel != nil { + { + size, err := m.KvModel.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} +func (m *Contract_CustomModel) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Contract_CustomModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.CustomModel != nil { + { + size, err := m.CustomModel.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + return len(dAtA) - i, nil +} +func (m *KVModel) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *KVModel) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *KVModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Models) > 0 { + for iNdEx := len(m.Models) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Models[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *CustomModel) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CustomModel) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CustomModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Msg) > 0 { + i -= len(m.Msg) + copy(dAtA[i:], m.Msg) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Msg))) + i-- + dAtA[i] = 0x2a + } + return len(dAtA) - i, nil +} + func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { offset -= sovGenesis(v) base := offset @@ -197,24 +671,118 @@ func (m *GenesisState) Size() (n int) { } var l int _ = l - l = m.Wasm.Size() + l = m.Params.Size() n += 1 + l + sovGenesis(uint64(l)) - if len(m.PrivilegedContractAddresses) > 0 { - for _, s := range m.PrivilegedContractAddresses { - l = len(s) + if len(m.Codes) > 0 { + for _, e := range m.Codes { + l = e.Size() n += 1 + l + sovGenesis(uint64(l)) } } - if len(m.PinnedCodeIDs) > 0 { - l = 0 - for _, e := range m.PinnedCodeIDs { - l += sovGenesis(uint64(e)) + if len(m.Contracts) > 0 { + for _, e := range m.Contracts { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.Sequences) > 0 { + for _, e := range m.Sequences { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.GenMsgs) > 0 { + for _, e := range m.GenMsgs { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.PrivilegedContractAddresses) > 0 { + for _, s := range m.PrivilegedContractAddresses { + l = len(s) + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.PinnedCodeIDs) > 0 { + l = 0 + for _, e := range m.PinnedCodeIDs { + l += sovGenesis(uint64(e)) } n += 1 + sovGenesis(uint64(l)) + l } return n } +func (m *Contract) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddress) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = m.ContractInfo.Size() + n += 1 + l + sovGenesis(uint64(l)) + if m.ContractState != nil { + n += m.ContractState.Size() + } + return n +} + +func (m *Contract_KvModel) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.KvModel != nil { + l = m.KvModel.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} +func (m *Contract_CustomModel) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CustomModel != nil { + l = m.CustomModel.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} +func (m *KVModel) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Models) > 0 { + for _, e := range m.Models { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *CustomModel) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Msg) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + func sovGenesis(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -252,7 +820,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Wasm", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -279,11 +847,147 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Wasm.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Codes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Codes = append(m.Codes, types.Code{}) + if err := m.Codes[len(m.Codes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Contracts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Contracts = append(m.Contracts, Contract{}) + if err := m.Contracts[len(m.Contracts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sequences", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sequences = append(m.Sequences, types.Sequence{}) + if err := m.Sequences[len(m.Sequences)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GenMsgs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GenMsgs = append(m.GenMsgs, types.GenesisState_GenMsgs{}) + if err := m.GenMsgs[len(m.GenMsgs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field PrivilegedContractAddresses", wireType) } @@ -315,7 +1019,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } m.PrivilegedContractAddresses = append(m.PrivilegedContractAddresses, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 3: + case 7: if wireType == 0 { var v uint64 for shift := uint(0); ; shift += 7 { @@ -412,6 +1116,359 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } return nil } +func (m *Contract) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Contract: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Contract: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ContractInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KvModel", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &KVModel{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.ContractState = &Contract_KvModel{v} + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CustomModel", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &CustomModel{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.ContractState = &Contract_CustomModel{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *KVModel) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: KVModel: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: KVModel: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Models", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Models = append(m.Models, types.Model{}) + if err := m.Models[len(m.Models)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CustomModel) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CustomModel: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CustomModel: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msg = append(m.Msg[:0], dAtA[iNdEx:postIndex]...) + if m.Msg == nil { + m.Msg = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipGenesis(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/twasm/types/genesis_test.go b/x/twasm/types/genesis_test.go index 90a3979e..3d327138 100644 --- a/x/twasm/types/genesis_test.go +++ b/x/twasm/types/genesis_test.go @@ -19,7 +19,7 @@ func TestGenesisValidate(t *testing.T) { }, "wasm invalid": { state: GenesisStateFixture(t, func(state *GenesisState) { - state.Wasm.Codes[0].CodeID = 0 + state.Codes[0].CodeID = 0 }), expErr: true, }, @@ -44,7 +44,7 @@ func TestGenesisValidate(t *testing.T) { "invalid extension": { state: GenesisStateFixture(t, func(state *GenesisState) { var invalidType govtypes.Proposal // any protobuf type - err := state.Wasm.Contracts[0].ContractInfo.SetExtension(&invalidType) + err := state.Contracts[0].ContractInfo.SetExtension(&invalidType) require.NoError(t, err) }), expErr: true, @@ -52,21 +52,21 @@ func TestGenesisValidate(t *testing.T) { "unique pinned codeIDs": { state: GenesisStateFixture(t, func(state *GenesisState) { state.PinnedCodeIDs = []uint64{1, 2, 3} - state.Wasm.Codes = []types.Code{newCode(1), newCode(2), newCode(3), newCode(4)} + state.Codes = []types.Code{newCode(1), newCode(2), newCode(3), newCode(4)} }), expErr: false, }, "duplicate pinned codeIDs": { state: GenesisStateFixture(t, func(state *GenesisState) { state.PinnedCodeIDs = []uint64{1, 2, 3, 3} - state.Wasm.Codes = []types.Code{newCode(1), newCode(2), newCode(3), newCode(4)} + state.Codes = []types.Code{newCode(1), newCode(2), newCode(3), newCode(4)} }), expErr: true, }, "pinned codeIDs do not exist in genesis codeIDs": { state: GenesisStateFixture(t, func(state *GenesisState) { state.PinnedCodeIDs = []uint64{1, 2, 3} - state.Wasm.Codes = []types.Code{newCode(1), newCode(2), newCode(4), newCode(5)} + state.Codes = []types.Code{newCode(1), newCode(2), newCode(4), newCode(5)} }), expErr: true, }, @@ -74,7 +74,7 @@ func TestGenesisValidate(t *testing.T) { state: GenesisStateFixture(t, func(state *GenesisState) { addresses := []string{RandomBech32Address(t), RandomBech32Address(t), RandomBech32Address(t)} state.PrivilegedContractAddresses = addresses - state.Wasm.Contracts = []types.Contract{newContract(addresses[0]), newContract(addresses[1]), newContract(addresses[2])} + state.Contracts = []Contract{newContract(t, addresses[0]), newContract(t, addresses[1]), newContract(t, addresses[2])} }), expErr: false, }, @@ -82,7 +82,7 @@ func TestGenesisValidate(t *testing.T) { state: GenesisStateFixture(t, func(state *GenesisState) { addresses := []string{RandomBech32Address(t), RandomBech32Address(t), RandomBech32Address(t)} state.PrivilegedContractAddresses = addresses - state.Wasm.Contracts = []types.Contract{newContract(addresses[0]), newContract(addresses[1]), newContract(RandomBech32Address(t))} + state.Contracts = []Contract{newContract(t, addresses[0]), newContract(t, addresses[1]), newContract(t, RandomBech32Address(t))} }), expErr: true, }, @@ -108,8 +108,8 @@ func newCode(codeID uint64) types.Code { } // newContract returns Contract with custom address -func newContract(addr string) types.Contract { - contract := types.ContractFixture(func(c *types.Contract) { +func newContract(t *testing.T, addr string) Contract { + contract := ContractFixture(t, func(c *Contract) { c.ContractAddress = addr }) return contract diff --git a/x/twasm/types/privilege.go b/x/twasm/types/privilege.go index a7ccf4dd..ee62d70c 100644 --- a/x/twasm/types/privilege.go +++ b/x/twasm/types/privilege.go @@ -39,7 +39,9 @@ var ( // PrivilegeDelegator is a permission to let accounts send tokens via delegation to this contract. Can be used by vesting accounts PrivilegeDelegator = registerCallbackType(0x7, "delegator", false) - // PrivilegeStateExporterImporter is a permission to allow contracts to export / import their state + // PrivilegeStateExporterImporter is a permission to let contracts manage their state export on a dump and genesis import (in non seed mode) + // The contract receives a sudo message of type export where the result is stored in genesis. For the import path the json object containing state + // is passed to the contract via sudo import method. PrivilegeStateExporterImporter = registerCallbackType(0x8, "state_exporter_importer", false) ) diff --git a/x/twasm/types/test_fixtures.go b/x/twasm/types/test_fixtures.go index bba5913c..63f90f4e 100644 --- a/x/twasm/types/test_fixtures.go +++ b/x/twasm/types/test_fixtures.go @@ -1,8 +1,11 @@ package types import ( + "bytes" "testing" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" @@ -35,25 +38,56 @@ func DemoteProposalFixture(mutators ...func(proposal *DemotePrivilegedContractPr return p } +// DeterministicGenesisStateFixture is the same as GenesisStateFixture but with deterministic addresses and codes +func DeterministicGenesisStateFixture(t *testing.T, mutators ...func(*GenesisState)) GenesisState { + genesisState := GenesisStateFixture(t) + for i := range genesisState.Contracts { + genesisState.Contracts[i].ContractAddress = wasmkeeper.BuildContractAddress(uint64(i), uint64(i)).String() + } + for i := range genesisState.Codes { + wasmCode := bytes.Repeat([]byte{byte(i)}, 20) + genesisState.Codes[i].CodeInfo = wasmtypes.CodeInfoFixture(wasmtypes.WithSHA256CodeHash(wasmCode)) + genesisState.Codes[i].CodeBytes = wasmCode + } + for _, m := range mutators { + m(&genesisState) + } + return genesisState +} + +// GenesisStateFixture test data fixture func GenesisStateFixture(t *testing.T, mutators ...func(*GenesisState)) GenesisState { t.Helper() anyContractAddr := RandomBech32Address(t) + wasmState := wasmtypes.GenesisFixture(func(state *wasmtypes.GenesisState) { + state.Codes[1] = wasmtypes.CodeFixture(func(code *wasmtypes.Code) { + code.CodeID = 2 + code.Pinned = true + }) + state.Contracts[1] = wasmtypes.ContractFixture(func(contract *wasmtypes.Contract) { + contract.ContractAddress = anyContractAddr + contract.ContractInfo.CodeID = 2 + }) + state.Sequences = []wasmtypes.Sequence{ + {IDKey: wasmtypes.KeyLastCodeID, Value: 10}, + {IDKey: wasmtypes.KeyLastInstanceID, Value: 11}, + } + state.GenMsgs = nil + }) + contracts := make([]Contract, len(wasmState.Contracts)) + for i, v := range wasmState.Contracts { + contracts[i] = Contract{ + ContractAddress: v.ContractAddress, + ContractInfo: v.ContractInfo, + ContractState: &Contract_KvModel{&KVModel{v.ContractState}}, + } + } genesisState := GenesisState{ - Wasm: wasmtypes.GenesisFixture(func(state *wasmtypes.GenesisState) { - state.Codes[1] = wasmtypes.CodeFixture(func(code *wasmtypes.Code) { - code.CodeID = 2 - code.Pinned = true - }) - state.Contracts[1] = wasmtypes.ContractFixture(func(contract *wasmtypes.Contract) { - contract.ContractAddress = anyContractAddr - contract.ContractInfo.CodeID = 2 - }) - state.Sequences = []wasmtypes.Sequence{ - {IDKey: wasmtypes.KeyLastCodeID, Value: 10}, - {IDKey: wasmtypes.KeyLastInstanceID, Value: 11}, - } - state.GenMsgs = nil - }), + Params: wasmState.Params, + Codes: wasmState.Codes, + Contracts: contracts, + Sequences: wasmState.Sequences, + GenMsgs: wasmState.GenMsgs, PrivilegedContractAddresses: []string{anyContractAddr}, } for _, m := range mutators { @@ -62,6 +96,21 @@ func GenesisStateFixture(t *testing.T, mutators ...func(*GenesisState)) GenesisS return genesisState } +// ContractFixture test data factory +func ContractFixture(t *testing.T, mutators ...func(contract *Contract)) Contract { + t.Helper() + wasmContract := wasmtypes.ContractFixture() + c := Contract{ + ContractAddress: wasmContract.ContractAddress, + ContractInfo: wasmContract.ContractInfo, + ContractState: &Contract_KvModel{&KVModel{wasmContract.ContractState}}, + } + for _, m := range mutators { + m(&c) + } + return c +} + func TgradeContractDetailsFixture(t *testing.T, mutators ...func(d *TgradeContractDetails)) TgradeContractDetails { t.Helper() d := TgradeContractDetails{