From 8ef856ec9c3a460f7655e0abd4e0e624f5ef9734 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Thu, 4 Jul 2024 13:00:15 +0200 Subject: [PATCH 01/11] [wip] refactor: remove staking from testutil --- testutil/network/network.go | 7 +- testutil/sims/app_helpers.go | 35 +++++----- testutil/sims/staking.go | 123 +++++++++++++++++++++++++++++++++ testutil/sims/state_helpers.go | 15 ++-- 4 files changed, 150 insertions(+), 30 deletions(-) create mode 100644 testutil/sims/staking.go diff --git a/testutil/network/network.go b/testutil/network/network.go index 0d0e942a9fb2..4ffa0ca511d1 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -31,7 +31,6 @@ import ( pruningtypes "cosmossdk.io/store/pruning/types" authtypes "cosmossdk.io/x/auth/types" banktypes "cosmossdk.io/x/bank/types" - stakingtypes "cosmossdk.io/x/staking/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" @@ -49,6 +48,7 @@ import ( srvconfig "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/testutil" + "github.com/cosmos/cosmos-sdk/testutil/sims" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" @@ -483,12 +483,11 @@ func New(l Logger, baseDir string, cfg Config) (NetworkI, error) { return nil, err } - createValMsg, err := stakingtypes.NewMsgCreateValidator( + createValMsg, err := sims.FakeStakingMsgCreateValidator( sdk.ValAddress(addr).String(), valPubKeys[i], sdk.NewCoin(cfg.BondDenom, cfg.BondedTokens), - stakingtypes.NewDescription(nodeDirName, "", "", "", ""), - stakingtypes.NewCommissionRates(commission, sdkmath.LegacyOneDec(), sdkmath.LegacyOneDec()), + commission, sdkmath.LegacyOneDec(), sdkmath.LegacyOneDec(), sdkmath.OneInt(), ) if err != nil { diff --git a/testutil/sims/app_helpers.go b/testutil/sims/app_helpers.go index 720713ca56ac..edc048f01112 100644 --- a/testutil/sims/app_helpers.go +++ b/testutil/sims/app_helpers.go @@ -16,7 +16,6 @@ import ( sdkmath "cosmossdk.io/math" authtypes "cosmossdk.io/x/auth/types" banktypes "cosmossdk.io/x/bank/types" - stakingtypes "cosmossdk.io/x/staking/types" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" @@ -25,6 +24,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/runtime" servertypes "github.com/cosmos/cosmos-sdk/server/types" + "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/mock" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -223,8 +223,7 @@ func GenesisStateWithValSet( authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) genesisState[authtypes.ModuleName] = codec.MustMarshalJSON(authGenesis) - validators := make([]stakingtypes.Validator, 0, len(valSet.Validators)) - delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators)) + validators := make([]StakingValidator, 0, len(valSet.Validators)) bondAmt := sdk.DefaultPowerReduction @@ -239,27 +238,32 @@ func GenesisStateWithValSet( return nil, fmt.Errorf("failed to create new any: %w", err) } - validator := stakingtypes.Validator{ + validator := StakingValidator{ OperatorAddress: sdk.ValAddress(val.Address).String(), ConsensusPubkey: pkAny, Jailed: false, - Status: stakingtypes.Bonded, + Status: 3, Tokens: bondAmt, DelegatorShares: sdkmath.LegacyOneDec(), - Description: stakingtypes.Description{}, - UnbondingHeight: int64(0), - UnbondingTime: time.Unix(0, 0).UTC(), - Commission: stakingtypes.NewCommission(sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec()), MinSelfDelegation: sdkmath.ZeroInt(), } validators = append(validators, validator) - delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress().String(), sdk.ValAddress(val.Address).String(), sdkmath.LegacyOneDec())) } // set validators and delegations - stakingGenesis := stakingtypes.NewGenesisState(stakingtypes.DefaultParams(), validators, delegations) - genesisState[stakingtypes.ModuleName] = codec.MustMarshalJSON(stakingGenesis) + stakingGenesis := StakingGenesisState{ + Params: StakingParams{ + UnbondingTime: time.Hour * 24 * 7 * 3, + MaxValidators: 100, + MaxEntries: 7, + HistoricalEntries: 10000, + BondDenom: sdk.DefaultBondDenom, + MinCommissionRate: sdkmath.LegacyZeroDec(), + }, + Validators: validators, + } + genesisState[testutil.StakingModuleName], _ = json.Marshal(stakingGenesis) totalSupply := sdk.NewCoins() for _, b := range balances { @@ -267,14 +271,9 @@ func GenesisStateWithValSet( totalSupply = totalSupply.Add(b.Coins...) } - for range delegations { - // add delegated tokens to total supply - totalSupply = totalSupply.Add(sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)) - } - // add bonded amount to bonded pool module account balances = append(balances, banktypes.Balance{ - Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), + Address: authtypes.NewModuleAddress(StakingBondedPoolName).String(), Coins: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)}, }) diff --git a/testutil/sims/staking.go b/testutil/sims/staking.go new file mode 100644 index 000000000000..4ee2c086c56e --- /dev/null +++ b/testutil/sims/staking.go @@ -0,0 +1,123 @@ +package sims + +import ( + "time" + + "github.com/cosmos/gogoproto/proto" + any "github.com/cosmos/gogoproto/types/any" + + "cosmossdk.io/math" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + StakingNotBondedPoolName = "not_bonded_tokens_pool" + StakingBondedPoolName = "bonded_tokens_pool" +) + +type StakingGenesisState struct { + // params defines all the parameters of related to deposit. + Params StakingParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // last_total_power tracks the total amounts of bonded tokens recorded during + // the previous end block. + LastTotalPower math.Int `protobuf:"bytes,2,opt,name=last_total_power,json=lastTotalPower,proto3,customtype=cosmossdk.io/math.Int" json:"last_total_power"` + // validators defines the validator set at genesis. + Validators []StakingValidator `protobuf:"bytes,4,rep,name=validators,proto3" json:"validators"` + // delegations defines the delegations active at genesis. + Delegations []StakingDelegation `protobuf:"bytes,5,rep,name=delegations,proto3" json:"delegations"` +} + +type StakingParams struct { + // unbonding_time is the time duration of unbonding. + UnbondingTime time.Duration `protobuf:"bytes,1,opt,name=unbonding_time,json=unbondingTime,proto3,stdduration" json:"unbonding_time"` + // max_validators is the maximum number of validators. + MaxValidators uint32 `protobuf:"varint,2,opt,name=max_validators,json=maxValidators,proto3" json:"max_validators,omitempty"` + // max_entries is the max entries for either unbonding delegation or redelegation (per pair/trio). + MaxEntries uint32 `protobuf:"varint,3,opt,name=max_entries,json=maxEntries,proto3" json:"max_entries,omitempty"` + // historical_entries is the number of historical entries to persist. + HistoricalEntries uint32 `protobuf:"varint,4,opt,name=historical_entries,json=historicalEntries,proto3" json:"historical_entries,omitempty"` + // bond_denom defines the bondable coin denomination. + BondDenom string `protobuf:"bytes,5,opt,name=bond_denom,json=bondDenom,proto3" json:"bond_denom,omitempty"` + // min_commission_rate is the chain-wide minimum commission rate that a validator can charge their delegators + MinCommissionRate math.LegacyDec `protobuf:"bytes,6,opt,name=min_commission_rate,json=minCommissionRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"min_commission_rate" yaml:"min_commission_rate"` +} + +type StakingValidator struct { + // operator_address defines the address of the validator's operator; bech encoded in JSON. + OperatorAddress string `protobuf:"bytes,1,opt,name=operator_address,json=operatorAddress,proto3" json:"operator_address,omitempty"` + // consensus_pubkey is the consensus public key of the validator, as a Protobuf Any. + ConsensusPubkey *any.Any `protobuf:"bytes,2,opt,name=consensus_pubkey,json=consensusPubkey,proto3" json:"consensus_pubkey,omitempty"` + // jailed defined whether the validator has been jailed from bonded status or not. + Jailed bool `protobuf:"varint,3,opt,name=jailed,proto3" json:"jailed,omitempty"` + // status is the validator status (bonded/unbonding/unbonded). + Status int32 `protobuf:"varint,4,opt,name=status,proto3" json:"status,omitempty"` + // tokens define the delegated tokens (incl. self-delegation). + Tokens math.Int `protobuf:"bytes,5,opt,name=tokens,proto3,customtype=cosmossdk.io/math.Int" json:"tokens"` + // delegator_shares defines total shares issued to a validator's delegators. + DelegatorShares math.LegacyDec `protobuf:"bytes,6,opt,name=delegator_shares,json=delegatorShares,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"delegator_shares"` + // min_self_delegation is the validator's self declared minimum self delegation. + MinSelfDelegation math.Int `protobuf:"bytes,11,opt,name=min_self_delegation,json=minSelfDelegation,proto3,customtype=cosmossdk.io/math.Int" json:"min_self_delegation"` +} + +type StakingDelegation struct { + // delegator_address is the encoded address of the delegator. + DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` + // validator_address is the encoded address of the validator. + ValidatorAddress string `protobuf:"bytes,2,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` + // shares define the delegation shares received. + Shares math.LegacyDec `protobuf:"bytes,3,opt,name=shares,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"shares"` +} + +func FakeStakingMsgCreateValidator( + valAddr string, pubKey cryptotypes.PubKey, selfDelegation sdk.Coin, + rate, maxRate, maxChangeRate math.LegacyDec, minSelfDelegation math.Int, +) (proto.Message, error) { + var pkAny *codectypes.Any + if pubKey != nil { + var err error + if pkAny, err = codectypes.NewAnyWithValue(pubKey); err != nil { + return nil, err + } + } + + v := &StakingMsgCreateValidator{ + Commission: StakingValidatorCommission{ + Rate: rate, + MaxRate: maxRate, + MaxChangeRate: maxChangeRate, + }, + MinSelfDelegation: minSelfDelegation, + DelegatorAddress: "", + ValidatorAddress: valAddr, + Pubkey: pkAny, + Value: selfDelegation, + } + + _ = v + + return nil, nil +} + +type StakingMsgCreateValidator struct { + Commission StakingValidatorCommission `protobuf:"bytes,2,opt,name=commission,proto3" json:"commission"` + MinSelfDelegation math.Int `protobuf:"bytes,3,opt,name=min_self_delegation,json=minSelfDelegation,proto3,customtype=cosmossdk.io/math.Int" json:"min_self_delegation"` + // Deprecated: Use of Delegator Address in MsgCreateValidator is deprecated. + // The validator address bytes and delegator address bytes refer to the same account while creating validator (defer + // only in bech32 notation). + DelegatorAddress string `protobuf:"bytes,4,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` // Deprecated: Do not use. + ValidatorAddress string `protobuf:"bytes,5,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` + Pubkey *any.Any `protobuf:"bytes,6,opt,name=pubkey,proto3" json:"pubkey,omitempty"` + Value sdk.Coin `protobuf:"bytes,7,opt,name=value,proto3" json:"value"` +} + +type StakingValidatorCommission struct { + // rate is the commission rate charged to delegators, as a fraction. + Rate math.LegacyDec `protobuf:"bytes,1,opt,name=rate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"rate"` + // max_rate defines the maximum commission rate which validator can ever charge, as a fraction. + MaxRate math.LegacyDec `protobuf:"bytes,2,opt,name=max_rate,json=maxRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"max_rate"` + // max_change_rate defines the maximum daily increase of the validator commission, as a fraction. + MaxChangeRate math.LegacyDec `protobuf:"bytes,3,opt,name=max_change_rate,json=maxChangeRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"max_change_rate"` +} diff --git a/testutil/sims/state_helpers.go b/testutil/sims/state_helpers.go index 8a3ce8a488a3..04b4b254d10f 100644 --- a/testutil/sims/state_helpers.go +++ b/testutil/sims/state_helpers.go @@ -16,7 +16,6 @@ import ( "cosmossdk.io/math" authtypes "cosmossdk.io/x/auth/types" banktypes "cosmossdk.io/x/bank/types" - stakingtypes "cosmossdk.io/x/staking/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" @@ -124,22 +123,22 @@ func appStateFnWithExtendedCbs( panic(err) } - stakingStateBz, ok := rawState[stakingtypes.ModuleName] + stakingStateBz, ok := rawState[testutil.StakingModuleName] if !ok { panic("staking genesis state is missing") } - stakingState := new(stakingtypes.GenesisState) - if err = cdc.UnmarshalJSON(stakingStateBz, stakingState); err != nil { + stakingState := new(StakingGenesisState) + if err = json.Unmarshal(stakingStateBz, stakingState); err != nil { panic(err) } // compute not bonded balance notBondedTokens := math.ZeroInt() for _, val := range stakingState.Validators { - if val.Status != stakingtypes.Unbonded { + if val.Status != 1 { // unbonded continue } - notBondedTokens = notBondedTokens.Add(val.GetTokens()) + notBondedTokens = notBondedTokens.Add(val.Tokens) } notBondedCoins := sdk.NewCoin(stakingState.Params.BondDenom, notBondedTokens) // edit bank state to make it have the not bonded pool tokens @@ -152,7 +151,7 @@ func appStateFnWithExtendedCbs( panic(err) } - stakingAddr := authtypes.NewModuleAddress(stakingtypes.NotBondedPoolName).String() + stakingAddr := authtypes.NewModuleAddress(StakingNotBondedPoolName).String() var found bool for _, balance := range bankState.Balances { if balance.Address == stakingAddr { @@ -169,7 +168,7 @@ func appStateFnWithExtendedCbs( // change appState back for name, state := range map[string]proto.Message{ - stakingtypes.ModuleName: stakingState, + // stakingtypes.ModuleName: stakingState, TODO(@julienrbrt) uncomment (!) testutil.BankModuleName: bankState, } { if moduleStateCb != nil { From b22fb7ae68ff1a70d318c291b391ecb960e3e09d Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Mon, 8 Jul 2024 10:47:09 +0200 Subject: [PATCH 02/11] re-add delegations --- testutil/sims/app_helpers.go | 16 +++++++++++++++- testutil/sims/state_helpers.go | 16 ++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/testutil/sims/app_helpers.go b/testutil/sims/app_helpers.go index edc048f01112..542ef1a28273 100644 --- a/testutil/sims/app_helpers.go +++ b/testutil/sims/app_helpers.go @@ -224,6 +224,7 @@ func GenesisStateWithValSet( genesisState[authtypes.ModuleName] = codec.MustMarshalJSON(authGenesis) validators := make([]StakingValidator, 0, len(valSet.Validators)) + delegations := make([]StakingDelegation, 0, len(valSet.Validators)) bondAmt := sdk.DefaultPowerReduction @@ -247,8 +248,15 @@ func GenesisStateWithValSet( DelegatorShares: sdkmath.LegacyOneDec(), MinSelfDelegation: sdkmath.ZeroInt(), } + validators = append(validators, validator) + deletation := StakingDelegation{ + DelegatorAddress: genAccs[0].GetAddress().String(), + ValidatorAddress: sdk.ValAddress(val.Address).String(), + Shares: sdkmath.LegacyOneDec(), + } + delegations = append(delegations, deletation) } // set validators and delegations @@ -261,7 +269,8 @@ func GenesisStateWithValSet( BondDenom: sdk.DefaultBondDenom, MinCommissionRate: sdkmath.LegacyZeroDec(), }, - Validators: validators, + Validators: validators, + Delegations: delegations, } genesisState[testutil.StakingModuleName], _ = json.Marshal(stakingGenesis) @@ -271,6 +280,11 @@ func GenesisStateWithValSet( totalSupply = totalSupply.Add(b.Coins...) } + for range delegations { + // add delegated tokens to total supply + totalSupply = totalSupply.Add(sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)) + } + // add bonded amount to bonded pool module account balances = append(balances, banktypes.Balance{ Address: authtypes.NewModuleAddress(StakingBondedPoolName).String(), diff --git a/testutil/sims/state_helpers.go b/testutil/sims/state_helpers.go index 04b4b254d10f..c9d3840e33ce 100644 --- a/testutil/sims/state_helpers.go +++ b/testutil/sims/state_helpers.go @@ -167,14 +167,22 @@ func appStateFnWithExtendedCbs( } // change appState back - for name, state := range map[string]proto.Message{ - // stakingtypes.ModuleName: stakingState, TODO(@julienrbrt) uncomment (!) - testutil.BankModuleName: bankState, + for name, state := range map[string]interface{}{ + testutil.StakingModuleName: stakingState, + testutil.BankModuleName: bankState, } { if moduleStateCb != nil { moduleStateCb(name, state) } - rawState[name] = cdc.MustMarshalJSON(state) + + if ps, ok := state.(proto.Message); ok { + rawState[name] = cdc.MustMarshalJSON(ps) + } else { + rawState[name], err = json.Marshal(state) + if err != nil { + panic(err) + } + } } // extend state from callback function From 45cdbb8dabbbf2652ec4359305ad65bceaeaa621 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 17 Jul 2024 14:32:15 +0200 Subject: [PATCH 03/11] manual --- testutil/sims/staking.go | 96 +++++++++++++++++++++++----------- testutil/sims/state_helpers.go | 11 +++- 2 files changed, 75 insertions(+), 32 deletions(-) diff --git a/testutil/sims/staking.go b/testutil/sims/staking.go index 4ee2c086c56e..713f2d53faa0 100644 --- a/testutil/sims/staking.go +++ b/testutil/sims/staking.go @@ -3,13 +3,11 @@ package sims import ( "time" - "github.com/cosmos/gogoproto/proto" - any "github.com/cosmos/gogoproto/types/any" + "google.golang.org/protobuf/types/known/anypb" + "google.golang.org/protobuf/types/known/structpb" "cosmossdk.io/math" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -30,6 +28,44 @@ type StakingGenesisState struct { Delegations []StakingDelegation `protobuf:"bytes,5,rep,name=delegations,proto3" json:"delegations"` } +func (s *StakingGenesisState) ToProto() (*anypb.Any, error) { + // Create a map to hold the protobuf fields + fields := map[string]interface{}{ + "params": s.Params, + "last_total_power": s.LastTotalPower, + "validators": s.Validators, + "delegations": s.Delegations, + } + + // Convert the map to a protobuf Struct + pbStruct, err := structpb.NewStruct(fields) + if err != nil { + return nil, err + } + + // Marshal the Struct into an Any message + anyMsg, err := anypb.New(pbStruct) + if err != nil { + return nil, err + } + + return anyMsg, nil +} + +func ProtoToStakingGenesisState(protoMsg *anypb.Any) (*StakingGenesisState, error) { + var s structpb.Struct + if err := protoMsg.UnmarshalTo(&s); err != nil { + return nil, err + } + + genesisStake := &StakingGenesisState{} + // myStruct.Params = s.Fields["params"].GetStringValue() + // myStruct.Field2 = int32(s.Fields["field2"].GetNumberValue()) + // myStruct.Field3 = []byte(s.Fields["field3"].GetStringValue()) + + return genesisStake, nil +} + type StakingParams struct { // unbonding_time is the time duration of unbonding. UnbondingTime time.Duration `protobuf:"bytes,1,opt,name=unbonding_time,json=unbondingTime,proto3,stdduration" json:"unbonding_time"` @@ -71,35 +107,35 @@ type StakingDelegation struct { Shares math.LegacyDec `protobuf:"bytes,3,opt,name=shares,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"shares"` } -func FakeStakingMsgCreateValidator( - valAddr string, pubKey cryptotypes.PubKey, selfDelegation sdk.Coin, - rate, maxRate, maxChangeRate math.LegacyDec, minSelfDelegation math.Int, -) (proto.Message, error) { - var pkAny *codectypes.Any - if pubKey != nil { - var err error - if pkAny, err = codectypes.NewAnyWithValue(pubKey); err != nil { - return nil, err - } - } +// func FakeStakingMsgCreateValidator( +// valAddr string, pubKey cryptotypes.PubKey, selfDelegation sdk.Coin, +// rate, maxRate, maxChangeRate math.LegacyDec, minSelfDelegation math.Int, +// ) (proto.Message, error) { +// var pkAny *codectypes.Any +// if pubKey != nil { +// var err error +// if pkAny, err = codectypes.NewAnyWithValue(pubKey); err != nil { +// return nil, err +// } +// } - v := &StakingMsgCreateValidator{ - Commission: StakingValidatorCommission{ - Rate: rate, - MaxRate: maxRate, - MaxChangeRate: maxChangeRate, - }, - MinSelfDelegation: minSelfDelegation, - DelegatorAddress: "", - ValidatorAddress: valAddr, - Pubkey: pkAny, - Value: selfDelegation, - } +// v := &StakingMsgCreateValidator{ +// Commission: StakingValidatorCommission{ +// Rate: rate, +// MaxRate: maxRate, +// MaxChangeRate: maxChangeRate, +// }, +// MinSelfDelegation: minSelfDelegation, +// DelegatorAddress: "", +// ValidatorAddress: valAddr, +// Pubkey: pkAny, +// Value: selfDelegation, +// } - _ = v +// _ = v - return nil, nil -} +// return nil, nil +// } type StakingMsgCreateValidator struct { Commission StakingValidatorCommission `protobuf:"bytes,2,opt,name=commission,proto3" json:"commission"` diff --git a/testutil/sims/state_helpers.go b/testutil/sims/state_helpers.go index c9d3840e33ce..f8862527aab7 100644 --- a/testutil/sims/state_helpers.go +++ b/testutil/sims/state_helpers.go @@ -11,6 +11,7 @@ import ( "time" "github.com/cosmos/gogoproto/proto" + "google.golang.org/protobuf/types/known/anypb" "cosmossdk.io/core/address" "cosmossdk.io/math" @@ -128,10 +129,16 @@ func appStateFnWithExtendedCbs( panic("staking genesis state is missing") } - stakingState := new(StakingGenesisState) - if err = json.Unmarshal(stakingStateBz, stakingState); err != nil { + rawStakingState := new(anypb.Any) + if err = json.Unmarshal(stakingStateBz, rawStakingState); err != nil { panic(err) } + + stakingState, err := ProtoToStakingGenesisState(rawStakingState) + if err != nil { + panic(err) + } + // compute not bonded balance notBondedTokens := math.ZeroInt() for _, val := range stakingState.Validators { From c43221553cf17aef7242b110099c76d26a0d0785 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Thu, 18 Jul 2024 17:26:52 +0200 Subject: [PATCH 04/11] updates --- testutil/network/network.go | 28 +++-- testutil/sims/staking.go | 182 ++++++++++++++++++++++++++------- testutil/sims/state_helpers.go | 2 +- 3 files changed, 165 insertions(+), 47 deletions(-) diff --git a/testutil/network/network.go b/testutil/network/network.go index 4ffa0ca511d1..dd739919c4b9 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -483,13 +483,27 @@ func New(l Logger, baseDir string, cfg Config) (NetworkI, error) { return nil, err } - createValMsg, err := sims.FakeStakingMsgCreateValidator( - sdk.ValAddress(addr).String(), - valPubKeys[i], - sdk.NewCoin(cfg.BondDenom, cfg.BondedTokens), - commission, sdkmath.LegacyOneDec(), sdkmath.LegacyOneDec(), - sdkmath.OneInt(), - ) + var pkAny *codectypes.Any + if pubkey := valPubKeys[i]; pubkey != nil { + var err error + if pkAny, err = codectypes.NewAnyWithValue(pubKey); err != nil { + return nil, err + } + } + + createValMsgStruct := &sims.StakingMsgCreateValidator{ + Commission: sims.StakingValidatorCommission{ + Rate: commission, + MaxRate: commission, + MaxChangeRate: sdkmath.LegacyOneDec(), + }, + MinSelfDelegation: sdkmath.OneInt(), + ValidatorAddress: sdk.ValAddress(addr).String(), + Pubkey: pkAny, + Value: sdk.NewCoin(cfg.BondDenom, cfg.BondedTokens), + } + + createValMsg, err := createValMsgStruct.ToProto() if err != nil { return nil, err } diff --git a/testutil/sims/staking.go b/testutil/sims/staking.go index 713f2d53faa0..6da541b6192e 100644 --- a/testutil/sims/staking.go +++ b/testutil/sims/staking.go @@ -3,6 +3,7 @@ package sims import ( "time" + gogoany "github.com/cosmos/gogoproto/types/any" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/structpb" @@ -29,9 +30,14 @@ type StakingGenesisState struct { } func (s *StakingGenesisState) ToProto() (*anypb.Any, error) { + params, err := s.Params.ToProto() + if err != nil { + return nil, err + } + // Create a map to hold the protobuf fields fields := map[string]interface{}{ - "params": s.Params, + "params": params, "last_total_power": s.LastTotalPower, "validators": s.Validators, "delegations": s.Delegations, @@ -59,9 +65,10 @@ func ProtoToStakingGenesisState(protoMsg *anypb.Any) (*StakingGenesisState, erro } genesisStake := &StakingGenesisState{} - // myStruct.Params = s.Fields["params"].GetStringValue() - // myStruct.Field2 = int32(s.Fields["field2"].GetNumberValue()) - // myStruct.Field3 = []byte(s.Fields["field3"].GetStringValue()) + // genesisStake.Params = s.Fields["params"]. + // genesisStake.LastTotalPower = s.Fields["last_total_power"]. + // genesisStake.Validators = s.Fields["validators"]. + // genesisStake.Delegations = s.Fields["delegations"]. return genesisStake, nil } @@ -81,11 +88,37 @@ type StakingParams struct { MinCommissionRate math.LegacyDec `protobuf:"bytes,6,opt,name=min_commission_rate,json=minCommissionRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"min_commission_rate" yaml:"min_commission_rate"` } +func (s *StakingParams) ToProto() (*anypb.Any, error) { + // Create a map to hold the protobuf fields + fields := map[string]interface{}{ + "unbonding_time": s.UnbondingTime.String(), + "max_validators": s.MaxValidators, + "max_entries": s.MaxEntries, + "historical_entries": s.HistoricalEntries, + "bondDenom": s.BondDenom, + "min_commission_rate": s.MinCommissionRate.String(), + } + + // Convert the map to a protobuf Struct + pbStruct, err := structpb.NewStruct(fields) + if err != nil { + return nil, err + } + + // Marshal the Struct into an Any message + anyMsg, err := anypb.New(pbStruct) + if err != nil { + return nil, err + } + + return anyMsg, nil +} + type StakingValidator struct { // operator_address defines the address of the validator's operator; bech encoded in JSON. OperatorAddress string `protobuf:"bytes,1,opt,name=operator_address,json=operatorAddress,proto3" json:"operator_address,omitempty"` // consensus_pubkey is the consensus public key of the validator, as a Protobuf Any. - ConsensusPubkey *any.Any `protobuf:"bytes,2,opt,name=consensus_pubkey,json=consensusPubkey,proto3" json:"consensus_pubkey,omitempty"` + ConsensusPubkey *gogoany.Any `protobuf:"bytes,2,opt,name=consensus_pubkey,json=consensusPubkey,proto3" json:"consensus_pubkey,omitempty"` // jailed defined whether the validator has been jailed from bonded status or not. Jailed bool `protobuf:"varint,3,opt,name=jailed,proto3" json:"jailed,omitempty"` // status is the validator status (bonded/unbonding/unbonded). @@ -98,6 +131,33 @@ type StakingValidator struct { MinSelfDelegation math.Int `protobuf:"bytes,11,opt,name=min_self_delegation,json=minSelfDelegation,proto3,customtype=cosmossdk.io/math.Int" json:"min_self_delegation"` } +func (s *StakingValidator) ToProto() (*anypb.Any, error) { + // Create a map to hold the protobuf fields + fields := map[string]interface{}{ + "operator_address": s.OperatorAddress, + "consensus_pubkey": s.ConsensusPubkey, + "jailed": s.Jailed, + "status": s.Status, + "tokens": s.Tokens.String(), + "delegator_shares": s.DelegatorShares.String(), + "min_self_delegation": s.MinSelfDelegation.String(), + } + + // Convert the map to a protobuf Struct + pbStruct, err := structpb.NewStruct(fields) + if err != nil { + return nil, err + } + + // Marshal the Struct into an Any message + anyMsg, err := anypb.New(pbStruct) + if err != nil { + return nil, err + } + + return anyMsg, nil +} + type StakingDelegation struct { // delegator_address is the encoded address of the delegator. DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` @@ -107,46 +167,67 @@ type StakingDelegation struct { Shares math.LegacyDec `protobuf:"bytes,3,opt,name=shares,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"shares"` } -// func FakeStakingMsgCreateValidator( -// valAddr string, pubKey cryptotypes.PubKey, selfDelegation sdk.Coin, -// rate, maxRate, maxChangeRate math.LegacyDec, minSelfDelegation math.Int, -// ) (proto.Message, error) { -// var pkAny *codectypes.Any -// if pubKey != nil { -// var err error -// if pkAny, err = codectypes.NewAnyWithValue(pubKey); err != nil { -// return nil, err -// } -// } - -// v := &StakingMsgCreateValidator{ -// Commission: StakingValidatorCommission{ -// Rate: rate, -// MaxRate: maxRate, -// MaxChangeRate: maxChangeRate, -// }, -// MinSelfDelegation: minSelfDelegation, -// DelegatorAddress: "", -// ValidatorAddress: valAddr, -// Pubkey: pkAny, -// Value: selfDelegation, -// } - -// _ = v - -// return nil, nil -// } +func (s *StakingDelegation) ToProto() (*anypb.Any, error) { + // Create a map to hold the protobuf fields + fields := map[string]interface{}{ + "delegator_address": s.DelegatorAddress, + "validator_address": s.ValidatorAddress, + "shares": s.Shares.String(), + } + + // Convert the map to a protobuf Struct + pbStruct, err := structpb.NewStruct(fields) + if err != nil { + return nil, err + } + + // Marshal the Struct into an Any message + anyMsg, err := anypb.New(pbStruct) + if err != nil { + return nil, err + } + + return anyMsg, nil +} type StakingMsgCreateValidator struct { Commission StakingValidatorCommission `protobuf:"bytes,2,opt,name=commission,proto3" json:"commission"` MinSelfDelegation math.Int `protobuf:"bytes,3,opt,name=min_self_delegation,json=minSelfDelegation,proto3,customtype=cosmossdk.io/math.Int" json:"min_self_delegation"` - // Deprecated: Use of Delegator Address in MsgCreateValidator is deprecated. // The validator address bytes and delegator address bytes refer to the same account while creating validator (defer // only in bech32 notation). - DelegatorAddress string `protobuf:"bytes,4,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` // Deprecated: Do not use. - ValidatorAddress string `protobuf:"bytes,5,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` - Pubkey *any.Any `protobuf:"bytes,6,opt,name=pubkey,proto3" json:"pubkey,omitempty"` - Value sdk.Coin `protobuf:"bytes,7,opt,name=value,proto3" json:"value"` + ValidatorAddress string `protobuf:"bytes,5,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` + Pubkey *gogoany.Any `protobuf:"bytes,6,opt,name=pubkey,proto3" json:"pubkey,omitempty"` + Value sdk.Coin `protobuf:"bytes,7,opt,name=value,proto3" json:"value"` +} + +func (s *StakingMsgCreateValidator) ToProto() (*anypb.Any, error) { + comm, err := s.Commission.ToProto() + if err != nil { + return nil, err + } + + // Create a map to hold the protobuf fields + fields := map[string]interface{}{ + "commission": comm, + "min_self_delegation": s.MinSelfDelegation.String(), + "validator_address": s.ValidatorAddress, + "pubkey": s.Pubkey, + "value": s.Value.String(), + } + + // Convert the map to a protobuf Struct + pbStruct, err := structpb.NewStruct(fields) + if err != nil { + return nil, err + } + + // Marshal the Struct into an Any message + anyMsg, err := anypb.New(pbStruct) + if err != nil { + return nil, err + } + + return anyMsg, nil } type StakingValidatorCommission struct { @@ -157,3 +238,26 @@ type StakingValidatorCommission struct { // max_change_rate defines the maximum daily increase of the validator commission, as a fraction. MaxChangeRate math.LegacyDec `protobuf:"bytes,3,opt,name=max_change_rate,json=maxChangeRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"max_change_rate"` } + +func (s *StakingValidatorCommission) ToProto() (*anypb.Any, error) { + // Create a map to hold the protobuf fields + fields := map[string]interface{}{ + "rate": s.Rate.String(), + "max_rate": s.MaxRate.String(), + "max_change_rate": s.MaxChangeRate.String(), + } + + // Convert the map to a protobuf Struct + pbStruct, err := structpb.NewStruct(fields) + if err != nil { + return nil, err + } + + // Marshal the Struct into an Any message + anyMsg, err := anypb.New(pbStruct) + if err != nil { + return nil, err + } + + return anyMsg, nil +} diff --git a/testutil/sims/state_helpers.go b/testutil/sims/state_helpers.go index f8862527aab7..fe48e185f7c8 100644 --- a/testutil/sims/state_helpers.go +++ b/testutil/sims/state_helpers.go @@ -130,7 +130,7 @@ func appStateFnWithExtendedCbs( } rawStakingState := new(anypb.Any) - if err = json.Unmarshal(stakingStateBz, rawStakingState); err != nil { + if err = cdc.UnmarshalJSON(stakingStateBz, rawStakingState); err != nil { panic(err) } From 5135c45ff464c4138cd606e52f40b2463db6e8e0 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 24 Jul 2024 11:02:46 +0200 Subject: [PATCH 05/11] progress --- testutil/network/network.go | 69 ------ testutil/sims/app_helpers.go | 50 +++- testutil/sims/staking.go | 447 ++++++++++++++++++++++++++++------- 3 files changed, 406 insertions(+), 160 deletions(-) diff --git a/testutil/network/network.go b/testutil/network/network.go index dd739919c4b9..687bd9daebfb 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -36,7 +36,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" - "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/codec" addresscodec "github.com/cosmos/cosmos-sdk/codec/address" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -48,7 +47,6 @@ import ( srvconfig "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/sims" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" @@ -388,7 +386,6 @@ func New(l Logger, baseDir string, cfg Config) (NetworkI, error) { nodeDirName := fmt.Sprintf("node%d", i) nodeDir := filepath.Join(network.BaseDir, nodeDirName, "simd") clientDir := filepath.Join(network.BaseDir, nodeDirName, "simcli") - gentxsDir := filepath.Join(network.BaseDir, "gentxs") err := os.MkdirAll(filepath.Join(nodeDir, "config"), 0o755) if err != nil { @@ -478,72 +475,6 @@ func New(l Logger, baseDir string, cfg Config) (NetworkI, error) { genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: balances.Sort()}) genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0)) - commission, err := sdkmath.LegacyNewDecFromStr("0.5") - if err != nil { - return nil, err - } - - var pkAny *codectypes.Any - if pubkey := valPubKeys[i]; pubkey != nil { - var err error - if pkAny, err = codectypes.NewAnyWithValue(pubKey); err != nil { - return nil, err - } - } - - createValMsgStruct := &sims.StakingMsgCreateValidator{ - Commission: sims.StakingValidatorCommission{ - Rate: commission, - MaxRate: commission, - MaxChangeRate: sdkmath.LegacyOneDec(), - }, - MinSelfDelegation: sdkmath.OneInt(), - ValidatorAddress: sdk.ValAddress(addr).String(), - Pubkey: pkAny, - Value: sdk.NewCoin(cfg.BondDenom, cfg.BondedTokens), - } - - createValMsg, err := createValMsgStruct.ToProto() - if err != nil { - return nil, err - } - - p2pURL, err := url.Parse(p2pAddr) - if err != nil { - return nil, err - } - - memo := fmt.Sprintf("%s@%s:%s", nodeIDs[i], p2pURL.Hostname(), p2pURL.Port()) - fee := sdk.NewCoins(sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), sdkmath.NewInt(0))) - txBuilder := cfg.TxConfig.NewTxBuilder() - err = txBuilder.SetMsgs(createValMsg) - if err != nil { - return nil, err - } - txBuilder.SetFeeAmount(fee) // Arbitrary fee - txBuilder.SetGasLimit(1000000) // Need at least 100386 - txBuilder.SetMemo(memo) - - txFactory := tx.Factory{} - txFactory = txFactory. - WithChainID(cfg.ChainID). - WithMemo(memo). - WithKeybase(kb). - WithTxConfig(cfg.TxConfig) - - err = tx.Sign(context.Background(), txFactory, nodeDirName, txBuilder, true) - if err != nil { - return nil, err - } - - txBz, err := cfg.TxConfig.TxJSONEncoder()(txBuilder.GetTx()) - if err != nil { - return nil, err - } - err = writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz) - if err != nil { - return nil, err - } err = srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "app.toml"), appCfg) if err != nil { return nil, err diff --git a/testutil/sims/app_helpers.go b/testutil/sims/app_helpers.go index 542ef1a28273..bc707234f86b 100644 --- a/testutil/sims/app_helpers.go +++ b/testutil/sims/app_helpers.go @@ -224,11 +224,13 @@ func GenesisStateWithValSet( genesisState[authtypes.ModuleName] = codec.MustMarshalJSON(authGenesis) validators := make([]StakingValidator, 0, len(valSet.Validators)) + lastValidatorPower := make([]LastValidatorPower, 0, len(valSet.Validators)) delegations := make([]StakingDelegation, 0, len(valSet.Validators)) bondAmt := sdk.DefaultPowerReduction + var totalPower int64 - for _, val := range valSet.Validators { + for i, val := range valSet.Validators { pk, err := cryptocodec.FromCmtPubKeyInterface(val.PubKey) if err != nil { return nil, fmt.Errorf("failed to convert pubkey: %w", err) @@ -239,17 +241,37 @@ func GenesisStateWithValSet( return nil, fmt.Errorf("failed to create new any: %w", err) } - validator := StakingValidator{ - OperatorAddress: sdk.ValAddress(val.Address).String(), - ConsensusPubkey: pkAny, - Jailed: false, - Status: 3, - Tokens: bondAmt, - DelegatorShares: sdkmath.LegacyOneDec(), - MinSelfDelegation: sdkmath.ZeroInt(), + commission, err := sdkmath.LegacyNewDecFromStr("0.5") + if err != nil { + return nil, err } + validator := StakingValidator{ + OperatorAddress: sdk.ValAddress(val.Address).String(), + ConsensusPubkey: pkAny, + Jailed: false, + Status: 3, + Tokens: bondAmt, + DelegatorShares: sdkmath.LegacyOneDec(), + Description: StakingDescription{ + Moniker: fmt.Sprintf("val-%d", i), + }, + Commission: StakingValidatorCommission{ + StakingCommissionRates: StakingCommissionRates{ + Rate: commission, + MaxRate: commission, + MaxChangeRate: sdkmath.LegacyOneDec(), + }, + }, + MinSelfDelegation: sdkmath.OneInt(), + } validators = append(validators, validator) + totalPower += int64(bondAmt.Int64()) + + lastValidatorPower = append(lastValidatorPower, LastValidatorPower{ + Address: sdk.ValAddress(val.Address).String(), + Power: int64(bondAmt.Int64()), + }) deletation := StakingDelegation{ DelegatorAddress: genAccs[0].GetAddress().String(), @@ -265,12 +287,16 @@ func GenesisStateWithValSet( UnbondingTime: time.Hour * 24 * 7 * 3, MaxValidators: 100, MaxEntries: 7, - HistoricalEntries: 10000, + HistoricalEntries: 0, BondDenom: sdk.DefaultBondDenom, MinCommissionRate: sdkmath.LegacyZeroDec(), + KeyRotationFee: sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100)), }, - Validators: validators, - Delegations: delegations, + LastTotalPower: sdkmath.NewInt(totalPower), + LastValidatorPowers: lastValidatorPower, + Validators: validators, + Delegations: delegations, + Exported: true, } genesisState[testutil.StakingModuleName], _ = json.Marshal(stakingGenesis) diff --git a/testutil/sims/staking.go b/testutil/sims/staking.go index 6da541b6192e..fc442d4d08d2 100644 --- a/testutil/sims/staking.go +++ b/testutil/sims/staking.go @@ -1,6 +1,7 @@ package sims import ( + "fmt" "time" gogoany "github.com/cosmos/gogoproto/types/any" @@ -17,16 +18,29 @@ const ( StakingBondedPoolName = "bonded_tokens_pool" ) +// LastValidatorPower required for validator set update logic. +type LastValidatorPower struct { + // address is the address of the validator. + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + // power defines the power of the validator. + Power int64 `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"` +} + type StakingGenesisState struct { // params defines all the parameters of related to deposit. Params StakingParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` // last_total_power tracks the total amounts of bonded tokens recorded during // the previous end block. LastTotalPower math.Int `protobuf:"bytes,2,opt,name=last_total_power,json=lastTotalPower,proto3,customtype=cosmossdk.io/math.Int" json:"last_total_power"` + // last_validator_powers is a special index that provides a historical list + // of the last-block's bonded validators. + LastValidatorPowers []LastValidatorPower `protobuf:"bytes,3,rep,name=last_validator_powers,json=lastValidatorPowers,proto3" json:"last_validator_powers"` // validators defines the validator set at genesis. Validators []StakingValidator `protobuf:"bytes,4,rep,name=validators,proto3" json:"validators"` // delegations defines the delegations active at genesis. Delegations []StakingDelegation `protobuf:"bytes,5,rep,name=delegations,proto3" json:"delegations"` + // exported defines a bool to identify whether the chain dealing with exported or initialized genesis. + Exported bool `protobuf:"varint,8,opt,name=exported,proto3" json:"exported,omitempty"` } func (s *StakingGenesisState) ToProto() (*anypb.Any, error) { @@ -35,27 +49,47 @@ func (s *StakingGenesisState) ToProto() (*anypb.Any, error) { return nil, err } - // Create a map to hold the protobuf fields - fields := map[string]interface{}{ - "params": params, - "last_total_power": s.LastTotalPower, - "validators": s.Validators, - "delegations": s.Delegations, + lastValidatorPowers := make([]map[string]interface{}, len(s.LastValidatorPowers)) + for i, lvp := range s.LastValidatorPowers { + lastValidatorPowers[i] = map[string]interface{}{ + "address": lvp.Address, + "power": lvp.Power, + } } - // Convert the map to a protobuf Struct - pbStruct, err := structpb.NewStruct(fields) - if err != nil { - return nil, err + validators := make([]map[string]interface{}, len(s.Validators)) + for i, v := range s.Validators { + validatorProto, err := v.ToProto() + if err != nil { + return nil, err + } + validators[i] = map[string]interface{}{"validator": validatorProto} + } + + delegations := make([]map[string]interface{}, len(s.Delegations)) + for i, d := range s.Delegations { + delegationProto, err := d.ToProto() + if err != nil { + return nil, err + } + delegations[i] = map[string]interface{}{"delegation": delegationProto} } - // Marshal the Struct into an Any message - anyMsg, err := anypb.New(pbStruct) + fields := map[string]interface{}{ + "params": params, + "last_total_power": s.LastTotalPower.String(), + "last_validator_powers": lastValidatorPowers, + "validators": validators, + "delegations": delegations, + "exported": s.Exported, + } + + pbStruct, err := structpb.NewStruct(fields) if err != nil { return nil, err } - return anyMsg, nil + return anypb.New(pbStruct) } func ProtoToStakingGenesisState(protoMsg *anypb.Any) (*StakingGenesisState, error) { @@ -64,13 +98,71 @@ func ProtoToStakingGenesisState(protoMsg *anypb.Any) (*StakingGenesisState, erro return nil, err } - genesisStake := &StakingGenesisState{} - // genesisStake.Params = s.Fields["params"]. - // genesisStake.LastTotalPower = s.Fields["last_total_power"]. - // genesisStake.Validators = s.Fields["validators"]. - // genesisStake.Delegations = s.Fields["delegations"]. + genesisState := &StakingGenesisState{} + + // Parse Params + paramsAny, err := anypb.New(s.Fields["params"].GetStructValue()) + if err != nil { + return nil, err + } + params, err := ProtoToStakingParams(paramsAny) + if err != nil { + return nil, err + } + genesisState.Params = *params + + // Parse LastTotalPower + lastTotalPower, ok := math.NewIntFromString(s.Fields["last_total_power"].GetStringValue()) + if !ok { + return nil, fmt.Errorf("failed to parse last_total_power") + } + genesisState.LastTotalPower = lastTotalPower + + // Parse LastValidatorPowers + lastValidatorPowersValue := s.Fields["last_validator_powers"].GetListValue() + genesisState.LastValidatorPowers = make([]LastValidatorPower, len(lastValidatorPowersValue.Values)) + for i, v := range lastValidatorPowersValue.Values { + lvpStruct := v.GetStructValue() + genesisState.LastValidatorPowers[i] = LastValidatorPower{ + Address: lvpStruct.Fields["address"].GetStringValue(), + Power: int64(lvpStruct.Fields["power"].GetNumberValue()), + } + } + + // Parse Validators + validatorsValue := s.Fields["validators"].GetListValue() + genesisState.Validators = make([]StakingValidator, len(validatorsValue.Values)) + for i, v := range validatorsValue.Values { + validatorAny, err := anypb.New(v.GetStructValue().Fields["validator"].GetStructValue()) + if err != nil { + return nil, err + } + validator, err := ProtoToStakingValidator(validatorAny) + if err != nil { + return nil, err + } + genesisState.Validators[i] = *validator + } + + // Parse Delegations + delegationsValue := s.Fields["delegations"].GetListValue() + genesisState.Delegations = make([]StakingDelegation, len(delegationsValue.Values)) + for i, v := range delegationsValue.Values { + delegationAny, err := anypb.New(v.GetStructValue().Fields["delegation"].GetStructValue()) + if err != nil { + return nil, err + } + delegation, err := ProtoToStakingDelegation(delegationAny) + if err != nil { + return nil, err + } + genesisState.Delegations[i] = *delegation + } - return genesisStake, nil + // Parse Exported + genesisState.Exported = s.Fields["exported"].GetBoolValue() + + return genesisState, nil } type StakingParams struct { @@ -86,32 +178,69 @@ type StakingParams struct { BondDenom string `protobuf:"bytes,5,opt,name=bond_denom,json=bondDenom,proto3" json:"bond_denom,omitempty"` // min_commission_rate is the chain-wide minimum commission rate that a validator can charge their delegators MinCommissionRate math.LegacyDec `protobuf:"bytes,6,opt,name=min_commission_rate,json=minCommissionRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"min_commission_rate" yaml:"min_commission_rate"` + // key_rotation_fee is fee to be spent when rotating validator's key + // (either consensus pubkey or operator key) + KeyRotationFee sdk.Coin `protobuf:"bytes,7,opt,name=key_rotation_fee,json=keyRotationFee,proto3" json:"key_rotation_fee"` } func (s *StakingParams) ToProto() (*anypb.Any, error) { - // Create a map to hold the protobuf fields fields := map[string]interface{}{ "unbonding_time": s.UnbondingTime.String(), "max_validators": s.MaxValidators, "max_entries": s.MaxEntries, "historical_entries": s.HistoricalEntries, - "bondDenom": s.BondDenom, + "bond_denom": s.BondDenom, "min_commission_rate": s.MinCommissionRate.String(), + "key_rotation_fee": map[string]interface{}{ + "denom": s.KeyRotationFee.Denom, + "amount": s.KeyRotationFee.Amount.String(), + }, } - // Convert the map to a protobuf Struct pbStruct, err := structpb.NewStruct(fields) if err != nil { return nil, err } - // Marshal the Struct into an Any message - anyMsg, err := anypb.New(pbStruct) + return anypb.New(pbStruct) +} + +func ProtoToStakingParams(protoMsg *anypb.Any) (*StakingParams, error) { + var s structpb.Struct + if err := protoMsg.UnmarshalTo(&s); err != nil { + return nil, err + } + + params := &StakingParams{} + + unbondingTime, err := time.ParseDuration(s.Fields["unbonding_time"].GetStringValue()) + if err != nil { + return nil, err + } + params.UnbondingTime = unbondingTime + + params.MaxValidators = uint32(s.Fields["max_validators"].GetNumberValue()) + params.MaxEntries = uint32(s.Fields["max_entries"].GetNumberValue()) + params.HistoricalEntries = uint32(s.Fields["historical_entries"].GetNumberValue()) + params.BondDenom = s.Fields["bond_denom"].GetStringValue() + + minCommissionRate, err := math.LegacyNewDecFromStr(s.Fields["min_commission_rate"].GetStringValue()) if err != nil { return nil, err } + params.MinCommissionRate = minCommissionRate + + keyRotationFeeStruct := s.Fields["key_rotation_fee"].GetStructValue() + amount, ok := math.NewIntFromString(keyRotationFeeStruct.Fields["amount"].GetStringValue()) + if !ok { + return nil, fmt.Errorf("failed to parse key_rotation_fee amount") + } + params.KeyRotationFee = sdk.NewCoin( + keyRotationFeeStruct.Fields["denom"].GetStringValue(), + amount, + ) - return anyMsg, nil + return params, nil } type StakingValidator struct { @@ -127,37 +256,185 @@ type StakingValidator struct { Tokens math.Int `protobuf:"bytes,5,opt,name=tokens,proto3,customtype=cosmossdk.io/math.Int" json:"tokens"` // delegator_shares defines total shares issued to a validator's delegators. DelegatorShares math.LegacyDec `protobuf:"bytes,6,opt,name=delegator_shares,json=delegatorShares,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"delegator_shares"` + // description defines the description terms for the validator. + Description StakingDescription `protobuf:"bytes,7,opt,name=description,proto3" json:"description"` + // unbonding_height defines, if unbonding, the height at which this validator has begun unbonding. + UnbondingHeight int64 `protobuf:"varint,8,opt,name=unbonding_height,json=unbondingHeight,proto3" json:"unbonding_height,omitempty"` + // unbonding_time defines, if unbonding, the min time for the validator to complete unbonding. + UnbondingTime time.Time `protobuf:"bytes,9,opt,name=unbonding_time,json=unbondingTime,proto3,stdtime" json:"unbonding_time"` + // commission defines the commission parameters. + Commission StakingValidatorCommission `protobuf:"bytes,10,opt,name=commission,proto3" json:"commission"` // min_self_delegation is the validator's self declared minimum self delegation. MinSelfDelegation math.Int `protobuf:"bytes,11,opt,name=min_self_delegation,json=minSelfDelegation,proto3,customtype=cosmossdk.io/math.Int" json:"min_self_delegation"` + // strictly positive if this validator's unbonding has been stopped by external modules + UnbondingOnHoldRefCount int64 `protobuf:"varint,12,opt,name=unbonding_on_hold_ref_count,json=unbondingOnHoldRefCount,proto3" json:"unbonding_on_hold_ref_count,omitempty"` + // list of unbonding ids, each uniquely identifying an unbonding of this validator + UnbondingIds []uint64 `protobuf:"varint,13,rep,packed,name=unbonding_ids,json=unbondingIds,proto3" json:"unbonding_ids,omitempty"` } func (s *StakingValidator) ToProto() (*anypb.Any, error) { - // Create a map to hold the protobuf fields + consensusPubkeyAny, err := gogoany.NewAnyWithCacheWithValue(s.ConsensusPubkey) + if err != nil { + return nil, err + } + + descriptionProto, err := s.Description.ToProto() + if err != nil { + return nil, err + } + + commissionProto, err := s.Commission.ToProto() + if err != nil { + return nil, err + } + fields := map[string]interface{}{ - "operator_address": s.OperatorAddress, - "consensus_pubkey": s.ConsensusPubkey, - "jailed": s.Jailed, - "status": s.Status, - "tokens": s.Tokens.String(), - "delegator_shares": s.DelegatorShares.String(), - "min_self_delegation": s.MinSelfDelegation.String(), + "operator_address": s.OperatorAddress, + "consensus_pubkey": consensusPubkeyAny, + "jailed": s.Jailed, + "status": s.Status, + "tokens": s.Tokens.String(), + "delegator_shares": s.DelegatorShares.String(), + "description": descriptionProto, + "unbonding_height": s.UnbondingHeight, + "unbonding_time": s.UnbondingTime.Format(time.RFC3339), + "commission": commissionProto, + "min_self_delegation": s.MinSelfDelegation.String(), + "unbonding_on_hold_ref_count": s.UnbondingOnHoldRefCount, + "unbonding_ids": s.UnbondingIds, } - // Convert the map to a protobuf Struct pbStruct, err := structpb.NewStruct(fields) if err != nil { return nil, err } - // Marshal the Struct into an Any message - anyMsg, err := anypb.New(pbStruct) + return anypb.New(pbStruct) +} + +func ProtoToStakingValidator(protoMsg *anypb.Any) (*StakingValidator, error) { + var s structpb.Struct + if err := protoMsg.UnmarshalTo(&s); err != nil { + return nil, err + } + + validator := &StakingValidator{} + + validator.OperatorAddress = s.Fields["operator_address"].GetStringValue() + + consensusPubkeyAny := s.Fields["consensus_pubkey"].GetStructValue() + validator.ConsensusPubkey = &gogoany.Any{ + TypeUrl: consensusPubkeyAny.Fields["type_url"].GetStringValue(), + Value: []byte(consensusPubkeyAny.Fields["value"].GetStringValue()), + } + + validator.Jailed = s.Fields["jailed"].GetBoolValue() + validator.Status = int32(s.Fields["status"].GetNumberValue()) + + tokens, ok := math.NewIntFromString(s.Fields["tokens"].GetStringValue()) + if !ok { + return nil, fmt.Errorf("failed to parse tokens") + } + validator.Tokens = tokens + + delegatorShares, err := math.LegacyNewDecFromStr(s.Fields["delegator_shares"].GetStringValue()) + if err != nil { + return nil, err + } + validator.DelegatorShares = delegatorShares + + descriptionAny, err := anypb.New(s.Fields["description"].GetStructValue()) + if err != nil { + return nil, err + } + description, err := ProtoToStakingDescription(descriptionAny) + if err != nil { + return nil, err + } + validator.Description = *description + + validator.UnbondingHeight = int64(s.Fields["unbonding_height"].GetNumberValue()) + + unbondingTime, err := time.Parse(time.RFC3339, s.Fields["unbonding_time"].GetStringValue()) + if err != nil { + return nil, err + } + validator.UnbondingTime = unbondingTime + + commissionAny, err := anypb.New(s.Fields["commission"].GetStructValue()) + if err != nil { + return nil, err + } + commission, err := ProtoToStakingValidatorCommission(commissionAny) + if err != nil { + return nil, err + } + validator.Commission = *commission + + minSelfDelegation, ok := math.NewIntFromString(s.Fields["min_self_delegation"].GetStringValue()) + if !ok { + return nil, fmt.Errorf("failed to parse min_self_delegation") + } + validator.MinSelfDelegation = minSelfDelegation + + validator.UnbondingOnHoldRefCount = int64(s.Fields["unbonding_on_hold_ref_count"].GetNumberValue()) + + unbondingIdsValue := s.Fields["unbonding_ids"].GetListValue() + validator.UnbondingIds = make([]uint64, len(unbondingIdsValue.Values)) + for i, v := range unbondingIdsValue.Values { + validator.UnbondingIds[i] = uint64(v.GetNumberValue()) + } + + return validator, nil +} + +// StakingDescription defines a validator description. +type StakingDescription struct { + // moniker defines a human-readable name for the validator. + Moniker string `protobuf:"bytes,1,opt,name=moniker,proto3" json:"moniker,omitempty"` + // identity defines an optional identity signature (ex. UPort or Keybase). + Identity string `protobuf:"bytes,2,opt,name=identity,proto3" json:"identity,omitempty"` + // website defines an optional website link. + Website string `protobuf:"bytes,3,opt,name=website,proto3" json:"website,omitempty"` + // security_contact defines an optional email for security contact. + SecurityContact string `protobuf:"bytes,4,opt,name=security_contact,json=securityContact,proto3" json:"security_contact,omitempty"` + // details define other optional details. + Details string `protobuf:"bytes,5,opt,name=details,proto3" json:"details,omitempty"` +} + +func (s *StakingDescription) ToProto() (*anypb.Any, error) { + fields := map[string]interface{}{ + "moniker": s.Moniker, + "identity": s.Identity, + "website": s.Website, + "security_contact": s.SecurityContact, + "details": s.Details, + } + + pbStruct, err := structpb.NewStruct(fields) if err != nil { return nil, err } - return anyMsg, nil + return anypb.New(pbStruct) } +func ProtoToStakingDescription(protoMsg *anypb.Any) (*StakingDescription, error) { + var s structpb.Struct + if err := protoMsg.UnmarshalTo(&s); err != nil { + return nil, err + } + + return &StakingDescription{ + Moniker: s.Fields["moniker"].GetStringValue(), + Identity: s.Fields["identity"].GetStringValue(), + Website: s.Fields["website"].GetStringValue(), + SecurityContact: s.Fields["security_contact"].GetStringValue(), + Details: s.Fields["details"].GetStringValue(), + }, nil +} + +// StakingDelegation defines the structure for delegated funds per delegator. type StakingDelegation struct { // delegator_address is the encoded address of the delegator. DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` @@ -181,56 +458,29 @@ func (s *StakingDelegation) ToProto() (*anypb.Any, error) { return nil, err } - // Marshal the Struct into an Any message - anyMsg, err := anypb.New(pbStruct) - if err != nil { - return nil, err - } - - return anyMsg, nil -} - -type StakingMsgCreateValidator struct { - Commission StakingValidatorCommission `protobuf:"bytes,2,opt,name=commission,proto3" json:"commission"` - MinSelfDelegation math.Int `protobuf:"bytes,3,opt,name=min_self_delegation,json=minSelfDelegation,proto3,customtype=cosmossdk.io/math.Int" json:"min_self_delegation"` - // The validator address bytes and delegator address bytes refer to the same account while creating validator (defer - // only in bech32 notation). - ValidatorAddress string `protobuf:"bytes,5,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` - Pubkey *gogoany.Any `protobuf:"bytes,6,opt,name=pubkey,proto3" json:"pubkey,omitempty"` - Value sdk.Coin `protobuf:"bytes,7,opt,name=value,proto3" json:"value"` + return anypb.New(pbStruct) } -func (s *StakingMsgCreateValidator) ToProto() (*anypb.Any, error) { - comm, err := s.Commission.ToProto() - if err != nil { - return nil, err - } - - // Create a map to hold the protobuf fields - fields := map[string]interface{}{ - "commission": comm, - "min_self_delegation": s.MinSelfDelegation.String(), - "validator_address": s.ValidatorAddress, - "pubkey": s.Pubkey, - "value": s.Value.String(), - } - - // Convert the map to a protobuf Struct - pbStruct, err := structpb.NewStruct(fields) - if err != nil { +func ProtoToStakingDelegation(protoMsg *anypb.Any) (*StakingDelegation, error) { + var s structpb.Struct + if err := protoMsg.UnmarshalTo(&s); err != nil { return nil, err } - // Marshal the Struct into an Any message - anyMsg, err := anypb.New(pbStruct) + shares, err := math.LegacyNewDecFromStr(s.Fields["shares"].GetStringValue()) if err != nil { return nil, err } - return anyMsg, nil + return &StakingDelegation{ + DelegatorAddress: s.Fields["delegator_address"].GetStringValue(), + ValidatorAddress: s.Fields["validator_address"].GetStringValue(), + Shares: shares, + }, nil } -type StakingValidatorCommission struct { +// CommissionRates defines the initial commission rates to be used for creating a validator. +type StakingCommissionRates struct { // rate is the commission rate charged to delegators, as a fraction. Rate math.LegacyDec `protobuf:"bytes,1,opt,name=rate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"rate"` // max_rate defines the maximum commission rate which validator can ever charge, as a fraction. @@ -239,6 +489,14 @@ type StakingValidatorCommission struct { MaxChangeRate math.LegacyDec `protobuf:"bytes,3,opt,name=max_change_rate,json=maxChangeRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"max_change_rate"` } +// StakingValidatorCommission defines the initial commission rates to be used for creating a validator. +type StakingValidatorCommission struct { + // commission_rates defines the initial commission rates to be used for creating a validator. + StakingCommissionRates `protobuf:"bytes,1,opt,name=commission_rates,json=commissionRates,proto3,embedded=commission_rates" json:"commission_rates"` + // update_time is the last time the commission rate was changed. + UpdateTime time.Time `protobuf:"bytes,2,opt,name=update_time,json=updateTime,proto3,stdtime" json:"update_time"` +} + func (s *StakingValidatorCommission) ToProto() (*anypb.Any, error) { // Create a map to hold the protobuf fields fields := map[string]interface{}{ @@ -253,11 +511,42 @@ func (s *StakingValidatorCommission) ToProto() (*anypb.Any, error) { return nil, err } - // Marshal the Struct into an Any message - anyMsg, err := anypb.New(pbStruct) + return anypb.New(pbStruct) +} + +func ProtoToStakingValidatorCommission(protoMsg *anypb.Any) (*StakingValidatorCommission, error) { + var s structpb.Struct + if err := protoMsg.UnmarshalTo(&s); err != nil { + return nil, err + } + + commission := &StakingValidatorCommission{} + + commissionRates := s.Fields["commission_rates"].GetStructValue() + rate, err := math.LegacyNewDecFromStr(commissionRates.Fields["rate"].GetStringValue()) + if err != nil { + return nil, err + } + maxRate, err := math.LegacyNewDecFromStr(commissionRates.Fields["max_rate"].GetStringValue()) + if err != nil { + return nil, err + } + maxChangeRate, err := math.LegacyNewDecFromStr(commissionRates.Fields["max_change_rate"].GetStringValue()) + if err != nil { + return nil, err + } + + commission.StakingCommissionRates = StakingCommissionRates{ + Rate: rate, + MaxRate: maxRate, + MaxChangeRate: maxChangeRate, + } + + updateTime, err := time.Parse(time.RFC3339, s.Fields["update_time"].GetStringValue()) if err != nil { return nil, err } + commission.UpdateTime = updateTime - return anyMsg, nil + return commission, nil } From b73a4c7fae55a0812a829c8035eea9587ace1a34 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 24 Jul 2024 11:42:27 +0200 Subject: [PATCH 06/11] delete gen_txs --- testutil/network/network.go | 4 ---- testutil/network/util.go | 48 ------------------------------------- 2 files changed, 52 deletions(-) diff --git a/testutil/network/network.go b/testutil/network/network.go index 687bd9daebfb..e4ee032b8041 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -519,10 +519,6 @@ func New(l Logger, baseDir string, cfg Config) (NetworkI, error) { if err != nil { return nil, err } - err = collectGenFiles(cfg, network.Validators, cmtConfigs, network.BaseDir) - if err != nil { - return nil, err - } l.Log("starting test network...") for idx, v := range network.Validators { diff --git a/testutil/network/util.go b/testutil/network/util.go index a3662bf6ea67..1d0f025fabba 100644 --- a/testutil/network/util.go +++ b/testutil/network/util.go @@ -14,7 +14,6 @@ import ( pvm "github.com/cometbft/cometbft/privval" "github.com/cometbft/cometbft/proxy" "github.com/cometbft/cometbft/rpc/client/local" - cmttime "github.com/cometbft/cometbft/types/time" "golang.org/x/sync/errgroup" "cosmossdk.io/log" @@ -27,8 +26,6 @@ import ( servergrpc "github.com/cosmos/cosmos-sdk/server/grpc" servercmtlog "github.com/cosmos/cosmos-sdk/server/log" "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/x/genutil" - genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" ) @@ -135,51 +132,6 @@ func startInProcess(cfg Config, val *Validator) error { return nil } -func collectGenFiles(cfg Config, vals []*Validator, cmtConfigs []*cmtcfg.Config, outputDir string) error { - genTime := cfg.GenesisTime - if genTime.IsZero() { - genTime = cmttime.Now() - } - - for i := 0; i < cfg.NumValidators; i++ { - cmtCfg := cmtConfigs[i] - - nodeDir := filepath.Join(outputDir, vals[i].moniker, "simd") - gentxsDir := filepath.Join(outputDir, "gentxs") - - cmtCfg.Moniker = vals[i].moniker - cmtCfg.SetRoot(nodeDir) - - initCfg := genutiltypes.NewInitConfig(cfg.ChainID, gentxsDir, vals[i].nodeID, vals[i].pubKey) - - genFile := cmtCfg.GenesisFile() - appGenesis, err := genutiltypes.AppGenesisFromFile(genFile) - if err != nil { - return err - } - - appState, err := genutil.GenAppStateFromConfig(cfg.Codec, cfg.TxConfig, - cmtCfg, initCfg, appGenesis, banktypes.GenesisBalancesIterator{}, genutiltypes.DefaultMessageValidator, - cfg.ValidatorAddressCodec, cfg.AddressCodec) - if err != nil { - return err - } - - // overwrite each validator's genesis file to have a canonical genesis time - if err := genutil.ExportGenesisFileWithTime(genFile, cfg.ChainID, nil, appState, genTime); err != nil { - return err - } - - v := vals[i].GetViper() - err = genutiltest.TrackCometConfig(v, nodeDir) - if err != nil { - return err - } - } - - return nil -} - func initGenFiles(cfg Config, genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance, genFiles []string) error { // set the accounts in the genesis state var authGenState authtypes.GenesisState From 98c5991684a42fcdc805abb1e6e5842b24523afc Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 24 Jul 2024 12:05:05 +0200 Subject: [PATCH 07/11] setup viper comet --- testutil/network/network.go | 16 ++++++++++++++-- testutil/network/util.go | 2 +- x/genutil/client/testutil/helpers.go | 8 -------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/testutil/network/network.go b/testutil/network/network.go index e4ee032b8041..8a5eda71ae8c 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -515,11 +515,23 @@ func New(l Logger, baseDir string, cfg Config) (NetworkI, error) { } } - err := initGenFiles(cfg, genAccounts, genBalances, genFiles) - if err != nil { + if err := initGenFiles(cfg, genAccounts, genBalances, genFiles); err != nil { return nil, err } + // setup viper config.toml for each validator + for i, val := range network.Validators { + cmtCfg := cmtConfigs[i] + nodeDir := filepath.Join(network.BaseDir, val.moniker, "simd") + cmtCfg.Moniker = val.moniker + cmtCfg.SetRoot(nodeDir) + v := network.Validators[i].GetViper() + v.Set(flags.FlagHome, nodeDir) + v.SetConfigType("toml") + v.SetConfigName("config") + v.AddConfigPath(filepath.Join(nodeDir, "config")) + } + l.Log("starting test network...") for idx, v := range network.Validators { if err := startInProcess(cfg, v); err != nil { diff --git a/testutil/network/util.go b/testutil/network/util.go index 1d0f025fabba..3f4faf2c4e01 100644 --- a/testutil/network/util.go +++ b/testutil/network/util.go @@ -40,7 +40,7 @@ func startInProcess(cfg Config, val *Validator) error { nodeKey, err := p2p.LoadOrGenNodeKey(cmtCfg.NodeKeyFile()) if err != nil { - return err + return fmt.Errorf("failed to load node key: %w", err) } app := cfg.AppConstructor(val) diff --git a/x/genutil/client/testutil/helpers.go b/x/genutil/client/testutil/helpers.go index 459f325bc755..0e9b1ca2e4e5 100644 --- a/x/genutil/client/testutil/helpers.go +++ b/x/genutil/client/testutil/helpers.go @@ -64,11 +64,3 @@ func WriteAndTrackCometConfig(v *viper.Viper, home string, cfg *cmtcfg.Config) e v.AddConfigPath(filepath.Join(home, "config")) return v.ReadInConfig() } - -func TrackCometConfig(v *viper.Viper, home string) error { - v.Set(flags.FlagHome, home) - v.SetConfigType("toml") - v.SetConfigName("config") - v.AddConfigPath(filepath.Join(home, "config")) - return v.ReadInConfig() -} From 34cc4813e195b6df85bfa8c1aa939030e6a37e37 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 24 Jul 2024 13:16:17 +0200 Subject: [PATCH 08/11] wip --- testutil/network/util.go | 10 +++++----- types/module/module.go | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/testutil/network/util.go b/testutil/network/util.go index 3f4faf2c4e01..502cfbceefbd 100644 --- a/testutil/network/util.go +++ b/testutil/network/util.go @@ -62,9 +62,13 @@ func startInProcess(cfg Config, val *Validator) error { return node.ChecksummedGenesisDoc{GenesisDoc: gen, Sha256Checksum: make([]byte, 0)}, nil } + ctx := context.Background() + ctx, val.cancelFn = context.WithCancel(ctx) + val.errGroup, ctx = errgroup.WithContext(ctx) + cmtApp := server.NewCometABCIWrapper(app) tmNode, err := node.NewNode( //resleak:notresource - context.TODO(), + ctx, cmtCfg, pvm.LoadOrGenFilePV(cmtCfg.PrivValidatorKeyFile(), cmtCfg.PrivValidatorStateFile()), nodeKey, @@ -97,10 +101,6 @@ func startInProcess(cfg Config, val *Validator) error { app.RegisterNodeService(val.clientCtx, *val.AppConfig) } - ctx := context.Background() - ctx, val.cancelFn = context.WithCancel(ctx) - val.errGroup, ctx = errgroup.WithContext(ctx) - grpcCfg := val.AppConfig.GRPC if grpcCfg.Enable { diff --git a/types/module/module.go b/types/module/module.go index 7ea5db116bc5..a113aea49381 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -412,6 +412,10 @@ func (m *Manager) InitGenesis(ctx sdk.Context, genesisData map[string]json.RawMe var validatorUpdates []ValidatorUpdate ctx.Logger().Info("initializing blockchain state from genesis.json") for _, moduleName := range m.OrderInitGenesis { + if moduleName == "staking" { + fmt.Println(string(genesisData[moduleName])) + } + if genesisData[moduleName] == nil { continue } From 723699cd4f6ff26208793a3c01ccf12f68011875 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 24 Jul 2024 15:00:10 +0200 Subject: [PATCH 09/11] sims DONE. --- testutil/sims/app_helpers.go | 35 ++++++--- testutil/sims/staking.go | 135 ++++++++++++++++++++++++++++------- types/module/module.go | 4 -- 3 files changed, 136 insertions(+), 38 deletions(-) diff --git a/testutil/sims/app_helpers.go b/testutil/sims/app_helpers.go index bc707234f86b..cb3b3ec07185 100644 --- a/testutil/sims/app_helpers.go +++ b/testutil/sims/app_helpers.go @@ -247,17 +247,18 @@ func GenesisStateWithValSet( } validator := StakingValidator{ - OperatorAddress: sdk.ValAddress(val.Address).String(), - ConsensusPubkey: pkAny, - Jailed: false, - Status: 3, - Tokens: bondAmt, - DelegatorShares: sdkmath.LegacyOneDec(), + OperatorAddress: sdk.ValAddress(val.Address).String(), + ConsensusPubkey: pkAny, + consensusPubKeyConcrete: pk, + Jailed: false, + Status: 3, + Tokens: bondAmt, + DelegatorShares: sdkmath.LegacyOneDec(), Description: StakingDescription{ Moniker: fmt.Sprintf("val-%d", i), }, Commission: StakingValidatorCommission{ - StakingCommissionRates: StakingCommissionRates{ + CommissionRates: StakingCommissionRates{ Rate: commission, MaxRate: commission, MaxChangeRate: sdkmath.LegacyOneDec(), @@ -266,11 +267,11 @@ func GenesisStateWithValSet( MinSelfDelegation: sdkmath.OneInt(), } validators = append(validators, validator) - totalPower += int64(bondAmt.Int64()) + totalPower += bondAmt.Int64() lastValidatorPower = append(lastValidatorPower, LastValidatorPower{ Address: sdk.ValAddress(val.Address).String(), - Power: int64(bondAmt.Int64()), + Power: bondAmt.Int64(), }) deletation := StakingDelegation{ @@ -298,7 +299,21 @@ func GenesisStateWithValSet( Delegations: delegations, Exported: true, } - genesisState[testutil.StakingModuleName], _ = json.Marshal(stakingGenesis) + + stakingGenesisProto, err := stakingGenesis.ToProto() + if err != nil { + return nil, fmt.Errorf("transform staking genesis struct to proto failed: %w", err) + } + + marshalledStakingGenesisProto, err := codec.MarshalJSON(stakingGenesisProto) + if err != nil { + return nil, fmt.Errorf("marshal staking genesis proto to json failed: %w", err) + } + + genesisState[testutil.StakingModuleName], err = extractAnyValueFromJSON(marshalledStakingGenesisProto) + if err != nil { + return nil, fmt.Errorf("extract staking genesis proto from json failed: %w", err) + } totalSupply := sdk.NewCoins() for _, b := range balances { diff --git a/testutil/sims/staking.go b/testutil/sims/staking.go index fc442d4d08d2..f7b5dda6ad09 100644 --- a/testutil/sims/staking.go +++ b/testutil/sims/staking.go @@ -1,6 +1,7 @@ package sims import ( + "bytes" "fmt" "time" @@ -10,6 +11,7 @@ import ( "cosmossdk.io/math" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -44,12 +46,16 @@ type StakingGenesisState struct { } func (s *StakingGenesisState) ToProto() (*anypb.Any, error) { - params, err := s.Params.ToProto() + paramsAny, err := s.Params.ToProto() + if err != nil { + return nil, err + } + params, err := structpbToMap(paramsAny) if err != nil { return nil, err } - lastValidatorPowers := make([]map[string]interface{}, len(s.LastValidatorPowers)) + lastValidatorPowers := make([]interface{}, len(s.LastValidatorPowers)) for i, lvp := range s.LastValidatorPowers { lastValidatorPowers[i] = map[string]interface{}{ "address": lvp.Address, @@ -57,22 +63,30 @@ func (s *StakingGenesisState) ToProto() (*anypb.Any, error) { } } - validators := make([]map[string]interface{}, len(s.Validators)) + validators := make([]interface{}, len(s.Validators)) for i, v := range s.Validators { - validatorProto, err := v.ToProto() + validatorAny, err := v.ToProto() + if err != nil { + return nil, err + } + validatorProto, err := structpbToMap(validatorAny) if err != nil { return nil, err } - validators[i] = map[string]interface{}{"validator": validatorProto} + validators[i] = validatorProto } - delegations := make([]map[string]interface{}, len(s.Delegations)) + delegations := make([]interface{}, len(s.Delegations)) for i, d := range s.Delegations { - delegationProto, err := d.ToProto() + delegationAny, err := d.ToProto() + if err != nil { + return nil, err + } + delegationProto, err := structpbToMap(delegationAny) if err != nil { return nil, err } - delegations[i] = map[string]interface{}{"delegation": delegationProto} + delegations[i] = delegationProto } fields := map[string]interface{}{ @@ -133,7 +147,7 @@ func ProtoToStakingGenesisState(protoMsg *anypb.Any) (*StakingGenesisState, erro validatorsValue := s.Fields["validators"].GetListValue() genesisState.Validators = make([]StakingValidator, len(validatorsValue.Values)) for i, v := range validatorsValue.Values { - validatorAny, err := anypb.New(v.GetStructValue().Fields["validator"].GetStructValue()) + validatorAny, err := anypb.New(v.GetStructValue()) if err != nil { return nil, err } @@ -148,7 +162,7 @@ func ProtoToStakingGenesisState(protoMsg *anypb.Any) (*StakingGenesisState, erro delegationsValue := s.Fields["delegations"].GetListValue() genesisState.Delegations = make([]StakingDelegation, len(delegationsValue.Values)) for i, v := range delegationsValue.Values { - delegationAny, err := anypb.New(v.GetStructValue().Fields["delegation"].GetStructValue()) + delegationAny, err := anypb.New(v.GetStructValue()) if err != nil { return nil, err } @@ -247,7 +261,8 @@ type StakingValidator struct { // operator_address defines the address of the validator's operator; bech encoded in JSON. OperatorAddress string `protobuf:"bytes,1,opt,name=operator_address,json=operatorAddress,proto3" json:"operator_address,omitempty"` // consensus_pubkey is the consensus public key of the validator, as a Protobuf Any. - ConsensusPubkey *gogoany.Any `protobuf:"bytes,2,opt,name=consensus_pubkey,json=consensusPubkey,proto3" json:"consensus_pubkey,omitempty"` + ConsensusPubkey *gogoany.Any `protobuf:"bytes,2,opt,name=consensus_pubkey,json=consensusPubkey,proto3" json:"consensus_pubkey,omitempty"` + consensusPubKeyConcrete cryptotypes.PubKey `protobuf:-,json:"-"` // jailed defined whether the validator has been jailed from bonded status or not. Jailed bool `protobuf:"varint,3,opt,name=jailed,proto3" json:"jailed,omitempty"` // status is the validator status (bonded/unbonding/unbonded). @@ -273,24 +288,42 @@ type StakingValidator struct { } func (s *StakingValidator) ToProto() (*anypb.Any, error) { - consensusPubkeyAny, err := gogoany.NewAnyWithCacheWithValue(s.ConsensusPubkey) + var consensusPubkeyProto map[string]interface{} + if s.ConsensusPubkey != nil { + consensusPubkeyProto = map[string]interface{}{ + "@type": s.ConsensusPubkey.TypeUrl, + "key": s.consensusPubKeyConcrete.Bytes(), + } + } + + descriptionAny, err := s.Description.ToProto() + if err != nil { + return nil, err + } + + descriptionProto, err := structpbToMap(descriptionAny) if err != nil { return nil, err } - descriptionProto, err := s.Description.ToProto() + commissionAny, err := s.Commission.ToProto() if err != nil { return nil, err } - commissionProto, err := s.Commission.ToProto() + commissionProto, err := structpbToMap(commissionAny) if err != nil { return nil, err } + unbondingIds := make([]interface{}, len(s.UnbondingIds)) + for i, id := range s.UnbondingIds { + unbondingIds[i] = id + } + fields := map[string]interface{}{ "operator_address": s.OperatorAddress, - "consensus_pubkey": consensusPubkeyAny, + "consensus_pubkey": consensusPubkeyProto, "jailed": s.Jailed, "status": s.Status, "tokens": s.Tokens.String(), @@ -301,7 +334,7 @@ func (s *StakingValidator) ToProto() (*anypb.Any, error) { "commission": commissionProto, "min_self_delegation": s.MinSelfDelegation.String(), "unbonding_on_hold_ref_count": s.UnbondingOnHoldRefCount, - "unbonding_ids": s.UnbondingIds, + "unbonding_ids": unbondingIds, } pbStruct, err := structpb.NewStruct(fields) @@ -323,9 +356,9 @@ func ProtoToStakingValidator(protoMsg *anypb.Any) (*StakingValidator, error) { validator.OperatorAddress = s.Fields["operator_address"].GetStringValue() consensusPubkeyAny := s.Fields["consensus_pubkey"].GetStructValue() - validator.ConsensusPubkey = &gogoany.Any{ - TypeUrl: consensusPubkeyAny.Fields["type_url"].GetStringValue(), - Value: []byte(consensusPubkeyAny.Fields["value"].GetStringValue()), + validator.ConsensusPubkey = &gogoany.Any{ // TODO(@julienrbrt): Possibly this is not correct, as we just put the raw bytes of the pubkey in the any value. To check later, right now it works :D + TypeUrl: consensusPubkeyAny.Fields["@type"].GetStringValue(), + Value: []byte(consensusPubkeyAny.Fields["key"].GetStringValue()), } validator.Jailed = s.Fields["jailed"].GetBoolValue() @@ -492,7 +525,7 @@ type StakingCommissionRates struct { // StakingValidatorCommission defines the initial commission rates to be used for creating a validator. type StakingValidatorCommission struct { // commission_rates defines the initial commission rates to be used for creating a validator. - StakingCommissionRates `protobuf:"bytes,1,opt,name=commission_rates,json=commissionRates,proto3,embedded=commission_rates" json:"commission_rates"` + CommissionRates StakingCommissionRates `protobuf:"bytes,1,opt,name=commission_rates,json=commissionRates,proto3,embedded=commission_rates" json:"commission_rates"` // update_time is the last time the commission rate was changed. UpdateTime time.Time `protobuf:"bytes,2,opt,name=update_time,json=updateTime,proto3,stdtime" json:"update_time"` } @@ -500,9 +533,12 @@ type StakingValidatorCommission struct { func (s *StakingValidatorCommission) ToProto() (*anypb.Any, error) { // Create a map to hold the protobuf fields fields := map[string]interface{}{ - "rate": s.Rate.String(), - "max_rate": s.MaxRate.String(), - "max_change_rate": s.MaxChangeRate.String(), + "commission_rates": map[string]interface{}{ + "rate": s.CommissionRates.Rate.String(), + "max_rate": s.CommissionRates.MaxRate.String(), + "max_change_rate": s.CommissionRates.MaxChangeRate.String(), + }, + "update_time": s.UpdateTime.Format(time.RFC3339), } // Convert the map to a protobuf Struct @@ -536,7 +572,7 @@ func ProtoToStakingValidatorCommission(protoMsg *anypb.Any) (*StakingValidatorCo return nil, err } - commission.StakingCommissionRates = StakingCommissionRates{ + commission.CommissionRates = StakingCommissionRates{ Rate: rate, MaxRate: maxRate, MaxChangeRate: maxChangeRate, @@ -550,3 +586,54 @@ func ProtoToStakingValidatorCommission(protoMsg *anypb.Any) (*StakingValidatorCo return commission, nil } + +func structpbToMap(any *anypb.Any) (map[string]interface{}, error) { + if any == nil { + return nil, nil + } + var s structpb.Struct + if err := any.UnmarshalTo(&s); err != nil { + return nil, err + } + return s.AsMap(), nil +} + +// Extract the value from a marshalled any without unmarshalling the whole thing +// This is requird as we cannot unmarshal the protobuf structs directly to json +func extractAnyValueFromJSON(jsonData []byte) ([]byte, error) { + // Find the start of the "value" field + valueStart := bytes.Index(jsonData, []byte(`"value"`)) + if valueStart == -1 { + return nil, fmt.Errorf("error: 'value' field not found") + } + + // Find the start of the value's content (skip over "value": ) + contentStart := bytes.IndexByte(jsonData[valueStart:], '{') + if contentStart == -1 { + return nil, fmt.Errorf("error: opening brace for 'value' content not found") + } + contentStart += valueStart + + // Keep track of nested braces + braceCount := 1 + var contentEnd int + + // Find the end of the value's content + for i := contentStart + 1; i < len(jsonData); i++ { + if jsonData[i] == '{' { + braceCount++ + } else if jsonData[i] == '}' { + braceCount-- + if braceCount == 0 { + contentEnd = i + 1 + break + } + } + } + + if contentEnd == 0 { + return nil, fmt.Errorf("error: closing brace for 'value' content not found") + } + + return jsonData[contentStart:contentEnd], nil +} diff --git a/types/module/module.go b/types/module/module.go index a113aea49381..7ea5db116bc5 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -412,10 +412,6 @@ func (m *Manager) InitGenesis(ctx sdk.Context, genesisData map[string]json.RawMe var validatorUpdates []ValidatorUpdate ctx.Logger().Info("initializing blockchain state from genesis.json") for _, moduleName := range m.OrderInitGenesis { - if moduleName == "staking" { - fmt.Println(string(genesisData[moduleName])) - } - if genesisData[moduleName] == nil { continue } From fd50a476706900d16f97f50302233cac17461352 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 24 Jul 2024 15:58:31 +0200 Subject: [PATCH 10/11] don't use marshal json --- testutil/sims/staking.go | 8 ++++++-- testutil/sims/state_helpers.go | 18 ++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/testutil/sims/staking.go b/testutil/sims/staking.go index f7b5dda6ad09..e99e11c47eab 100644 --- a/testutil/sims/staking.go +++ b/testutil/sims/staking.go @@ -261,8 +261,8 @@ type StakingValidator struct { // operator_address defines the address of the validator's operator; bech encoded in JSON. OperatorAddress string `protobuf:"bytes,1,opt,name=operator_address,json=operatorAddress,proto3" json:"operator_address,omitempty"` // consensus_pubkey is the consensus public key of the validator, as a Protobuf Any. - ConsensusPubkey *gogoany.Any `protobuf:"bytes,2,opt,name=consensus_pubkey,json=consensusPubkey,proto3" json:"consensus_pubkey,omitempty"` - consensusPubKeyConcrete cryptotypes.PubKey `protobuf:-,json:"-"` + ConsensusPubkey *gogoany.Any `protobuf:"bytes,2,opt,name=consensus_pubkey,json=consensusPubkey,proto3" json:"consensus_pubkey,omitempty"` + consensusPubKeyConcrete cryptotypes.PubKey // jailed defined whether the validator has been jailed from bonded status or not. Jailed bool `protobuf:"varint,3,opt,name=jailed,proto3" json:"jailed,omitempty"` // status is the validator status (bonded/unbonding/unbonded). @@ -287,6 +287,10 @@ type StakingValidator struct { UnbondingIds []uint64 `protobuf:"varint,13,rep,packed,name=unbonding_ids,json=unbondingIds,proto3" json:"unbonding_ids,omitempty"` } +func (s *StakingValidator) SetPubKeyContrete(pk cryptotypes.PubKey) { + s.consensusPubKeyConcrete = pk +} + func (s *StakingValidator) ToProto() (*anypb.Any, error) { var consensusPubkeyProto map[string]interface{} if s.ConsensusPubkey != nil { diff --git a/testutil/sims/state_helpers.go b/testutil/sims/state_helpers.go index fe48e185f7c8..f7e4444a8712 100644 --- a/testutil/sims/state_helpers.go +++ b/testutil/sims/state_helpers.go @@ -139,6 +139,11 @@ func appStateFnWithExtendedCbs( panic(err) } + stakingStateProto, err := stakingState.ToProto() + if err != nil { + panic(fmt.Errorf("failed to convert staking state to proto: %w", err)) + } + // compute not bonded balance notBondedTokens := math.ZeroInt() for _, val := range stakingState.Validators { @@ -174,22 +179,15 @@ func appStateFnWithExtendedCbs( } // change appState back - for name, state := range map[string]interface{}{ - testutil.StakingModuleName: stakingState, + for name, state := range map[string]proto.Message{ + testutil.StakingModuleName: stakingStateProto, testutil.BankModuleName: bankState, } { if moduleStateCb != nil { moduleStateCb(name, state) } - if ps, ok := state.(proto.Message); ok { - rawState[name] = cdc.MustMarshalJSON(ps) - } else { - rawState[name], err = json.Marshal(state) - if err != nil { - panic(err) - } - } + rawState[name] = cdc.MustMarshalJSON(state) } // extend state from callback function From 78a5165e959c804b1bb9104ea34871da0b946333 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 24 Jul 2024 15:59:46 +0200 Subject: [PATCH 11/11] network.New = e2e --- .../server/grpc/out_of_gas_test.go | 18 +++++------ .../server/grpc/server_test.go | 32 +++++++++---------- 2 files changed, 25 insertions(+), 25 deletions(-) rename tests/{integration => e2e}/server/grpc/out_of_gas_test.go (82%) rename tests/{integration => e2e}/server/grpc/server_test.go (91%) diff --git a/tests/integration/server/grpc/out_of_gas_test.go b/tests/e2e/server/grpc/out_of_gas_test.go similarity index 82% rename from tests/integration/server/grpc/out_of_gas_test.go rename to tests/e2e/server/grpc/out_of_gas_test.go index f662d2a25ff8..0dfb371267cb 100644 --- a/tests/integration/server/grpc/out_of_gas_test.go +++ b/tests/e2e/server/grpc/out_of_gas_test.go @@ -24,7 +24,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -type IntegrationTestOutOfGasSuite struct { +type E2ETestOutOfGasSuite struct { suite.Suite cfg network.Config @@ -32,9 +32,9 @@ type IntegrationTestOutOfGasSuite struct { conn *grpc.ClientConn } -func (s *IntegrationTestOutOfGasSuite) SetupSuite() { +func (s *E2ETestOutOfGasSuite) SetupSuite() { var err error - s.T().Log("setting up integration test suite") + s.T().Log("setting up E2E test suite") s.cfg, err = network.DefaultConfigWithAppConfigWithQueryGasLimit(configurator.NewAppConfig( configurator.AccountsModule(), @@ -63,13 +63,13 @@ func (s *IntegrationTestOutOfGasSuite) SetupSuite() { s.Require().NoError(err) } -func (s *IntegrationTestOutOfGasSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") +func (s *E2ETestOutOfGasSuite) TearDownSuite() { + s.T().Log("tearing down E2E test suite") s.conn.Close() s.network.Cleanup() } -func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_TestService() { +func (s *E2ETestOutOfGasSuite) TestGRPCServer_TestService() { // gRPC query to test service should work testClient := testdata.NewQueryClient(s.conn) testRes, err := testClient.Echo(context.Background(), &testdata.EchoRequest{Message: "hello"}) @@ -77,7 +77,7 @@ func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_TestService() { s.Require().Equal("hello", testRes.Message) } -func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_BankBalance_OutOfGas() { +func (s *E2ETestOutOfGasSuite) TestGRPCServer_BankBalance_OutOfGas() { val0 := s.network.GetValidators()[0] // gRPC query to bank service should work @@ -93,6 +93,6 @@ func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_BankBalance_OutOfGas() { s.Require().ErrorContains(err, sdkerrors.ErrOutOfGas.Error()) } -func TestIntegrationTestOutOfGasSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestOutOfGasSuite)) +func TestE2ETestOutOfGasSuite(t *testing.T) { + suite.Run(t, new(E2ETestOutOfGasSuite)) } diff --git a/tests/integration/server/grpc/server_test.go b/tests/e2e/server/grpc/server_test.go similarity index 91% rename from tests/integration/server/grpc/server_test.go rename to tests/e2e/server/grpc/server_test.go index f22793c56921..468f3e67260f 100644 --- a/tests/integration/server/grpc/server_test.go +++ b/tests/e2e/server/grpc/server_test.go @@ -36,7 +36,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/tx/signing" ) -type IntegrationTestSuite struct { +type E2ETestSuite struct { suite.Suite cfg network.Config @@ -44,9 +44,9 @@ type IntegrationTestSuite struct { conn *grpc.ClientConn } -func (s *IntegrationTestSuite) SetupSuite() { +func (s *E2ETestSuite) SetupSuite() { var err error - s.T().Log("setting up integration test suite") + s.T().Log("setting up E2E test suite") s.cfg, err = network.DefaultConfigWithAppConfig(configurator.NewAppConfig( configurator.AccountsModule(), @@ -75,13 +75,13 @@ func (s *IntegrationTestSuite) SetupSuite() { s.Require().NoError(err) } -func (s *IntegrationTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") +func (s *E2ETestSuite) TearDownSuite() { + s.T().Log("tearing down E2E test suite") s.conn.Close() s.network.Cleanup() } -func (s *IntegrationTestSuite) TestGRPCServer_TestService() { +func (s *E2ETestSuite) TestGRPCServer_TestService() { // gRPC query to test service should work testClient := testdata.NewQueryClient(s.conn) testRes, err := testClient.Echo(context.Background(), &testdata.EchoRequest{Message: "hello"}) @@ -89,7 +89,7 @@ func (s *IntegrationTestSuite) TestGRPCServer_TestService() { s.Require().Equal("hello", testRes.Message) } -func (s *IntegrationTestSuite) TestGRPCServer_BankBalance() { +func (s *E2ETestSuite) TestGRPCServer_BankBalance() { val0 := s.network.GetValidators()[0] // gRPC query to bank service should work @@ -120,7 +120,7 @@ func (s *IntegrationTestSuite) TestGRPCServer_BankBalance() { s.Require().Equal([]string{"1"}, blockHeight) } -func (s *IntegrationTestSuite) TestGRPCServer_Reflection() { +func (s *E2ETestSuite) TestGRPCServer_Reflection() { // Test server reflection ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() @@ -142,7 +142,7 @@ func (s *IntegrationTestSuite) TestGRPCServer_Reflection() { } } -func (s *IntegrationTestSuite) TestGRPCServer_InterfaceReflection() { +func (s *E2ETestSuite) TestGRPCServer_InterfaceReflection() { // this tests the application reflection capabilities and compatibility between v1 and v2 ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() @@ -165,7 +165,7 @@ func (s *IntegrationTestSuite) TestGRPCServer_InterfaceReflection() { } } -func (s *IntegrationTestSuite) TestGRPCServer_GetTxsEvent() { +func (s *E2ETestSuite) TestGRPCServer_GetTxsEvent() { // Query the tx via gRPC without pagination. This used to panic, see // https://github.com/cosmos/cosmos-sdk/issues/8038. txServiceClient := txtypes.NewServiceClient(s.conn) @@ -178,7 +178,7 @@ func (s *IntegrationTestSuite) TestGRPCServer_GetTxsEvent() { s.Require().NoError(err) } -func (s *IntegrationTestSuite) TestGRPCServer_BroadcastTx() { +func (s *E2ETestSuite) TestGRPCServer_BroadcastTx() { val0 := s.network.GetValidators()[0] txBuilder := s.mkTxBuilder() @@ -203,7 +203,7 @@ func (s *IntegrationTestSuite) TestGRPCServer_BroadcastTx() { // Test and enforce that we upfront reject any connections to baseapp containing // invalid initial x-cosmos-block-height that aren't positive and in the range [0, max(int64)] // See issue https://github.com/cosmos/cosmos-sdk/issues/7662. -func (s *IntegrationTestSuite) TestGRPCServerInvalidHeaderHeights() { +func (s *E2ETestSuite) TestGRPCServerInvalidHeaderHeights() { t := s.T() // We should reject connections with invalid block heights off the bat. @@ -231,7 +231,7 @@ func (s *IntegrationTestSuite) TestGRPCServerInvalidHeaderHeights() { // TestGRPCUnpacker - tests the grpc endpoint for Validator and using the interface registry unpack and extract the // ConsAddr. (ref: https://github.com/cosmos/cosmos-sdk/issues/8045) -func (s *IntegrationTestSuite) TestGRPCUnpacker() { +func (s *E2ETestSuite) TestGRPCUnpacker() { ir := s.cfg.InterfaceRegistry queryClient := stakingtypes.NewQueryClient(s.conn) validator, err := queryClient.Validator(context.Background(), @@ -252,7 +252,7 @@ func (s *IntegrationTestSuite) TestGRPCUnpacker() { } // mkTxBuilder creates a TxBuilder containing a signed tx from validator 0. -func (s *IntegrationTestSuite) mkTxBuilder() client.TxBuilder { +func (s *E2ETestSuite) mkTxBuilder() client.TxBuilder { val := s.network.GetValidators()[0] s.Require().NoError(s.network.WaitForNextBlock()) @@ -285,6 +285,6 @@ func (s *IntegrationTestSuite) mkTxBuilder() client.TxBuilder { return txBuilder } -func TestIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) +func TestE2ETestSuite(t *testing.T) { + suite.Run(t, new(E2ETestSuite)) }