cosmos-sdk/testutil/testnet/validator.go
Julien Robert c452721442
style: add gci linter (#16758)
Co-authored-by: Jacob Gadikian <faddat@users.noreply.github.com>
2023-06-29 09:46:37 +00:00

190 lines
5.3 KiB
Go

package testnet
import (
"fmt"
cmted25519 "github.com/cometbft/cometbft/crypto/ed25519"
cmttypes "github.com/cometbft/cometbft/types"
sdkmath "cosmossdk.io/math"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/bech32"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
// ValidatorPrivKeys is a slice of [*ValidatorPrivKey].
type ValidatorPrivKeys []*ValidatorPrivKey
// ValidatorPrivKey holds a validator key (a comet ed25519 key)
// and the validator's delegator or account key (a Cosmos SDK secp256k1 key).
type ValidatorPrivKey struct {
Val cmted25519.PrivKey
Del *secp256k1.PrivKey
}
// NewValidatorPrivKeys returns a ValidatorPrivKeys of length n,
// where each set of keys is dynamically generated.
//
// If writing a test where deterministic keys are required,
// the caller should manually construct a slice and assign each key as needed.
func NewValidatorPrivKeys(n int) ValidatorPrivKeys {
vpk := make(ValidatorPrivKeys, n)
for i := range vpk {
vpk[i] = &ValidatorPrivKey{
Val: cmted25519.GenPrivKey(),
Del: secp256k1.GenPrivKey(),
}
}
return vpk
}
// CometGenesisValidators derives the CometGenesisValidators belonging to vpk.
func (vpk ValidatorPrivKeys) CometGenesisValidators() CometGenesisValidators {
cgv := make(CometGenesisValidators, len(vpk))
for i, pk := range vpk {
pubKey := pk.Val.PubKey()
const votingPower = 1
cmtVal := cmttypes.NewValidator(pubKey, votingPower)
cgv[i] = &CometGenesisValidator{
V: cmttypes.GenesisValidator{
Address: cmtVal.Address,
PubKey: cmtVal.PubKey,
Power: cmtVal.VotingPower,
Name: fmt.Sprintf("val-%d", i),
},
PK: pk,
}
}
return cgv
}
// CometGenesisValidators is a slice of [*CometGenesisValidator].
type CometGenesisValidators []*CometGenesisValidator
// CometGenesisValidator holds a comet GenesisValidator
// and a reference to the ValidatorPrivKey from which the CometGenesisValidator was derived.
type CometGenesisValidator struct {
V cmttypes.GenesisValidator
PK *ValidatorPrivKey
}
// ToComet returns a new slice of [cmttypes.GenesisValidator],
// useful for some interactions.
func (cgv CometGenesisValidators) ToComet() []cmttypes.GenesisValidator {
vs := make([]cmttypes.GenesisValidator, len(cgv))
for i, v := range cgv {
vs[i] = v.V
}
return vs
}
// StakingValidators derives the StakingValidators belonging to cgv.
func (cgv CometGenesisValidators) StakingValidators() StakingValidators {
vals := make(StakingValidators, len(cgv))
for i, v := range cgv {
pk, err := cryptocodec.FromCmtPubKeyInterface(v.V.PubKey)
if err != nil {
panic(fmt.Errorf("failed to extract comet pub key: %w", err))
}
pkAny, err := codectypes.NewAnyWithValue(pk)
if err != nil {
panic(fmt.Errorf("failed to wrap pub key in any type: %w", err))
}
vals[i] = &StakingValidator{
V: stakingtypes.Validator{
OperatorAddress: sdk.ValAddress(v.V.Address).String(), // TODO: this relies on global bech32 config.
ConsensusPubkey: pkAny,
Status: stakingtypes.Bonded,
Tokens: sdk.DefaultPowerReduction,
DelegatorShares: sdkmath.LegacyOneDec(),
MinSelfDelegation: sdkmath.ZeroInt(),
// more fields uncopied from testutil/sims/app_helpers.go:220
},
C: v,
PK: v.PK,
}
}
return vals
}
// StakingValidators is a slice of [*StakingValidator].
type StakingValidators []*StakingValidator
// StakingValidator holds a [stakingtypes.Validator],
// and the CometGenesisValidator and ValidatorPrivKey required to derive the StakingValidator.
type StakingValidator struct {
V stakingtypes.Validator
C *CometGenesisValidator
PK *ValidatorPrivKey
}
// ToStakingType returns a new slice of [stakingtypes.Validator],
// useful for some interactions.
func (sv StakingValidators) ToStakingType() []stakingtypes.Validator {
vs := make([]stakingtypes.Validator, len(sv))
for i, v := range sv {
vs[i] = v.V
}
return vs
}
// BaseAccounts returns the BaseAccounts for this set of StakingValidators.
// The base accounts are important for [*GenesisBuilder.BaseAccounts].
func (sv StakingValidators) BaseAccounts() BaseAccounts {
ba := make(BaseAccounts, len(sv))
for i, v := range sv {
const accountNumber = 0
const sequenceNumber = 0
pubKey := v.PK.Del.PubKey()
bech, err := bech32.ConvertAndEncode("cosmos", pubKey.Address().Bytes()) // TODO: this shouldn't be hardcoded to cosmos!
if err != nil {
panic(err)
}
accAddr, err := sdk.AccAddressFromBech32(bech)
if err != nil {
panic(err)
}
ba[i] = authtypes.NewBaseAccount(
accAddr, pubKey, accountNumber, sequenceNumber,
)
}
return ba
}
// Balances returns the balances held by this set of StakingValidators.
func (sv StakingValidators) Balances() []banktypes.Balance {
bals := make([]banktypes.Balance, len(sv))
for i, v := range sv {
addr, err := bech32.ConvertAndEncode("cosmos", v.PK.Del.PubKey().Address().Bytes()) // TODO: this shouldn't be hardcoded to cosmos!
if err != nil {
panic(err)
}
bals[i] = banktypes.Balance{
Address: addr,
Coins: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, v.V.Tokens)},
}
}
return bals
}