Skip to content

Commit

Permalink
provider crud flow tests
Browse files Browse the repository at this point in the history
  • Loading branch information
stana-miric committed Oct 30, 2024
1 parent 0363e0a commit 79af94b
Show file tree
Hide file tree
Showing 5 changed files with 755 additions and 133 deletions.
213 changes: 207 additions & 6 deletions tests/interchain/chainsuite/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,30 @@ import (
"context"
"encoding/json"
"fmt"
"path"
"strconv"
"strings"
"sync"

sdkmath "cosmossdk.io/math"
abci "github.com/cometbft/cometbft/abci/types"
govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
providertypes "github.com/cosmos/interchain-security/v6/x/ccv/provider/types"
"github.com/strangelove-ventures/interchaintest/v8"
"github.com/strangelove-ventures/interchaintest/v8/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v8/ibc"
"golang.org/x/sync/errgroup"
)

// This moniker is hardcoded into interchaintest
const validatorMoniker = "validator"
const ValidatorMoniker = "validator"
const TestMonikerPrefix = "testAccount"

type Chain struct {
*cosmos.CosmosChain
ValidatorWallets []ValidatorWallet
RelayerWallet ibc.Wallet
TestWallets []ibc.Wallet
}

type ValidatorWallet struct {
Expand All @@ -30,14 +36,15 @@ type ValidatorWallet struct {
ValoperAddress string
}

func chainFromCosmosChain(cosmos *cosmos.CosmosChain, relayerWallet ibc.Wallet) (*Chain, error) {
func chainFromCosmosChain(cosmos *cosmos.CosmosChain, relayerWallet ibc.Wallet, testWallets []ibc.Wallet) (*Chain, error) {
c := &Chain{CosmosChain: cosmos}
wallets, err := getValidatorWallets(context.Background(), c)
if err != nil {
return nil, err
}
c.ValidatorWallets = wallets
c.RelayerWallet = relayerWallet
c.TestWallets = testWallets
return c, nil
}

Expand All @@ -53,6 +60,8 @@ func CreateProviderChain(ctx context.Context, testName interchaintest.TestName,
return nil, err
}
cosmosChain := chains[0].(*cosmos.CosmosChain)

// build relayer wallet
relayerWallet, err := cosmosChain.BuildRelayerWallet(ctx, "relayer-"+cosmosChain.Config().ChainID)
if err != nil {
return nil, err
Expand All @@ -74,13 +83,45 @@ func CreateProviderChain(ctx context.Context, testName interchaintest.TestName,
return nil, err
}

chain, err := chainFromCosmosChain(cosmosChain, relayerWallet)
// build test wallets
testWallets, err := setupTestWallets(ctx, cosmosChain, TestWalletsNumber)
if err != nil {
return nil, err
}
chain, err := chainFromCosmosChain(cosmosChain, relayerWallet, testWallets)
if err != nil {
return nil, err
}

return chain, nil
}

func setupTestWallets(ctx context.Context, cosmosChain *cosmos.CosmosChain, walletCount int) ([]ibc.Wallet, error) {
wallets := make([]ibc.Wallet, walletCount)
eg := new(errgroup.Group)
for i := 0; i < walletCount; i++ {
keyName := TestMonikerPrefix + strconv.Itoa(i)
wallet, err := cosmosChain.BuildWallet(ctx, keyName, "")
if err != nil {
return nil, err
}
wallets[i] = wallet
eg.Go(func() error {
return cosmosChain.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{
Amount: sdkmath.NewInt(int64(ValidatorFunds)),
Denom: cosmosChain.Config().Denom,
Address: wallet.FormattedAddress(),
})
})
}
err := eg.Wait()
if err != nil {
return nil, err
}

return wallets, nil
}

func getValidatorWallets(ctx context.Context, chain *Chain) ([]ValidatorWallet, error) {
wallets := make([]ValidatorWallet, len(chain.Validators))
lock := new(sync.Mutex)
Expand All @@ -89,7 +130,7 @@ func getValidatorWallets(ctx context.Context, chain *Chain) ([]ValidatorWallet,
i := i
eg.Go(func() error {
// This moniker is hardcoded into the chain's genesis process.
moniker := validatorMoniker
moniker := ValidatorMoniker
address, err := chain.Validators[i].KeyBech32(ctx, moniker, "acc")
if err != nil {
return err
Expand Down Expand Up @@ -143,7 +184,7 @@ func (c *Chain) VoteForProposal(ctx context.Context, proposalID string, vote str

func (c *Chain) SubmitAndVoteForProposal(ctx context.Context, prop cosmos.TxProposalv1, vote string) (string, error) {

propTx, err := c.SubmitProposal(ctx, validatorMoniker, prop)
propTx, err := c.SubmitProposal(ctx, ValidatorMoniker, prop)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -179,11 +220,111 @@ func (c *Chain) ExecuteProposalMsg(ctx context.Context, proposalMsg cosmos.Proto
return nil
}

func (c *Chain) CreateConsumer(ctx context.Context, msg *providertypes.MsgCreateConsumer, keyName string) (string, error) {
content, err := json.Marshal(msg)
if err != nil {
return "", err
}
jsonFile := "create-consumer.json"
if err = c.GetNode().WriteFile(ctx, content, jsonFile); err != nil {
return "", err
}

filePath := path.Join(c.GetNode().HomeDir(), jsonFile)
txHash, err := c.GetNode().ExecTx(ctx, keyName, "provider", "create-consumer", filePath)
if err != nil {
return "", err
}

response, err := c.GetNode().TxHashToResponse(ctx, txHash)
if err != nil {
return "", err
}

consumerId, found := getEvtAttribute(response.Events, providertypes.EventTypeCreateConsumer, providertypes.AttributeConsumerId)
if !found {
return "", fmt.Errorf("consumer id is not found")
}

return consumerId, err
}

func (c *Chain) UpdateConsumer(ctx context.Context, msg *providertypes.MsgUpdateConsumer, keyName string) error {
content, err := json.Marshal(msg)
if err != nil {
return err
}
jsonFile := "update-consumer.json"
if err = c.GetNode().WriteFile(ctx, content, jsonFile); err != nil {
return err
}

filePath := path.Join(c.GetNode().HomeDir(), jsonFile)

_, err = c.GetNode().ExecTx(ctx, keyName, "provider", "update-consumer", filePath)
if err != nil {
return err
}

return err
}

func (c *Chain) RemoveConsumer(ctx context.Context, consumerId string, keyName string) error {
_, err := c.GetNode().ExecTx(ctx, keyName, "provider", "remove-consumer", consumerId)
return err
}

func (c *Chain) OptIn(ctx context.Context, consumerID string, valIndex int) error {
_, err := c.Validators[valIndex].ExecTx(ctx, validatorMoniker, "provider", "opt-in", consumerID)
_, err := c.Validators[valIndex].ExecTx(ctx, ValidatorMoniker, "provider", "opt-in", consumerID)
return err
}

func (c *Chain) OptOut(ctx context.Context, consumerID string, valIndex int) error {
_, err := c.Validators[valIndex].ExecTx(ctx, ValidatorMoniker, "provider", "opt-out", consumerID)
return err
}

func (c *Chain) AssignKey(ctx context.Context, consumerID string, valIndex int, consensusPubKey string) error {
_, err := c.Validators[valIndex].ExecTx(ctx, ValidatorMoniker, "provider", "assign-consensus-key", consumerID, consensusPubKey)
return err
}

func (c *Chain) ValidatorConsumerAddress(ctx context.Context, consumerID string, providerConsensusAddress string) (ValidatorConsumerAddressResponse, error) {
queryRes, _, err := c.GetNode().ExecQuery(
ctx,
"provider", "validator-consumer-key", consumerID, providerConsensusAddress,
)
if err != nil {
return ValidatorConsumerAddressResponse{}, err
}

var queryResponse ValidatorConsumerAddressResponse
err = json.Unmarshal([]byte(queryRes), &queryResponse)
if err != nil {
return ValidatorConsumerAddressResponse{}, err
}

return queryResponse, nil
}

func (c *Chain) ValidatorProviderAddress(ctx context.Context, consumerID string, consumerConsensusAddress string) (ValidatorProviderAddressResponse, error) {
queryRes, _, err := c.GetNode().ExecQuery(
ctx,
"provider", "validator-provider-key", consumerID, consumerConsensusAddress,
)
if err != nil {
return ValidatorProviderAddressResponse{}, err
}

var queryResponse ValidatorProviderAddressResponse
err = json.Unmarshal([]byte(queryRes), &queryResponse)
if err != nil {
return ValidatorProviderAddressResponse{}, err
}

return queryResponse, nil
}

func (c *Chain) ListConsumerChains(ctx context.Context) (ListConsumerChainsResponse, error) {
queryRes, _, err := c.GetNode().ExecQuery(
ctx,
Expand Down Expand Up @@ -251,3 +392,63 @@ func (c *Chain) GetConsumerChainByChainId(ctx context.Context, chainId string) (
}
return ConsumerChain{}, fmt.Errorf("chain not found")
}

func (c *Chain) GetOptInValidators(ctx context.Context, consumerId string) (OptInValidatorsResponse, error) {
queryRes, _, err := c.GetNode().ExecQuery(
ctx,
"provider", "consumer-opted-in-validators", consumerId,
)
if err != nil {
return OptInValidatorsResponse{}, err
}

var queryResponse OptInValidatorsResponse
err = json.Unmarshal([]byte(queryRes), &queryResponse)
if err != nil {
return OptInValidatorsResponse{}, err
}

return queryResponse, nil
}

func (c *Chain) GetValidatorConsAddress(ctx context.Context, validatorIndex int) (string, error) {
queryRes, _, err := c.Validators[validatorIndex].ExecBin(
ctx,
"comet", "show-address",
)
if err != nil {
return "", err
}

address := strings.TrimSpace(string(queryRes))

return address, nil
}

func (c *Chain) GetValidatorKey(ctx context.Context, validatorIndex int) (string, error) {
queryRes, _, err := c.Validators[validatorIndex].ExecBin(
ctx,
"comet", "show-validator",
)
if err != nil {
return "", err
}

address := strings.TrimSpace(string(queryRes))

return address, nil
}

func getEvtAttribute(events []abci.Event, evtType string, key string) (string, bool) {
for _, evt := range events {
if evt.GetType() == evtType {
for _, attr := range evt.Attributes {
if attr.Key == key {
return attr.Value, true
}
}
}
}

return "", false
}
5 changes: 3 additions & 2 deletions tests/interchain/chainsuite/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ const (
GasPrices = "0.005"
UpgradeDelta = 30
SlashingWindowConsumer = 20
CommitTimeout = 4 * time.Second
CommitTimeout = 2 * time.Second
TotalValidatorFunds = 11_000_000_000
ValidatorFunds = 30_000_000
ValidatorCount = 1
FullNodeCount = 0
ChainSpawnWait = 155 * time.Second
CosmosChainType = "cosmos"
GovModuleAddress = "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn"
GovModuleAddress = "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn"
TestWalletsNumber = 5 // Ensure that test accounts are used in a way that maintains the mutual independence of tests
)

func DefaultConfigToml() testutil.Toml {
Expand Down
31 changes: 27 additions & 4 deletions tests/interchain/chainsuite/query_types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package chainsuite

import "time"
import (
"time"
)

type Metadata struct {
Name string `json:"name"`
Expand Down Expand Up @@ -144,13 +146,34 @@ type InnerSpec struct {
}

type Provider struct {
ClientState ClientState `json:"client_state"`
ConsensusState ConsensusState `json:"consensus_state"`
InitialValSet []interface{} `json:"initial_val_set"`
ClientState ClientState `json:"client_state"`
ConsensusState ConsensusState `json:"consensus_state"`
InitialValSet []InitialValidator `json:"initial_val_set"`
}

type InitialValidator struct {
PubKey PubKey `json:"pub_key"`
Power string `json:"power"`
}

type PubKey struct {
Ed25519 string `json:"ed25519"`
}

type ConsumerGenesisResponse struct {
Params Params `json:"params"`
NewChain bool `json:"new_chain"`
Provider Provider `json:"provider"`
}

type OptInValidatorsResponse struct {
ValidatorsProviderAddresses []string `json:"validators_provider_addresses"`
}

type ValidatorConsumerAddressResponse struct {
ConsumerAddress string `json:"consumer_address"`
}

type ValidatorProviderAddressResponse struct {
ProviderAddress string `json:"provider_address"`
}
Loading

0 comments on commit 79af94b

Please sign in to comment.