From 9b019529b386cb4cc593edfacd7b4df90001beda Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Tue, 23 Apr 2024 10:44:49 -0500 Subject: [PATCH 01/14] init ICS integration --- chain/cosmos/chain_node.go | 42 +++ chain/cosmos/codec.go | 2 + chain/cosmos/cosmos_chain.go | 350 ++++++++++++++++++++- chainset.go | 38 ++- examples/ibc/ics_test.go | 78 +++++ go.mod | 9 +- go.sum | 10 +- go.work | 2 +- go.work.sum | 254 +++++++++++++++ ibc/relayer.go | 6 +- ibc/types.go | 10 + interchain.go | 233 +++++++++++++- local-interchain/go.mod | 9 +- local-interchain/go.sum | 6 +- relayer/docker.go | 8 +- relayer/hermes/hermes_commander.go | 2 +- relayer/hyperspace/hyperspace_commander.go | 2 +- relayer/rly/cosmos_relayer.go | 33 +- 18 files changed, 1047 insertions(+), 47 deletions(-) create mode 100644 examples/ibc/ics_test.go diff --git a/chain/cosmos/chain_node.go b/chain/cosmos/chain_node.go index 23d7e1da7..677960b72 100644 --- a/chain/cosmos/chain_node.go +++ b/chain/cosmos/chain_node.go @@ -11,6 +11,7 @@ import ( "math/rand" "os" "path" + "path/filepath" "strconv" "strings" "sync" @@ -40,6 +41,7 @@ import ( "google.golang.org/grpc/credentials/insecure" icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" + ccvclient "github.com/cosmos/interchain-security/v5/x/ccv/provider/client" "github.com/strangelove-ventures/interchaintest/v8/blockdb" "github.com/strangelove-ventures/interchaintest/v8/dockerutil" "github.com/strangelove-ventures/interchaintest/v8/ibc" @@ -249,6 +251,25 @@ func (tn *ChainNode) OverwriteGenesisFile(ctx context.Context, content []byte) e return nil } +func (tn *ChainNode) PrivValFileContent(ctx context.Context) ([]byte, error) { + fr := dockerutil.NewFileRetriever(tn.logger(), tn.DockerClient, tn.TestName) + gen, err := fr.SingleFileContent(ctx, tn.VolumeName, "config/priv_validator_key.json") + if err != nil { + return nil, fmt.Errorf("getting priv_validator_key.json content: %w", err) + } + + return gen, nil +} + +func (tn *ChainNode) OverwritePrivValFile(ctx context.Context, content []byte) error { + fw := dockerutil.NewFileWriter(tn.logger(), tn.DockerClient, tn.TestName) + if err := fw.WriteFile(ctx, tn.VolumeName, "config/priv_validator_key.json", content); err != nil { + return fmt.Errorf("overwriting priv_validator_key.json: %w", err) + } + + return nil +} + func (tn *ChainNode) copyGentx(ctx context.Context, destVal *ChainNode) error { nid, err := tn.NodeID(ctx) if err != nil { @@ -802,6 +823,27 @@ func (tn *ChainNode) SendIBCTransfer( return tn.ExecTx(ctx, keyName, command...) } +func (tn *ChainNode) ConsumerAdditionProposal(ctx context.Context, keyName string, prop ccvclient.ConsumerAdditionProposalJSON) (string, error) { + propBz, err := json.Marshal(prop) + if err != nil { + return "", err + } + + fileName := "proposal_" + dockerutil.RandLowerCaseLetterString(4) + ".json" + + fw := dockerutil.NewFileWriter(tn.logger(), tn.DockerClient, tn.TestName) + if err := fw.WriteFile(ctx, tn.VolumeName, fileName, propBz); err != nil { + return "", fmt.Errorf("failure writing proposal json: %w", err) + } + + filePath := filepath.Join(tn.HomeDir(), fileName) + + return tn.ExecTx(ctx, keyName, + "gov", "submit-legacy-proposal", "consumer-addition", filePath, + "--gas", "auto", + ) +} + func (tn *ChainNode) GetTransaction(clientCtx client.Context, txHash string) (*sdk.TxResponse, error) { // Retry because sometimes the tx is not committed to state yet. var txResp *sdk.TxResponse diff --git a/chain/cosmos/codec.go b/chain/cosmos/codec.go index 83c0185f7..b297d2729 100644 --- a/chain/cosmos/codec.go +++ b/chain/cosmos/codec.go @@ -25,6 +25,7 @@ import ( transfer "github.com/cosmos/ibc-go/v8/modules/apps/transfer" ibccore "github.com/cosmos/ibc-go/v8/modules/core" ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ccvprovider "github.com/cosmos/interchain-security/v5/x/ccv/provider" ibcwasm "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos/08-wasm-types" ) @@ -50,6 +51,7 @@ func DefaultEncoding() testutil.TestEncodingConfig { ibccore.AppModuleBasic{}, ibctm.AppModuleBasic{}, ibcwasm.AppModuleBasic{}, + ccvprovider.AppModuleBasic{}, ) } diff --git a/chain/cosmos/cosmos_chain.go b/chain/cosmos/cosmos_chain.go index 9ca09faef..e7e4c7e4b 100644 --- a/chain/cosmos/cosmos_chain.go +++ b/chain/cosmos/cosmos_chain.go @@ -5,6 +5,7 @@ import ( "context" "crypto/sha256" "encoding/hex" + "encoding/json" "fmt" "io" "math" @@ -12,8 +13,11 @@ import ( "strconv" "strings" "sync" + "time" sdkmath "cosmossdk.io/math" + abcitypes "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/proto/tendermint/crypto" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" @@ -23,12 +27,19 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" paramsutils "github.com/cosmos/cosmos-sdk/x/params/client/utils" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" // nolint:staticcheck chanTypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ccvconsumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvclient "github.com/cosmos/interchain-security/v5/x/ccv/provider/client" + ccvprovidertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" dockertypes "github.com/docker/docker/api/types" volumetypes "github.com/docker/docker/api/types/volume" "github.com/docker/docker/client" + "github.com/icza/dyno" "github.com/strangelove-ventures/interchaintest/v8/blockdb" wasmtypes "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos/08-wasm-types" "github.com/strangelove-ventures/interchaintest/v8/chain/internal/tendermint" @@ -39,15 +50,22 @@ import ( "golang.org/x/sync/errgroup" ) +var ( + defaultUpgradePath = []string{"upgrade", "upgradedIBCState"} + DefaultProviderUnbondingPeriod = 504 * time.Hour +) + // CosmosChain is a local docker testnet for a Cosmos SDK chain. // Implements the ibc.Chain interface. type CosmosChain struct { testName string cfg ibc.ChainConfig - numValidators int + NumValidators int numFullNodes int Validators ChainNodes FullNodes ChainNodes + Provider *CosmosChain + Consumers []*CosmosChain // Additional processes that need to be run on a per-chain basis. Sidecars SidecarProcesses @@ -108,7 +126,7 @@ func NewCosmosChain(testName string, chainConfig ibc.ChainConfig, numValidators return &CosmosChain{ testName: testName, cfg: chainConfig, - numValidators: numValidators, + NumValidators: numValidators, numFullNodes: numFullNodes, log: log, cdc: cdc, @@ -492,6 +510,15 @@ func (c *CosmosChain) QueryBankMetadata(ctx context.Context, denom string) (*Ban return c.getFullNode().QueryBankMetadata(ctx, denom) } +// ConsumerAdditionProposal submits a legacy governance proposal to add a consumer to the chain. +func (c *CosmosChain) ConsumerAdditionProposal(ctx context.Context, keyName string, prop ccvclient.ConsumerAdditionProposalJSON) (tx TxProposal, _ error) { + txHash, err := c.getFullNode().ConsumerAdditionProposal(ctx, keyName, prop) + if err != nil { + return tx, fmt.Errorf("failed to submit consumer addition proposal: %w", err) + } + return c.txProposal(txHash) +} + func (c *CosmosChain) txProposal(txHash string) (tx TxProposal, _ error) { txResp, err := c.GetTransaction(txHash) if err != nil { @@ -709,13 +736,13 @@ func (c *CosmosChain) initializeChainNodes( c.pullImages(ctx, cli) image := chainCfg.Images[0] - newVals := make(ChainNodes, c.numValidators) + newVals := make(ChainNodes, c.NumValidators) copy(newVals, c.Validators) newFullNodes := make(ChainNodes, c.numFullNodes) copy(newFullNodes, c.FullNodes) eg, egCtx := errgroup.WithContext(ctx) - for i := len(c.Validators); i < c.numValidators; i++ { + for i := len(c.Validators); i < c.NumValidators; i++ { i := i eg.Go(func() error { val, err := c.NewChainNode(egCtx, testName, cli, networkID, image, true, i) @@ -1022,6 +1049,321 @@ func (c *CosmosChain) Start(testName string, ctx context.Context, additionalGene return testutil.WaitForBlocks(ctx, 2, c.getFullNode()) } +// Bootstraps the provider chain and starts it from genesis +func (c *CosmosChain) StartProvider(testName string, ctx context.Context, additionalGenesisWallets ...ibc.WalletAmount) error { + existingFunc := c.cfg.ModifyGenesis + c.cfg.ModifyGenesis = func(cc ibc.ChainConfig, b []byte) ([]byte, error) { + var err error + b, err = ModifyGenesis([]GenesisKV{ + NewGenesisKV("app_state.gov.params.voting_period", "10s"), + NewGenesisKV("app_state.gov.params.max_deposit_period", "10s"), + NewGenesisKV("app_state.gov.params.min_deposit.0.denom", c.cfg.Denom), + })(cc, b) + if err != nil { + return nil, err + } + if existingFunc != nil { + return existingFunc(cc, b) + } + return b, nil + } + + const proposerKeyName = "proposer" + if err := c.CreateKey(ctx, proposerKeyName); err != nil { + return fmt.Errorf("failed to add proposer key: %s", err) + } + + proposerAddr, err := c.getFullNode().AccountKeyBech32(ctx, proposerKeyName) + if err != nil { + return fmt.Errorf("failed to get proposer key: %s", err) + } + + proposer := ibc.WalletAmount{ + Address: proposerAddr, + Denom: c.cfg.Denom, + Amount: sdkmath.NewInt(10_000_000_000_000), + } + + additionalGenesisWallets = append(additionalGenesisWallets, proposer) + + if err := c.Start(testName, ctx, additionalGenesisWallets...); err != nil { + return err + } + + for _, consumer := range c.Consumers { + prop := ccvclient.ConsumerAdditionProposalJSON{ + Title: fmt.Sprintf("Addition of %s consumer chain", consumer.cfg.Name), + Summary: "Proposal to add new consumer chain", + ChainId: consumer.cfg.ChainID, + InitialHeight: clienttypes.Height{RevisionNumber: clienttypes.ParseChainID(consumer.cfg.ChainID), RevisionHeight: 1}, + GenesisHash: []byte("gen_hash"), + BinaryHash: []byte("bin_hash"), + SpawnTime: time.Now(), // Client on provider tracking consumer will be created as soon as proposal passes + + // TODO fetch or default variables + BlocksPerDistributionTransmission: 1000, + CcvTimeoutPeriod: 2419200000000000, + TransferTimeoutPeriod: 3600000000000, + ConsumerRedistributionFraction: "0.75", + HistoricalEntries: 10000, + UnbondingPeriod: 1728000000000000, + Deposit: "100000000" + c.cfg.Denom, + } + + height, err := c.Height(ctx) + if err != nil { + return fmt.Errorf("failed to query provider height before consumer addition proposal: %w", err) + } + + propTx, err := c.ConsumerAdditionProposal(ctx, proposerKeyName, prop) + if err != nil { + return err + } + + if err := c.VoteOnProposalAllValidators(ctx, propTx.ProposalID, ProposalVoteYes); err != nil { + return err + } + + // propTx.ProposalID + propID, err := strconv.ParseUint(propTx.ProposalID, 10, 64) + if err != nil { + return fmt.Errorf("failed to parse proposal id: %w", err) + } + + _, err = PollForProposalStatus(ctx, c, height, height+10, propID, govv1beta1.StatusPassed) + if err != nil { + return fmt.Errorf("proposal status did not change to passed in expected number of blocks: %w", err) + } + } + + return nil +} + +// Bootstraps the consumer chain and starts it from genesis +func (c *CosmosChain) StartConsumer(testName string, ctx context.Context, additionalGenesisWallets ...ibc.WalletAmount) error { + chainCfg := c.Config() + + configFileOverrides := chainCfg.ConfigFileOverrides + + eg := new(errgroup.Group) + // Initialize validators and fullnodes. + for _, v := range c.Nodes() { + v := v + eg.Go(func() error { + if err := v.InitFullNodeFiles(ctx); err != nil { + return err + } + for configFile, modifiedConfig := range configFileOverrides { + modifiedToml, ok := modifiedConfig.(testutil.Toml) + if !ok { + return fmt.Errorf("provided toml override for file %s is of type (%T). Expected (DecodedToml)", configFile, modifiedConfig) + } + if err := testutil.ModifyTomlConfigFile( + ctx, + v.logger(), + v.DockerClient, + v.TestName, + v.VolumeName, + configFile, + modifiedToml, + ); err != nil { + return err + } + } + return nil + }) + } + + // wait for this to finish + if err := eg.Wait(); err != nil { + return err + } + + // Copy provider priv val keys to these nodes + for i, val := range c.Provider.Validators { + privVal, err := val.PrivValFileContent(ctx) + if err != nil { + return err + } + if err := c.Validators[i].OverwritePrivValFile(ctx, privVal); err != nil { + return err + } + } + + if c.cfg.PreGenesis != nil { + err := c.cfg.PreGenesis(chainCfg) + if err != nil { + return err + } + } + + validator0 := c.Validators[0] + + for _, wallet := range additionalGenesisWallets { + if err := validator0.AddGenesisAccount(ctx, wallet.Address, []types.Coin{{Denom: wallet.Denom, Amount: sdkmath.NewInt(wallet.Amount.Int64())}}); err != nil { + return err + } + } + + providerHeight, err := c.Provider.Height(ctx) + if err != nil { + return fmt.Errorf("failed to query provider height") + } + providerHeightInt64 := int64(providerHeight) + + block, err := c.Provider.getFullNode().Client.Block(ctx, &providerHeightInt64) + if err != nil { + return fmt.Errorf("failed to query provider block to initialize consumer client") + } + + genbz, err := validator0.GenesisFileContent(ctx) + if err != nil { + return err + } + + // populate genesis file ccvconsumer module app_state. + // fetch provider latest block (timestamp, root.hash, and next_validators_hash) to populate provider_consensus_state + // populate provider_client_state with trusting and unbonding periods, latest_height.revision_height of height which is used for consensus state + // populate initial_val_set with provider val pubkeys and power + + nextValidatorsHash := block.Block.NextValidatorsHash + timestamp := block.Block.Time + rootHash := block.Block.AppHash + + page := int(1) + perPage := int(1000) + providerVals, err := c.Provider.getFullNode().Client.Validators(ctx, &providerHeightInt64, &page, &perPage) + if err != nil { + return fmt.Errorf("failed to get provider validators: %w", err) + } + + initialVals := make([]abcitypes.ValidatorUpdate, len(providerVals.Validators)) + for i, val := range providerVals.Validators { + initialVals[i] = abcitypes.ValidatorUpdate{ + PubKey: crypto.PublicKey{Sum: &crypto.PublicKey_Ed25519{Ed25519: val.PubKey.Bytes()}}, + Power: val.VotingPower, + } + } + + providerCfg := c.Provider.Config() + + clientState := ibctmtypes.NewClientState( + providerCfg.ChainID, + ibctmtypes.DefaultTrustLevel, + DefaultProviderUnbondingPeriod/2, + DefaultProviderUnbondingPeriod, // Needs to match provider unbonding period + ccvprovidertypes.DefaultMaxClockDrift, + clienttypes.Height{ + RevisionHeight: uint64(providerHeight), + RevisionNumber: clienttypes.ParseChainID(providerCfg.ChainID), + }, + commitmenttypes.GetSDKSpecs(), + defaultUpgradePath, + ) + + root := commitmenttypes.MerkleRoot{ + Hash: rootHash, + } + + consensusState := ibctmtypes.NewConsensusState(timestamp, root, nextValidatorsHash) + + ccvState := ccvconsumertypes.NewInitialGenesisState( + clientState, + consensusState, + initialVals, + ccvconsumertypes.DefaultGenesisState().GetParams(), + ) + + ccvState.Params.Enabled = true + + ccvStateMarshaled, err := c.cfg.EncodingConfig.Codec.MarshalJSON(ccvState) + c.log.Info("HERE STATE!", zap.String("GEN", string(ccvStateMarshaled))) + if err != nil { + return fmt.Errorf("failed to marshal ccv state to json: %w", err) + } + + var ccvStateUnmarshaled interface{} + if err := json.Unmarshal(ccvStateMarshaled, &ccvStateUnmarshaled); err != nil { + return fmt.Errorf("failed to unmarshal ccv state json: %w", err) + } + + var genesisJson interface{} + if err := json.Unmarshal(genbz, &genesisJson); err != nil { + return fmt.Errorf("failed to unmarshal genesis json: %w", err) + } + + if err := dyno.Set(genesisJson, ccvStateUnmarshaled, "app_state", "ccvconsumer"); err != nil { + return fmt.Errorf("failed to populate ccvconsumer genesis state: %w", err) + } + + if genbz, err = json.Marshal(genesisJson); err != nil { + return fmt.Errorf("failed to marshal genesis bytes to json: %w", err) + } + + genbz = bytes.ReplaceAll(genbz, []byte(`"stake"`), []byte(fmt.Sprintf(`"%s"`, chainCfg.Denom))) + + if c.cfg.ModifyGenesis != nil { + genbz, err = c.cfg.ModifyGenesis(chainCfg, genbz) + if err != nil { + return err + } + } + + // Provide EXPORT_GENESIS_FILE_PATH and EXPORT_GENESIS_CHAIN to help debug genesis file + exportGenesis := os.Getenv("EXPORT_GENESIS_FILE_PATH") + exportGenesisChain := os.Getenv("EXPORT_GENESIS_CHAIN") + if exportGenesis != "" && exportGenesisChain == c.cfg.Name { + c.log.Debug("Exporting genesis file", + zap.String("chain", exportGenesisChain), + zap.String("path", exportGenesis), + ) + _ = os.WriteFile(exportGenesis, genbz, 0600) + } + + chainNodes := c.Nodes() + + for _, cn := range chainNodes { + if err := cn.OverwriteGenesisFile(ctx, genbz); err != nil { + return err + } + } + + if err := chainNodes.LogGenesisHashes(ctx); err != nil { + return err + } + + eg, egCtx := errgroup.WithContext(ctx) + for _, n := range chainNodes { + n := n + eg.Go(func() error { + return n.CreateNodeContainer(egCtx) + }) + } + if err := eg.Wait(); err != nil { + return err + } + + peers := chainNodes.PeerString(ctx) + + eg, egCtx = errgroup.WithContext(ctx) + for _, n := range chainNodes { + n := n + c.log.Info("Starting container", zap.String("container", n.Name())) + eg.Go(func() error { + if err := n.SetPeers(egCtx, peers); err != nil { + return err + } + return n.StartContainer(egCtx) + }) + } + if err := eg.Wait(); err != nil { + return err + } + + // Wait for 5 blocks before considering the chains "started" + return testutil.WaitForBlocks(ctx, 5, c.getFullNode()) +} + // Height implements ibc.Chain func (c *CosmosChain) Height(ctx context.Context) (int64, error) { return c.getFullNode().Height(ctx) diff --git a/chainset.go b/chainset.go index 9294302d2..d5fd79bb3 100644 --- a/chainset.go +++ b/chainset.go @@ -10,6 +10,7 @@ import ( "github.com/docker/docker/client" "github.com/strangelove-ventures/interchaintest/v8/blockdb" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/ibc" "go.uber.org/multierr" "go.uber.org/zap" @@ -106,15 +107,50 @@ func (cs *chainSet) Start(ctx context.Context, testName string, additionalGenesi for c := range cs.chains { c := c + if cosmosChain, ok := c.(*cosmos.CosmosChain); ok && cosmosChain.Provider != nil { + // wait for provider chains to be started up first + continue + } eg.Go(func() error { + chainCfg := c.Config() + if cosmosChain, ok := c.(*cosmos.CosmosChain); ok { + if len(cosmosChain.Consumers) > 0 { + // this is a provider chain + if err := cosmosChain.StartProvider(testName, egCtx, additionalGenesisWallets[c]...); err != nil { + return fmt.Errorf("failed to start provider chain %s: %w", chainCfg.Name, err) + } + return nil + } + } + + // standard chain startup if err := c.Start(testName, egCtx, additionalGenesisWallets[c]...); err != nil { - return fmt.Errorf("failed to start chain %s: %w", c.Config().Name, err) + return fmt.Errorf("failed to start chain %s: %w", chainCfg.Name, err) } return nil }) } + if err := eg.Wait(); err != nil { + return err + } + + eg, egCtx = errgroup.WithContext(ctx) + // Now startup any consumer chains + for c := range cs.chains { + c := c + if cosmosChain, ok := c.(*cosmos.CosmosChain); ok && cosmosChain.Provider != nil { + eg.Go(func() error { + // this is a consumer chain + if err := cosmosChain.StartConsumer(testName, egCtx, additionalGenesisWallets[c]...); err != nil { + return fmt.Errorf("failed to start consumer chain %s: %w", c.Config().Name, err) + } + + return nil + }) + } + } return eg.Wait() } diff --git a/examples/ibc/ics_test.go b/examples/ibc/ics_test.go new file mode 100644 index 000000000..d64f1750d --- /dev/null +++ b/examples/ibc/ics_test.go @@ -0,0 +1,78 @@ +package ibc_test + +import ( + "context" + "fmt" + "testing" + "time" + + interchaintest "github.com/strangelove-ventures/interchaintest/v8" + "github.com/strangelove-ventures/interchaintest/v8/ibc" + "github.com/strangelove-ventures/interchaintest/v8/testreporter" + "github.com/strangelove-ventures/interchaintest/v8/testutil" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zaptest" +) + +// This tests Cosmos Interchain Security, spinning up a provider and a single consumer chain. +func TestICS(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode") + } + + t.Parallel() + + ctx := context.Background() + + // Chain Factory + cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ + {Name: "ics-provider", Version: "v3.1.0", ChainConfig: ibc.ChainConfig{GasAdjustment: 1.5}}, + {Name: "neutron", Version: "v2.0.2"}, // ics-consumer + }) + + chains, err := cf.Chains(t.Name()) + require.NoError(t, err) + provider, consumer := chains[0], chains[1] + + // Relayer Factory + client, network := interchaintest.DockerSetup(t) + + r := interchaintest.NewBuiltinRelayerFactory( + ibc.CosmosRly, + zaptest.NewLogger(t), + ).Build(t, client, network) + + // Prep Interchain + const ibcPath = "ics-path" + ic := interchaintest.NewInterchain(). + AddChain(provider). + AddChain(consumer). + AddRelayer(r, "relayer"). + AddProviderConsumerLink(interchaintest.ProviderConsumerLink{ + Provider: provider, + Consumer: consumer, + Relayer: r, + Path: ibcPath, + }) + + // Log location + f, err := interchaintest.CreateLogFile(fmt.Sprintf("%d.json", time.Now().Unix())) + require.NoError(t, err) + // Reporter/logs + rep := testreporter.NewReporter(f) + eRep := rep.RelayerExecReporter(t) + + // Build interchain + err = ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ + TestName: t.Name(), + Client: client, + NetworkID: network, + BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), + + SkipPathCreation: false, + }) + require.NoError(t, err, "failed to build interchain") + + err = testutil.WaitForBlocks(ctx, 10, provider, consumer) + require.NoError(t, err, "failed to wait for blocks") +} diff --git a/go.mod b/go.mod index 6f56bd01f..bacd2d597 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module github.com/strangelove-ventures/interchaintest/v8 -go 1.21 - -toolchain go1.21.0 +go 1.22.2 require ( cosmossdk.io/math v1.3.0 @@ -22,6 +20,7 @@ require ( github.com/cosmos/gogoproto v1.4.11 github.com/cosmos/ibc-go/modules/capability v1.0.0 github.com/cosmos/ibc-go/v8 v8.1.0 + github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240423100140-781f691e7f89 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.1 github.com/docker/docker v24.0.7+incompatible @@ -64,6 +63,7 @@ require ( cosmossdk.io/depinject v1.0.0-alpha.4 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.3.1 // indirect + cosmossdk.io/x/evidence v0.1.0 // indirect cosmossdk.io/x/tx v0.13.0 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -85,12 +85,13 @@ require ( github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chzyer/readline v1.5.1 // indirect + github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877 // indirect github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v1.1.0 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft-db v0.9.1 // indirect + github.com/cometbft/cometbft-db v0.10.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-db v1.0.0 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.4 // indirect diff --git a/go.sum b/go.sum index 370368215..2eee0401a 100644 --- a/go.sum +++ b/go.sum @@ -348,8 +348,8 @@ github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= -github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877 h1:1MLK4YpFtIEo3ZtMA5C795Wtv5VuUnrXX7mQG+aHg6o= +github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= @@ -363,8 +363,8 @@ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1: github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/cometbft/cometbft v0.38.5 h1:4lOcK5VTPrfbLOhNHmPYe6c7eDXHtBdMCQuKbAfFJdU= github.com/cometbft/cometbft v0.38.5/go.mod h1:0tqKin+KQs8zDwzYD8rPHzSBIDNPuB4NrwwGDNb/hUg= -github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= -github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= +github.com/cometbft/cometbft-db v0.10.0 h1:VMBQh88zXn64jXVvj39tlu/IgsGR84T7ImjS523DCiU= +github.com/cometbft/cometbft-db v0.10.0/go.mod h1:7RR7NRv99j7keWJ5IkE9iZibUTKYdtepXTp7Ra0FxKk= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -397,6 +397,8 @@ github.com/cosmos/ibc-go/v8 v8.1.0 h1:pf1106wl0Cf+p1+FjXzV6odlS9DnqVunPVWCH1Uz+l github.com/cosmos/ibc-go/v8 v8.1.0/go.mod h1:o1ipS95xpdjqNcB8Drq0eI3Sn4FRLigjll42ec1ECuU= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= +github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240423100140-781f691e7f89 h1:VVn2oLuiGmQIC3ovazpI0Z8R3zgXhgAx/lfOT5EfNHY= +github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240423100140-781f691e7f89/go.mod h1:c4oYjNwdfPKAhxzkwzTkkWROXKeUNPvc4VJHyNWrRU8= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= diff --git a/go.work b/go.work index e9cc53592..17e01f5e5 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.21 +go 1.22.2 use ( . diff --git a/go.work.sum b/go.work.sum index b00ad5933..10878a8b7 100644 --- a/go.work.sum +++ b/go.work.sum @@ -387,6 +387,7 @@ cosmossdk.io/log v1.3.0/go.mod h1:HIDyvWLqZe2ovlWabsDN4aPMpY/nUEquAhgfTf2ZzB8= cosmossdk.io/store v1.0.0/go.mod h1:ABMprwjvx6IpMp8l06TwuMrj6694/QP5NIW+X6jaTYc= cosmossdk.io/tools/confix v0.0.0-20230818115413-c402c51a1508/go.mod h1:qcJ1zwLIMefpDHZuYSa73yBe/k5HyQ5H1Jg9PWv30Ts= cosmossdk.io/tools/confix v0.1.0/go.mod h1:TdXKVYs4gEayav5wM+JHT+kTU2J7fozFNqoVaN+8CdY= +cosmossdk.io/tools/confix v0.1.1/go.mod h1:nQVvP1tHsGXS83PonPVWJtSbddIqyjEw99L4M3rPJyQ= cosmossdk.io/x/nft v0.0.0-20230630152705-9f4a4e416f85/go.mod h1:arLtdZiIFmnqTNWSk2tFtSodGDKTmr+Q0fGmF5wpn2c= cosmossdk.io/x/upgrade v0.1.0/go.mod h1:/6jjNGbiPCNtmA1N+rBtP601sr0g4ZXuj3yC6ClPCGY= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= @@ -662,4 +663,257 @@ github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= +github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw= +github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ= +github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4= +github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA= +github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= +github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig= +github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= +github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= +github.com/golangci/golangci-lint v1.52.0/go.mod h1:wlTh+d/oVlgZC2yCe6nlxrxNAnuhEQC0Zdygoh72Uak= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= +github.com/golangci/misspell v0.4.0/go.mod h1:W6O/bwV6lGDxUCChm2ykw9NQdd5bYd1Xkjo88UcWyJc= +github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= +github.com/google/go-containerregistry v0.13.0/go.mod h1:J9FQ+eSS4a1aC2GNZxvNpbWhgp0487v+cgiilB4FqDo= +github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= +github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= +github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= +github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= +github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= +github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/guptarohit/asciigraph v0.5.5/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= +github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU= +github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/hydrogen18/memlistener v1.0.0/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= +github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/informalsystems/itf-go v0.0.1/go.mod h1:wgqaQ/yl2kbNlgw6GaleuHEefpZvkZo6Hc0jc8cGG9M= +github.com/informalsystems/tm-load-test v1.3.0/go.mod h1:OQ5AQ9TbT5hKWBNIwsMjn6Bf4O0U4b1kRc+0qZlQJKw= +github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= +github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek= +github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= +github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw= +github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= +github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= +github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= +github.com/junk1tm/musttag v0.5.0/go.mod h1:PcR7BA+oREQYvHwgjIDmw3exJeds5JzRcvEJTfjrA0M= +github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= +github.com/kataras/golog v0.1.8/go.mod h1:rGPAin4hYROfk1qT9wZP6VY2rsb4zzc37QpdPjdkqVw= +github.com/kataras/iris/v12 v12.2.0/go.mod h1:BLzBpEunc41GbE68OUaQlqX4jzi791mx5HU04uPb90Y= +github.com/kataras/pio v0.0.11/go.mod h1:38hH6SWH6m4DKSYmRhlrCJ5WItwWgCVrTNU62XZyUvI= +github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= +github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= +github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= +github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= +github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= +github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= +github.com/labstack/echo/v4 v4.10.0/go.mod h1:S/T/5fy/GigaXnHTkh0ZGe4LpkkQysvRjFMSUTkDRNQ= +github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= +github.com/ldez/tagliatelle v0.4.0/go.mod h1:mNtTfrHy2haaBAw+VT7IBV6VXBThS7TCreYWbBcJ87I= +github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= +github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= +github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= +github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= +github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= +github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= +github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= +github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= +github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= +github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= +github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= +github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= +github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= +github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= +github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= +github.com/mgechev/revive v1.3.1/go.mod h1:YlD6TTWl2B8A103R9KWJSPVI9DrEf+oqr15q21Ld+5I= +github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4= +github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/moricho/tparallel v0.3.0/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= +github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= +github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= +github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= +github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= +github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= +github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/nats-io/jwt/v2 v2.0.3/go.mod h1:VRP+deawSXyhNjXmxPCHskrR6Mq50BqpEI5SEcNiGlY= +github.com/nats-io/nats-server/v2 v2.5.0/go.mod h1:Kj86UtrXAL6LwYRA6H4RqzkHhK0Vcv2ZnKD5WbQ1t3g= +github.com/nats-io/nats.go v1.31.0/go.mod h1:di3Bm5MLsoB4Bx61CBTsxuarI36WbhAwOm8QrW39+i8= +github.com/nats-io/nkeys v0.4.6/go.mod h1:4DxZNzenSVd1cYQoAa8948QY3QDjrHfcfVADymtkpts= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= +github.com/nishanths/exhaustive v0.9.5/go.mod h1:IbwrGdVMizvDcIxPYGVdQn5BqWJaOwpCvg4RGb8r/TA= +github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= +github.com/nunnatsa/ginkgolinter v0.9.0/go.mod h1:FHaMLURXP7qImeH6bvxWJUpyH+2tuqe5j4rW1gxJRmI= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= +github.com/oxyno-zeta/gomock-extra-matcher v1.2.0/go.mod h1:S0r7HmKeCGsHmvIVFMjKWwswb4+30nCNWbXRMBVPkaU= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= +github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM= +github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo= +github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= +github.com/polyfloyd/go-errorlint v1.4.5/go.mod h1:sIZEbFoDOCnTYYZoVkjc4hTnM459tuWA9H/EkdXwsKk= +github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY= +github.com/quasilyte/go-ruleguard v0.4.0/go.mod h1:Eu76Z/R8IXtViWUIHkE3p8gdH3/PKk1eh3YGfaEof10= +github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= +github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= +github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= +github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= +github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50= +github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ= +github.com/sagikazarmark/crypt v0.17.0/go.mod h1:SMtHTvdmsZMuY/bpZoqokSoChIrcJ/epOxZN58PbZDg= +github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= +github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/securego/gosec/v2 v2.15.0/go.mod h1:VOjTrZOkUtSDt2QLSJmQBMWnvwiQPEjg0l+5juIqGk8= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= +github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= +github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= +github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= +github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= +github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= +github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= +github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= +github.com/tdewolff/minify/v2 v2.12.4/go.mod h1:h+SRvSIX3kwgwTFOpSckvSxgax3uy8kZTSF1Ojrr3bk= +github.com/tdewolff/parse/v2 v2.6.4/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= +github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= +github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= +github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= +github.com/tomarrell/wrapcheck/v2 v2.8.1/go.mod h1:/n2Q3NZ4XFT50ho6Hbxg+RV1uyo2Uow/Vdm9NQcl5SE= +github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/vektra/mockery/v2 v2.23.1/go.mod h1:Zh3Kv1ckKs6FokhlVLcCu6UTyzfS3M8mpROz1lBNp+w= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= +github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= +github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= +gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= +go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= +go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= +go.etcd.io/etcd/client/v2 v2.305.10/go.mod h1:m3CKZi69HzilhVqtPDcjhSGp+kA1OmbNn0qamH80xjA= +go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= +go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= +go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= +go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= +golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc= +golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ= +gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20231212172506-995d672761c0/go.mod h1:guYXGPwC6jwxgWKW5Y405fKWOFNwlvUlUnzyp9i0uqo= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= +mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= +mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RFiZMMsLVL+A96Nvptar8Fj71is= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/ibc/relayer.go b/ibc/relayer.go index 5f49229c0..081490a2b 100644 --- a/ibc/relayer.go +++ b/ibc/relayer.go @@ -41,8 +41,8 @@ type Relayer interface { // setup channels, connections, and clients LinkPath(ctx context.Context, rep RelayerExecReporter, pathName string, channelOpts CreateChannelOptions, clientOptions CreateClientOptions) error - // update path channel filter - UpdatePath(ctx context.Context, rep RelayerExecReporter, pathName string, filter ChannelFilter) error + // update path channel filter or src/dst clients, conns, or chain IDs + UpdatePath(ctx context.Context, rep RelayerExecReporter, pathName string, opts PathUpdateOptions) error // update clients, such as after new genesis UpdateClients(ctx context.Context, rep RelayerExecReporter, pathName string) error @@ -80,7 +80,7 @@ type Relayer interface { // CreateClient performs the client handshake steps necessary for creating a light client // on src that tracks the state of dst. // Unlike CreateClients, this only creates the client on the destination chain - CreateClient(ctx context.Context, rep RelayerExecReporter, srcChainID, dstChainID, pathName string, opts CreateClientOptions) error + CreateClient(ctx context.Context, rep RelayerExecReporter, srcChainID string, dstChainID string, pathName string, opts CreateClientOptions) error // CreateConnections performs the connection handshake steps necessary for creating a connection // between the src and dst chains. diff --git a/ibc/types.go b/ibc/types.go index 25b9abbcb..a16a34607 100644 --- a/ibc/types.go +++ b/ibc/types.go @@ -380,3 +380,13 @@ type ChannelFilter struct { Rule string ChannelList []string } + +type PathUpdateOptions struct { + ChannelFilter *ChannelFilter + SrcClientID *string + SrcConnID *string + SrcChainID *string + DstClientID *string + DstConnID *string + DstChainID *string +} diff --git a/interchain.go b/interchain.go index 33fa5ee57..f3d4e012a 100644 --- a/interchain.go +++ b/interchain.go @@ -6,6 +6,7 @@ import ( "cosmossdk.io/math" "github.com/docker/docker/client" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/ibc" "github.com/strangelove-ventures/interchaintest/v8/testreporter" "go.uber.org/zap" @@ -26,6 +27,9 @@ type Interchain struct { // Key: relayer and path name; Value: the two chains being linked. links map[relayerPath]interchainLink + // Key: relayer and path name; Value: the provider and consumer chain link. + providerConsumerLinks map[relayerPath]providerConsumerLink + // Set to true after Build is called once. built bool @@ -53,6 +57,20 @@ type interchainLink struct { createChannelOpts ibc.CreateChannelOptions } +type providerConsumerLink struct { + provider, consumer ibc.Chain + + // If set, these options will be used when creating the client in the path link step. + // If a zero value initialization is used, e.g. CreateClientOptions{}, + // then the default values will be used via ibc.DefaultClientOpts. + createClientOpts ibc.CreateClientOptions + + // If set, these options will be used when creating the channel in the path link step. + // If a zero value initialization is used, e.g. CreateChannelOptions{}, + // then the default values will be used via ibc.DefaultChannelOpts. + createChannelOpts ibc.CreateChannelOptions +} + // NewInterchain returns a new Interchain. // // Typical usage involves multiple calls to AddChain, one or more calls to AddRelayer, @@ -64,7 +82,8 @@ func NewInterchain() *Interchain { chains: make(map[ibc.Chain]string), relayers: make(map[ibc.Relayer]string), - links: make(map[relayerPath]interchainLink), + links: make(map[relayerPath]interchainLink), + providerConsumerLinks: make(map[relayerPath]providerConsumerLink), } } @@ -131,6 +150,43 @@ func (ic *Interchain) AddRelayer(relayer ibc.Relayer, name string) *Interchain { return ic } +// AddLink adds the given link to the Interchain. +// If any validation fails, AddLink panics. +func (ic *Interchain) AddProviderConsumerLink(link ProviderConsumerLink) *Interchain { + if _, exists := ic.chains[link.Provider]; !exists { + cfg := link.Provider.Config() + panic(fmt.Errorf("chain with name=%s and id=%s was never added to Interchain", cfg.Name, cfg.ChainID)) + } + if _, exists := ic.chains[link.Consumer]; !exists { + cfg := link.Consumer.Config() + panic(fmt.Errorf("chain with name=%s and id=%s was never added to Interchain", cfg.Name, cfg.ChainID)) + } + if _, exists := ic.relayers[link.Relayer]; !exists { + panic(fmt.Errorf("relayer %v was never added to Interchain", link.Relayer)) + } + + if link.Provider == link.Consumer { + panic(fmt.Errorf("chains must be different (both were %v)", link.Provider)) + } + + key := relayerPath{ + Relayer: link.Relayer, + Path: link.Path, + } + + if _, exists := ic.providerConsumerLinks[key]; exists { + panic(fmt.Errorf("relayer %q already has a path named %q", key.Relayer, key.Path)) + } + + ic.providerConsumerLinks[key] = providerConsumerLink{ + provider: link.Provider, + consumer: link.Consumer, + createChannelOpts: link.CreateChannelOpts, + createClientOpts: link.CreateClientOpts, + } + return ic +} + // InterchainLink describes a link between two chains, // by specifying the chain names, the relayer name, // and the name of the path to create. @@ -155,6 +211,26 @@ type InterchainLink struct { CreateChannelOpts ibc.CreateChannelOptions } +type ProviderConsumerLink struct { + Provider, Consumer ibc.Chain + + // Relayer to use for link. + Relayer ibc.Relayer + + // Name of path to create. + Path string + + // If set, these options will be used when creating the client in the path link step. + // If a zero value initialization is used, e.g. CreateClientOptions{}, + // then the default values will be used via ibc.DefaultClientOpts. + CreateClientOpts ibc.CreateClientOptions + + // If set, these options will be used when creating the channel in the path link step. + // If a zero value initialization is used, e.g. CreateChannelOptions{}, + // then the default values will be used via ibc.DefaultChannelOpts. + CreateChannelOpts ibc.CreateChannelOptions +} + // AddLink adds the given link to the Interchain. // If any validation fails, AddLink panics. func (ic *Interchain) AddLink(link InterchainLink) *Interchain { @@ -227,6 +303,15 @@ func (ic *Interchain) Build(ctx context.Context, rep *testreporter.RelayerExecRe } ic.cs = newChainSet(ic.log, chains) + // Consumer chains need to have the same number of validators as their provider. + // Consumer also needs reference to its provider chain. + for _, providerConsumerLink := range ic.providerConsumerLinks { + provider, consumer := providerConsumerLink.provider.(*cosmos.CosmosChain), providerConsumerLink.consumer.(*cosmos.CosmosChain) + consumer.NumValidators = provider.NumValidators + consumer.Provider = provider + provider.Consumers = append(provider.Consumers, consumer) + } + // Initialize the chains (pull docker images, etc.). if err := ic.cs.Initialize(ctx, opts.TestName, opts.Client, opts.NetworkID); err != nil { return fmt.Errorf("failed to initialize chains: %w", err) @@ -251,15 +336,6 @@ func (ic *Interchain) Build(ctx context.Context, rep *testreporter.RelayerExecRe return fmt.Errorf("failed to track blocks: %w", err) } - // If any configured chain is an instance of Penumbra we need to initialize new pclientd instances for the - // newly created faucet account. - for c := range ic.chains { - err = CreatePenumbraClient(ctx, c, FaucetAccountKeyName) - if err != nil { - return err - } - } - if err := ic.configureRelayerKeys(ctx, rep); err != nil { // Error already wrapped with appropriate detail. return err @@ -286,9 +362,135 @@ func (ic *Interchain) Build(ctx context.Context, rep *testreporter.RelayerExecRe } } + // For every provider consumer link, teach the relayer about the link and create the link. + for rp, link := range ic.providerConsumerLinks { + rp := rp + link := link + p := link.provider + c := link.consumer + + if err := rp.Relayer.GeneratePath(ctx, rep, c.Config().ChainID, p.Config().ChainID, rp.Path); err != nil { + return fmt.Errorf( + "failed to generate path %s on relayer %s between chains %s and %s: %w", + rp.Path, rp.Relayer, ic.chains[p], ic.chains[c], err, + ) + } + } + + var eg errgroup.Group + + // Now link the paths in parallel + // Creates clients, connections, and channels for each link/path. + for rp, link := range ic.providerConsumerLinks { + rp := rp + link := link + p := link.provider + c := link.consumer + eg.Go(func() error { + // If the user specifies a zero value CreateClientOptions struct then we fall back to the default + // client options. + if link.createClientOpts == (ibc.CreateClientOptions{}) { + link.createClientOpts = ibc.DefaultClientOpts() + } + + // Check that the client creation options are valid and fully specified. + if err := link.createClientOpts.Validate(); err != nil { + return err + } + + // If the user specifies a zero value CreateChannelOptions struct then we fall back to the default + // channel options for an ics20 fungible token transfer channel. + if link.createChannelOpts == (ibc.CreateChannelOptions{}) { + link.createChannelOpts = ibc.DefaultChannelOpts() + } + + // Check that the channel creation options are valid and fully specified. + if err := link.createChannelOpts.Validate(); err != nil { + return err + } + + consumerClients, err := rp.Relayer.GetClients(ctx, rep, c.Config().ChainID) + if err != nil { + return fmt.Errorf( + "failed to fetch consumer clients while linking path %s on relayer %s between chains %s and %s: %w", + rp.Path, rp.Relayer, ic.chains[p], ic.chains[c], err, + ) + } + var consumerClient *ibc.ClientOutput + for _, client := range consumerClients { + if client.ClientState.ChainID == p.Config().ChainID { + consumerClient = client + break + } + } + if consumerClient == nil { + return fmt.Errorf( + "consumer chain %s does not have a client tracking the provider chain %s for path %s on relayer %s", + ic.chains[c], ic.chains[p], rp.Path, rp.Relayer, + ) + } + consumerClientID := consumerClients[0].ClientID + + providerClients, err := rp.Relayer.GetClients(ctx, rep, p.Config().ChainID) + if err != nil { + return fmt.Errorf( + "failed to fetch provider clients while linking path %s on relayer %s between chains %s and %s: %w", + rp.Path, rp.Relayer, ic.chains[p], ic.chains[c], err, + ) + } + var providerClient *ibc.ClientOutput + for _, client := range providerClients { + if client.ClientState.ChainID == c.Config().ChainID { + providerClient = client + break + } + } + if providerClient == nil { + return fmt.Errorf( + "provider chain %s does not have a client tracking the consumer chain %s for path %s on relayer %s", + ic.chains[p], ic.chains[c], rp.Path, rp.Relayer, + ) + } + providerClientID := providerClients[0].ClientID + + // Update relayer config with client IDs + if err := rp.Relayer.UpdatePath(ctx, rep, rp.Path, ibc.PathUpdateOptions{ + SrcClientID: &consumerClientID, + DstClientID: &providerClientID, + }); err != nil { + return fmt.Errorf( + "failed to update path %s on relayer %s between chains %s and %s: %w", + rp.Path, rp.Relayer, ic.chains[p], ic.chains[c], err, + ) + } + + // Connection handshake + if err := rp.Relayer.CreateConnections(ctx, rep, rp.Path); err != nil { + return fmt.Errorf( + "failed to create connections on path %s on relayer %s between chains %s and %s: %w", + rp.Path, rp.Relayer, ic.chains[p], ic.chains[c], err, + ) + } + + // Create the provider/consumer channel for relaying val set updates + if err := rp.Relayer.CreateChannel(ctx, rep, rp.Path, ibc.CreateChannelOptions{ + SourcePortName: "consumer", + DestPortName: "provider", + Order: ibc.Ordered, + Version: "1", + }); err != nil { + return fmt.Errorf( + "failed to create ccv channels on path %s on relayer %s between chains %s and %s: %w", + rp.Path, rp.Relayer, ic.chains[p], ic.chains[c], err, + ) + } + + return nil + }) + } + // Now link the paths in parallel // Creates clients, connections, and channels for each link/path. - var eg errgroup.Group for rp, link := range ic.links { rp := rp link := link @@ -463,6 +665,15 @@ func (ic *Interchain) relayerChains() map[ibc.Relayer][]ibc.Chain { uniq[r][link.chains[1]] = struct{}{} } + for rp, link := range ic.providerConsumerLinks { + r := rp.Relayer + if uniq[r] == nil { + uniq[r] = make(map[ibc.Chain]struct{}, 2) // Adding at least 2 chains per relayer. + } + uniq[r][link.provider] = struct{}{} + uniq[r][link.consumer] = struct{}{} + } + // Then convert the sets to slices. out := make(map[ibc.Relayer][]ibc.Chain, len(uniq)) for r, chainSet := range uniq { diff --git a/local-interchain/go.mod b/local-interchain/go.mod index 39a2d8a7a..c0fd5e62d 100644 --- a/local-interchain/go.mod +++ b/local-interchain/go.mod @@ -1,8 +1,6 @@ module github.com/strangelove-ventures/localinterchain -go 1.21 - -toolchain go1.21.0 +go 1.22.2 replace ( github.com/ChainSafe/go-schnorrkel => github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d @@ -22,6 +20,7 @@ require ( github.com/strangelove-ventures/interchaintest/v8 v8.0.0-00010101000000-000000000000 github.com/tyler-smith/go-bip39 v1.1.0 go.uber.org/zap v1.27.0 + gopkg.in/yaml.v3 v3.0.1 ) @@ -71,7 +70,7 @@ require ( github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/cometbft/cometbft v0.38.5 // indirect - github.com/cometbft/cometbft-db v0.9.1 // indirect + github.com/cometbft/cometbft-db v0.10.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-db v1.0.0 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.4 // indirect @@ -254,7 +253,7 @@ require ( gopkg.in/go-playground/assert.v1 v1.2.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gotest.tools/v3 v3.5.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect lukechampine.com/uint128 v1.2.0 // indirect diff --git a/local-interchain/go.sum b/local-interchain/go.sum index f05de0f56..9d9845a9e 100644 --- a/local-interchain/go.sum +++ b/local-interchain/go.sum @@ -342,8 +342,7 @@ github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= -github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877 h1:1MLK4YpFtIEo3ZtMA5C795Wtv5VuUnrXX7mQG+aHg6o= github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= @@ -357,8 +356,7 @@ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1: github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/cometbft/cometbft v0.38.5 h1:4lOcK5VTPrfbLOhNHmPYe6c7eDXHtBdMCQuKbAfFJdU= github.com/cometbft/cometbft v0.38.5/go.mod h1:0tqKin+KQs8zDwzYD8rPHzSBIDNPuB4NrwwGDNb/hUg= -github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= -github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= +github.com/cometbft/cometbft-db v0.10.0 h1:VMBQh88zXn64jXVvj39tlu/IgsGR84T7ImjS523DCiU= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= diff --git a/relayer/docker.go b/relayer/docker.go index 0425945f2..39eb8270e 100644 --- a/relayer/docker.go +++ b/relayer/docker.go @@ -228,7 +228,7 @@ func (r *DockerRelayer) CreateClients(ctx context.Context, rep ibc.RelayerExecRe return res.Err } -func (r *DockerRelayer) CreateClient(ctx context.Context, rep ibc.RelayerExecReporter, srcChainID, dstChainID, pathName string, opts ibc.CreateClientOptions) error { +func (r *DockerRelayer) CreateClient(ctx context.Context, rep ibc.RelayerExecReporter, srcChainID string, dstChainID string, pathName string, opts ibc.CreateClientOptions) error { cmd := r.c.CreateClient(srcChainID, dstChainID, pathName, opts, r.HomeDir()) res := r.Exec(ctx, rep, cmd, nil) return res.Err @@ -252,8 +252,8 @@ func (r *DockerRelayer) GeneratePath(ctx context.Context, rep ibc.RelayerExecRep return res.Err } -func (r *DockerRelayer) UpdatePath(ctx context.Context, rep ibc.RelayerExecReporter, pathName string, filter ibc.ChannelFilter) error { - cmd := r.c.UpdatePath(pathName, r.HomeDir(), filter) +func (r *DockerRelayer) UpdatePath(ctx context.Context, rep ibc.RelayerExecReporter, pathName string, opts ibc.PathUpdateOptions) error { + cmd := r.c.UpdatePath(pathName, r.HomeDir(), opts) res := r.Exec(ctx, rep, cmd, nil) return res.Err } @@ -564,7 +564,7 @@ type RelayerCommander interface { CreateConnections(pathName, homeDir string) []string Flush(pathName, channelID, homeDir string) []string GeneratePath(srcChainID, dstChainID, pathName, homeDir string) []string - UpdatePath(pathName, homeDir string, filter ibc.ChannelFilter) []string + UpdatePath(pathName, homeDir string, opts ibc.PathUpdateOptions) []string GetChannels(chainID, homeDir string) []string GetConnections(chainID, homeDir string) []string GetClients(chainID, homeDir string) []string diff --git a/relayer/hermes/hermes_commander.go b/relayer/hermes/hermes_commander.go index 9f3950c7e..cfc7142a8 100644 --- a/relayer/hermes/hermes_commander.go +++ b/relayer/hermes/hermes_commander.go @@ -145,7 +145,7 @@ func (c commander) CreateWallet(keyName, address, mnemonic string) ibc.Wallet { return NewWallet(keyName, address, mnemonic) } -func (c commander) UpdatePath(pathName, homeDir string, filter ibc.ChannelFilter) []string { +func (c commander) UpdatePath(pathName, homeDir string, opts ibc.PathUpdateOptions) []string { // TODO: figure out how to implement this. panic("implement me") } diff --git a/relayer/hyperspace/hyperspace_commander.go b/relayer/hyperspace/hyperspace_commander.go index 100ad7df1..6ce5b3f02 100644 --- a/relayer/hyperspace/hyperspace_commander.go +++ b/relayer/hyperspace/hyperspace_commander.go @@ -153,7 +153,7 @@ func (c *hyperspaceCommander) GeneratePath(srcChainID, dstChainID, pathName, hom } // Hyperspace does not have paths, just two configs -func (hyperspaceCommander) UpdatePath(pathName, homeDir string, filter ibc.ChannelFilter) []string { +func (hyperspaceCommander) UpdatePath(pathName, homeDir string, opts ibc.PathUpdateOptions) []string { panic("[UpdatePath] Do not call me") } diff --git a/relayer/rly/cosmos_relayer.go b/relayer/rly/cosmos_relayer.go index 4761040f7..1e79f931d 100644 --- a/relayer/rly/cosmos_relayer.go +++ b/relayer/rly/cosmos_relayer.go @@ -200,13 +200,38 @@ func (commander) GeneratePath(srcChainID, dstChainID, pathName, homeDir string) } } -func (commander) UpdatePath(pathName, homeDir string, filter ibc.ChannelFilter) []string { - return []string{ +func (commander) UpdatePath(pathName, homeDir string, opts ibc.PathUpdateOptions) []string { + command := []string{ "rly", "paths", "update", pathName, "--home", homeDir, - "--filter-rule", filter.Rule, - "--filter-channels", strings.Join(filter.ChannelList, ","), } + + if opts.ChannelFilter != nil { + command = append(command, + "--filter-rule", opts.ChannelFilter.Rule, + "--filter-channels", strings.Join(opts.ChannelFilter.ChannelList, ",")) + } + + if opts.SrcChainID != nil { + command = append(command, "--src-chain-id", *opts.SrcChainID) + } + if opts.DstChainID != nil { + command = append(command, "--dst-chain-id", *opts.DstChainID) + } + if opts.SrcClientID != nil { + command = append(command, "--src-client-id", *opts.SrcClientID) + } + if opts.DstClientID != nil { + command = append(command, "--dst-client-id", *opts.DstClientID) + } + if opts.SrcConnID != nil { + command = append(command, "--src-connection-id", *opts.SrcConnID) + } + if opts.DstConnID != nil { + command = append(command, "--dst-connection-id", *opts.DstConnID) + } + + return command } func (commander) GetChannels(chainID, homeDir string) []string { From 7f5dbc88ed647b00e70580c91d4d47589e3bcf02 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Tue, 23 Apr 2024 10:57:19 -0500 Subject: [PATCH 02/14] feat: ics to local-ic - #989 --- go.sum | 4 + .../chains/interchainsecurity.json | 144 ++++++++++++++++++ local-interchain/go.mod | 2 + local-interchain/go.sum | 3 + local-interchain/interchain/start.go | 40 ++++- local-interchain/interchain/types/chain.go | 1 + 6 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 local-interchain/chains/interchainsecurity.json diff --git a/go.sum b/go.sum index 2eee0401a..ffdafe972 100644 --- a/go.sum +++ b/go.sum @@ -968,6 +968,8 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/oxyno-zeta/gomock-extra-matcher v1.2.0 h1:WPEclU0y0PMwUzdDcaKZvld4aXpa3fkzjiUMQdcBEHg= +github.com/oxyno-zeta/gomock-extra-matcher v1.2.0/go.mod h1:S0r7HmKeCGsHmvIVFMjKWwswb4+30nCNWbXRMBVPkaU= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= @@ -1201,6 +1203,8 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= +go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= diff --git a/local-interchain/chains/interchainsecurity.json b/local-interchain/chains/interchainsecurity.json new file mode 100644 index 000000000..4b47af89d --- /dev/null +++ b/local-interchain/chains/interchainsecurity.json @@ -0,0 +1,144 @@ +{ + "chains": [ + { + "name": "gaia", + "chain_id": "localcosmos-1", + "denom": "uatom", + "binary": "gaiad", + "bech32_prefix": "cosmos", + "docker_image": { + "version": "v15.0.0-rc2" + }, + "gas_prices": "0%DENOM%", + "chain_type": "cosmos", + "coin_type": 118, + "trusting_period": "112h", + "gas_adjustment": 1.3, + "number_vals": 1, + "number_node": 0, + "debugging": true, + "block_time": "1s", + "genesis": { + "modify": [ + { + "key": "app_state.gov.params.voting_period", + "value": "3s" + }, + { + "key": "app_state.interchainaccounts.host_genesis_state.params.allow_messages", + "value": [ + "/cosmos.bank.v1beta1.MsgSend", + "/cosmos.bank.v1beta1.MsgMultiSend", + "/cosmos.staking.v1beta1.MsgDelegate", + "/cosmos.staking.v1beta1.MsgUndelegate", + "/cosmos.staking.v1beta1.MsgBeginRedelegate", + "/cosmos.staking.v1beta1.MsgRedeemTokensforShares", + "/cosmos.staking.v1beta1.MsgTokenizeShares", + "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", + "/ibc.applications.transfer.v1.MsgTransfer" + ] + } + ], + "accounts": [ + { + "name": "acc0", + "address": "cosmos1hj5fveer5cjtn4wd6wstzugjfdxzl0xpxvjjvr", + "amount": "10000000000%DENOM%", + "mnemonic": "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry" + } + ] + } + }, + { + "name": "ics-consumer", + "chain_id": "localneutron-1", + "denom": "untrn", + "binary": "neutrond", + "bech32_prefix": "neutron", + "docker_image": { + "version": "v2.0.2", + "repository": "ghcr.io/strangelove-ventures/heighliner/neutron" + }, + "gas_prices": "0.0untrn,0.0uatom", + "chain_type": "cosmos", + "coin_type": 118, + "trusting_period": "1197504s", + "gas_adjustment": 1.3, + "number_vals": 1, + "number_node": 0, + "ics_consumer_link": "localcosmos-1", + "debugging": true, + "block_time": "1s", + "genesis": { + "modify": [ + { + "key": "app_state.ccvconsumer.params.soft_opt_out_threshold", + "value": "0.05" + }, + { + "key": "app_state.ccvconsumer.params.reward_denoms", + "value": [ + "untrn" + ] + }, + { + "key": "app_state.ccvconsumer.params.provider_reward_denoms", + "value": [ + "uatom" + ] + }, + { + "key": "consensus_params.block.max_gas", + "value": "1000000000" + }, + { + "key": "app_state.globalfee.params.minimum_gas_prices", + "value": [ + { + "denom": "untrn", + "amount": "0" + } + ] + }, + { + "key": "app_state.feeburner.params.treasury_address", + "value": "neutron1hj5fveer5cjtn4wd6wstzugjfdxzl0xpznmsky" + }, + { + "key": "app_state.tokenfactory.params.fee_collector_address", + "value": "neutron1hj5fveer5cjtn4wd6wstzugjfdxzl0xpznmsky" + }, + { + "key": "app_state.interchainaccounts.host_genesis_state.params.allow_messages", + "value": [ + "/cosmos.bank.v1beta1.MsgSend", + "/cosmos.bank.v1beta1.MsgMultiSend", + "/cosmos.staking.v1beta1.MsgDelegate", + "/cosmos.staking.v1beta1.MsgUndelegate", + "/cosmos.staking.v1beta1.MsgBeginRedelegate", + "/cosmos.staking.v1beta1.MsgRedeemTokensforShares", + "/cosmos.staking.v1beta1.MsgTokenizeShares", + "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", + "/ibc.applications.transfer.v1.MsgTransfer", + "/ibc.lightclients.localhost.v2.ClientState", + "/ibc.core.client.v1.MsgCreateClient", + "/ibc.core.client.v1.Query/ClientState", + "/ibc.core.client.v1.Query/ConsensusState", + "/ibc.core.connection.v1.Query/Connection" + ] + } + ], + "accounts": [ + { + "name": "acc0", + "address": "neutron1hj5fveer5cjtn4wd6wstzugjfdxzl0xpznmsky", + "amount": "10000000000%DENOM%", + "mnemonic": "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/local-interchain/go.mod b/local-interchain/go.mod index c0fd5e62d..31bf87cc1 100644 --- a/local-interchain/go.mod +++ b/local-interchain/go.mod @@ -37,6 +37,7 @@ require ( cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.3.1 // indirect cosmossdk.io/store v1.0.2 // indirect + cosmossdk.io/x/evidence v0.1.0 // indirect cosmossdk.io/x/feegrant v0.1.0 // indirect cosmossdk.io/x/tx v0.13.0 // indirect cosmossdk.io/x/upgrade v0.1.1 // indirect @@ -81,6 +82,7 @@ require ( github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect github.com/cosmos/ibc-go/v8 v8.1.0 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect + github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240423100140-781f691e7f89 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/local-interchain/go.sum b/local-interchain/go.sum index 9d9845a9e..e9390f064 100644 --- a/local-interchain/go.sum +++ b/local-interchain/go.sum @@ -389,6 +389,7 @@ github.com/cosmos/ibc-go/v8 v8.1.0 h1:pf1106wl0Cf+p1+FjXzV6odlS9DnqVunPVWCH1Uz+l github.com/cosmos/ibc-go/v8 v8.1.0/go.mod h1:o1ipS95xpdjqNcB8Drq0eI3Sn4FRLigjll42ec1ECuU= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= +github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240423100140-781f691e7f89 h1:VVn2oLuiGmQIC3ovazpI0Z8R3zgXhgAx/lfOT5EfNHY= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -950,6 +951,7 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/oxyno-zeta/gomock-extra-matcher v1.2.0 h1:WPEclU0y0PMwUzdDcaKZvld4aXpa3fkzjiUMQdcBEHg= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= @@ -1178,6 +1180,7 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= diff --git a/local-interchain/interchain/start.go b/local-interchain/interchain/start.go index 99ecb4b60..56e39660f 100644 --- a/local-interchain/interchain/start.go +++ b/local-interchain/interchain/start.go @@ -58,6 +58,9 @@ func StartChain(installDir, chainCfgFile string, ac *types.AppStartConfig) { // ibc-path-name -> index of []cosmos.CosmosChain ibcpaths := make(map[string][]int) + // providerChainId -> []consumerChainIds + icsPair := make(map[string][]string) + chainSpecs := []*interchaintest.ChainSpec{} for idx, cfg := range config.Chains { @@ -69,6 +72,10 @@ func StartChain(installDir, chainCfgFile string, ac *types.AppStartConfig) { ibcpaths[path] = append(ibcpaths[path], idx) } } + + if cfg.ICSConsumerLink != "" { + icsPair[cfg.ICSConsumerLink] = append(icsPair[cfg.ICSConsumerLink], cfg.ChainID) + } } if err := VerifyIBCPaths(ibcpaths); err != nil { @@ -101,7 +108,7 @@ func StartChain(installDir, chainCfgFile string, ac *types.AppStartConfig) { client, network := interchaintest.DockerSetup(fakeT) // setup a relayer if we have IBC paths to use. - if len(ibcpaths) > 0 { + if len(ibcpaths) > 0 || len(icsPair) > 0 { rlyCfg := config.Relayer relayerType, relayerName := ibc.CosmosRly, "relay" @@ -124,6 +131,37 @@ func StartChain(installDir, chainCfgFile string, ac *types.AppStartConfig) { LinkIBCPaths(ibcpaths, chains, ic, relayer) } + // Add Interchain Security chain pairs together + if len(icsPair) > 0 { + for provider, consumers := range icsPair { + var p ibc.Chain + var c ibc.Chain + + // a provider can have multiple consumers + for _, consumer := range consumers { + for _, chain := range chains { + if chain.Config().ChainID == provider { + p = chain + } + if chain.Config().ChainID == consumer { + c = chain + } + } + } + + pathName := fmt.Sprintf("%s-%s", p.Config().ChainID, c.Config().ChainID) + + logger.Info("Adding ICS pair", zap.String("provider", p.Config().ChainID), zap.String("consumer", c.Config().ChainID), zap.String("path", pathName)) + + ic = ic.AddProviderConsumerLink(interchaintest.ProviderConsumerLink{ + Provider: p, + Consumer: c, + Relayer: relayer, + Path: pathName, + }) + } + } + // Build all chains & begin. err = ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ TestName: testName, diff --git a/local-interchain/interchain/types/chain.go b/local-interchain/interchain/types/chain.go index 785182d9e..95a799f6d 100644 --- a/local-interchain/interchain/types/chain.go +++ b/local-interchain/interchain/types/chain.go @@ -23,6 +23,7 @@ type Chain struct { Debugging bool `json:"debugging" yaml:"debugging"` BlockTime string `json:"block_time" yaml:"block_time"` HostPortOverride map[string]string `json:"host_port_override" yaml:"host_port_override"` + ICSConsumerLink string `json:"ics_consumer_link"` // a consumer sets this to ex: "provider-chain-id" to connect to them // Required Name string `json:"name" yaml:"name" validate:"min=1"` From cda86b826b0a1bdf7c8998779f5ba12c2eb05b71 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Tue, 23 Apr 2024 11:21:35 -0500 Subject: [PATCH 03/14] IBC not happy --- chain/cosmos/cosmos_chain.go | 2 +- examples/ibc/ics_test.go | 21 +++++++++++++++++-- .../chains/interchainsecurity.json | 10 ++++++--- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/chain/cosmos/cosmos_chain.go b/chain/cosmos/cosmos_chain.go index e7e4c7e4b..1b43e5631 100644 --- a/chain/cosmos/cosmos_chain.go +++ b/chain/cosmos/cosmos_chain.go @@ -52,7 +52,7 @@ import ( var ( defaultUpgradePath = []string{"upgrade", "upgradedIBCState"} - DefaultProviderUnbondingPeriod = 504 * time.Hour + DefaultProviderUnbondingPeriod = 336 * time.Hour ) // CosmosChain is a local docker testnet for a Cosmos SDK chain. diff --git a/examples/ibc/ics_test.go b/examples/ibc/ics_test.go index d64f1750d..78ffa4feb 100644 --- a/examples/ibc/ics_test.go +++ b/examples/ibc/ics_test.go @@ -7,6 +7,7 @@ import ( "time" interchaintest "github.com/strangelove-ventures/interchaintest/v8" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/ibc" "github.com/strangelove-ventures/interchaintest/v8/testreporter" "github.com/strangelove-ventures/interchaintest/v8/testutil" @@ -24,10 +25,26 @@ func TestICS(t *testing.T) { ctx := context.Background() + vals := 1 + fNodes := 0 + // Chain Factory cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ - {Name: "ics-provider", Version: "v3.1.0", ChainConfig: ibc.ChainConfig{GasAdjustment: 1.5}}, - {Name: "neutron", Version: "v2.0.2"}, // ics-consumer + { + Name: "ics-provider", + NumValidators: &vals, NumFullNodes: &fNodes, + Version: "v3.1.0", ChainConfig: ibc.ChainConfig{GasAdjustment: 1.5, TrustingPeriod: "336h"}, + }, + { // ics-consumer + Name: "neutron", Version: "v3.0.4", + NumValidators: &vals, NumFullNodes: &fNodes, + ChainConfig: ibc.ChainConfig{ + TrustingPeriod: "336h", + ModifyGenesis: cosmos.ModifyGenesis([]cosmos.GenesisKV{ + cosmos.NewGenesisKV("consensus_params.block.max_gas", "100000000"), + }), + }, + }, }) chains, err := cf.Chains(t.Name()) diff --git a/local-interchain/chains/interchainsecurity.json b/local-interchain/chains/interchainsecurity.json index 4b47af89d..73400bff6 100644 --- a/local-interchain/chains/interchainsecurity.json +++ b/local-interchain/chains/interchainsecurity.json @@ -12,7 +12,7 @@ "gas_prices": "0%DENOM%", "chain_type": "cosmos", "coin_type": 118, - "trusting_period": "112h", + "trusting_period": "336h", "gas_adjustment": 1.3, "number_vals": 1, "number_node": 0, @@ -57,13 +57,13 @@ "binary": "neutrond", "bech32_prefix": "neutron", "docker_image": { - "version": "v2.0.2", + "version": "v3.0.4", "repository": "ghcr.io/strangelove-ventures/heighliner/neutron" }, "gas_prices": "0.0untrn,0.0uatom", "chain_type": "cosmos", "coin_type": 118, - "trusting_period": "1197504s", + "trusting_period": "336h", "gas_adjustment": 1.3, "number_vals": 1, "number_node": 0, @@ -72,6 +72,10 @@ "block_time": "1s", "genesis": { "modify": [ + { + "key": "consensus_params.block.max_gas", + "value": "100000000" + }, { "key": "app_state.ccvconsumer.params.soft_opt_out_threshold", "value": "0.05" From 497d3f663104f225d71fbe1e3fd4a93814946295 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 24 Apr 2024 19:39:20 -0500 Subject: [PATCH 04/14] latest ICS v5, impl #1093 --- chain/cosmos/chain_node.go | 19 ++++ chain/cosmos/cosmos_chain.go | 178 +++++++++++++++++++++------------- configuredChains.yaml | 108 ++++++++++----------- examples/ibc/ics_test.go | 9 +- go.mod | 4 +- go.sum | 4 +- relayer/rly/cosmos_relayer.go | 2 +- 7 files changed, 197 insertions(+), 127 deletions(-) diff --git a/chain/cosmos/chain_node.go b/chain/cosmos/chain_node.go index 3bbe76b65..53b4f424f 100644 --- a/chain/cosmos/chain_node.go +++ b/chain/cosmos/chain_node.go @@ -36,6 +36,7 @@ import ( dockerclient "github.com/docker/docker/client" "github.com/docker/go-connections/nat" "go.uber.org/zap" + "golang.org/x/mod/semver" "golang.org/x/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -721,6 +722,24 @@ func (tn *ChainNode) IsAboveSDK47(ctx context.Context) bool { return tn.HasCommand(ctx, "genesis") } +// ICSVersion returns the version of interchain-security the binary was built with. +// If it doesn't depend on interchain-security, it returns an empty string. +func (tn *ChainNode) ICSVersion(ctx context.Context) string { + if strings.HasPrefix(tn.Chain.Config().Bin, "interchain-security") { + // This isn't super pretty, but it's the best we can do for an interchain-security binary. + // It doesn't depend on itself, and the version command doesn't actually output a version. + // Ideally if you have a binary called something like "v3.3.0-my-fix" you can use it as a version, since the v3.3.0 part is in it. + return semver.Canonical(tn.Image.Version) + } + info := tn.GetBuildInformation(ctx) + for _, dep := range info.BuildDeps { + if strings.HasPrefix(dep.Parent, "github.com/cosmos/interchain-security") { + return semver.Canonical(dep.Version) + } + } + return "" +} + // AddGenesisAccount adds a genesis account for each key func (tn *ChainNode) AddGenesisAccount(ctx context.Context, address string, genesisAmount []sdk.Coin) error { amount := "" diff --git a/chain/cosmos/cosmos_chain.go b/chain/cosmos/cosmos_chain.go index 1b43e5631..e55eb2281 100644 --- a/chain/cosmos/cosmos_chain.go +++ b/chain/cosmos/cosmos_chain.go @@ -10,14 +10,13 @@ import ( "io" "math" "os" + "path" "strconv" "strings" "sync" "time" sdkmath "cosmossdk.io/math" - abcitypes "github.com/cometbft/cometbft/abci/types" - "github.com/cometbft/cometbft/proto/tendermint/crypto" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" @@ -31,11 +30,7 @@ import ( paramsutils "github.com/cosmos/cosmos-sdk/x/params/client/utils" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" // nolint:staticcheck chanTypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" - ccvconsumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" ccvclient "github.com/cosmos/interchain-security/v5/x/ccv/provider/client" - ccvprovidertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" dockertypes "github.com/docker/docker/api/types" volumetypes "github.com/docker/docker/api/types/volume" "github.com/docker/docker/client" @@ -47,6 +42,7 @@ import ( "github.com/strangelove-ventures/interchaintest/v8/ibc" "github.com/strangelove-ventures/interchaintest/v8/testutil" "go.uber.org/zap" + "golang.org/x/mod/semver" "golang.org/x/sync/errgroup" ) @@ -1139,6 +1135,47 @@ func (c *CosmosChain) StartProvider(testName string, ctx context.Context, additi return nil } +func (c *CosmosChain) transformCCVState(ctx context.Context, ccvState []byte, consumerVersion, providerVersion string) ([]byte, error) { + // If they're both under 3.3.0, or if they're the same version, we don't need to transform the state. + if semver.MajorMinor(providerVersion) == semver.MajorMinor(consumerVersion) || + (semver.Compare(providerVersion, "v3.3.0") < 0 && semver.Compare(consumerVersion, "v3.3.0") < 0) { + return ccvState, nil + } + var imageVersion, toVersion string + // The trick here is that when we convert the state to a consumer < 3.3.0, we need a converter that knows about that version; those are >= 4.0.0, and need a --to flag. + // Other than that, this is a question of using whichever version is newer. If it's the provider's, we need a --to flag to tell it the consumer version. + // If it's the consumer's, we don't need a --to flag cause it'll assume the consumer version. + if semver.Compare(providerVersion, "v3.3.0") >= 0 && semver.Compare(providerVersion, consumerVersion) > 0 { + imageVersion = "v4.0.0" + if semver.Compare(providerVersion, "v4.0.0") > 0 { + imageVersion = providerVersion + } + toVersion = semver.Major(consumerVersion) + if toVersion == "v3" { + toVersion = semver.MajorMinor(consumerVersion) + } + } else { + imageVersion = consumerVersion + } + err := c.GetNode().WriteFile(ctx, ccvState, "ccvconsumer.json") + if err != nil { + return nil, fmt.Errorf("failed to write ccv state to file: %w", err) + } + job := dockerutil.NewImage(c.log, c.GetNode().DockerClient, c.GetNode().NetworkID, + c.GetNode().TestName, "ghcr.io/strangelove-ventures/heighliner/ics", imageVersion, + ) + cmd := []string{"interchain-security-cd", "genesis", "transform"} + if toVersion != "" { + cmd = append(cmd, "--to", toVersion+".x") + } + cmd = append(cmd, path.Join(c.GetNode().HomeDir(), "ccvconsumer.json")) + res := job.Run(ctx, cmd, dockerutil.ContainerOptions{Binds: c.GetNode().Bind()}) + if res.Err != nil { + return nil, fmt.Errorf("failed to transform ccv state: %w", res.Err) + } + return res.Stdout, nil +} + // Bootstraps the consumer chain and starts it from genesis func (c *CosmosChain) StartConsumer(testName string, ctx context.Context, additionalGenesisWallets ...ibc.WalletAmount) error { chainCfg := c.Config() @@ -1205,78 +1242,87 @@ func (c *CosmosChain) StartConsumer(testName string, ctx context.Context, additi } } - providerHeight, err := c.Provider.Height(ctx) - if err != nil { - return fmt.Errorf("failed to query provider height") - } - providerHeightInt64 := int64(providerHeight) + // providerHeight, err := c.Provider.Height(ctx) + // if err != nil { + // return fmt.Errorf("failed to query provider height") + // } + // providerHeightInt64 := int64(providerHeight) - block, err := c.Provider.getFullNode().Client.Block(ctx, &providerHeightInt64) - if err != nil { - return fmt.Errorf("failed to query provider block to initialize consumer client") - } + // block, err := c.Provider.getFullNode().Client.Block(ctx, &providerHeightInt64) + // if err != nil { + // return fmt.Errorf("failed to query provider block to initialize consumer client") + // } genbz, err := validator0.GenesisFileContent(ctx) if err != nil { return err } - // populate genesis file ccvconsumer module app_state. - // fetch provider latest block (timestamp, root.hash, and next_validators_hash) to populate provider_consensus_state - // populate provider_client_state with trusting and unbonding periods, latest_height.revision_height of height which is used for consensus state - // populate initial_val_set with provider val pubkeys and power - - nextValidatorsHash := block.Block.NextValidatorsHash - timestamp := block.Block.Time - rootHash := block.Block.AppHash - - page := int(1) - perPage := int(1000) - providerVals, err := c.Provider.getFullNode().Client.Validators(ctx, &providerHeightInt64, &page, &perPage) + ccvStateMarshaled, _, err := c.Provider.GetNode().ExecQuery(ctx, "provider", "consumer-genesis", c.cfg.ChainID) if err != nil { - return fmt.Errorf("failed to get provider validators: %w", err) - } - - initialVals := make([]abcitypes.ValidatorUpdate, len(providerVals.Validators)) - for i, val := range providerVals.Validators { - initialVals[i] = abcitypes.ValidatorUpdate{ - PubKey: crypto.PublicKey{Sum: &crypto.PublicKey_Ed25519{Ed25519: val.PubKey.Bytes()}}, - Power: val.VotingPower, - } - } - - providerCfg := c.Provider.Config() - - clientState := ibctmtypes.NewClientState( - providerCfg.ChainID, - ibctmtypes.DefaultTrustLevel, - DefaultProviderUnbondingPeriod/2, - DefaultProviderUnbondingPeriod, // Needs to match provider unbonding period - ccvprovidertypes.DefaultMaxClockDrift, - clienttypes.Height{ - RevisionHeight: uint64(providerHeight), - RevisionNumber: clienttypes.ParseChainID(providerCfg.ChainID), - }, - commitmenttypes.GetSDKSpecs(), - defaultUpgradePath, - ) - - root := commitmenttypes.MerkleRoot{ - Hash: rootHash, + return fmt.Errorf("failed to query provider for ccv state: %w", err) } - consensusState := ibctmtypes.NewConsensusState(timestamp, root, nextValidatorsHash) - - ccvState := ccvconsumertypes.NewInitialGenesisState( - clientState, - consensusState, - initialVals, - ccvconsumertypes.DefaultGenesisState().GetParams(), - ) + consumerICS := c.GetNode().ICSVersion(ctx) + providerICS := c.Provider.GetNode().ICSVersion(ctx) + ccvStateMarshaled, err = c.transformCCVState(ctx, ccvStateMarshaled, consumerICS, providerICS) - ccvState.Params.Enabled = true + // populate genesis file ccvconsumer module app_state. + // fetch provider latest block (timestamp, root.hash, and next_validators_hash) to populate provider_consensus_state + // populate provider_client_state with trusting and unbonding periods, latest_height.revision_height of height which is used for consensus state + // populate initial_val_set with provider val pubkeys and power - ccvStateMarshaled, err := c.cfg.EncodingConfig.Codec.MarshalJSON(ccvState) + // nextValidatorsHash := block.Block.NextValidatorsHash + // timestamp := block.Block.Time + // rootHash := block.Block.AppHash + + // page := int(1) + // perPage := int(1000) + // providerVals, err := c.Provider.getFullNode().Client.Validators(ctx, &providerHeightInt64, &page, &perPage) + // if err != nil { + // return fmt.Errorf("failed to get provider validators: %w", err) + // } + + // initialVals := make([]abcitypes.ValidatorUpdate, len(providerVals.Validators)) + // for i, val := range providerVals.Validators { + // initialVals[i] = abcitypes.ValidatorUpdate{ + // PubKey: crypto.PublicKey{Sum: &crypto.PublicKey_Ed25519{Ed25519: val.PubKey.Bytes()}}, + // Power: val.VotingPower, + // } + // } + + // providerCfg := c.Provider.Config() + + // clientState := ibctmtypes.NewClientState( + // providerCfg.ChainID, + // ibctmtypes.DefaultTrustLevel, + // DefaultProviderUnbondingPeriod/2, + // DefaultProviderUnbondingPeriod, // Needs to match provider unbonding period + // ccvprovidertypes.DefaultMaxClockDrift, + // clienttypes.Height{ + // RevisionHeight: uint64(providerHeight), + // RevisionNumber: clienttypes.ParseChainID(providerCfg.ChainID), + // }, + // commitmenttypes.GetSDKSpecs(), + // defaultUpgradePath, + // ) + + // root := commitmenttypes.MerkleRoot{ + // Hash: rootHash, + // } + + // consensusState := ibctmtypes.NewConsensusState(timestamp, root, nextValidatorsHash) + + // ccvState := ccvconsumertypes.NewInitialGenesisState( + // clientState, + // consensusState, + // initialVals, + // ccvconsumertypes.DefaultGenesisState().GetParams(), + // ) + + // ccvState.Params.Enabled = true + + // ccvStateMarshaled, err := c.cfg.EncodingConfig.Codec.MarshalJSON(ccvState) c.log.Info("HERE STATE!", zap.String("GEN", string(ccvStateMarshaled))) if err != nil { return fmt.Errorf("failed to marshal ccv state to json: %w", err) diff --git a/configuredChains.yaml b/configuredChains.yaml index bf2997cd9..a2a9e6794 100644 --- a/configuredChains.yaml +++ b/configuredChains.yaml @@ -9,7 +9,7 @@ agoric: bech32-prefix: agoric denom: urun gas-prices: 0.01urun - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 564 trusting-period: 672h images: @@ -24,7 +24,7 @@ akash: bech32-prefix: akash denom: uakt gas-prices: 0.01uakt - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/akash @@ -38,7 +38,7 @@ arkeo: bech32-prefix: arkeo denom: uarkeo gas-prices: 0.01uarkeo - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/arkeo @@ -52,7 +52,7 @@ axelar: bech32-prefix: axelar denom: uaxl gas-prices: 0.01uaxl - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 168h images: - repository: ghcr.io/strangelove-ventures/heighliner/axelar @@ -66,7 +66,7 @@ bitcanna: bech32-prefix: bcna denom: ubcna gas-prices: 0.01ubcna - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 336h images: - repository: ghcr.io/strangelove-ventures/heighliner/bitcanna @@ -80,7 +80,7 @@ bitsong: bech32-prefix: bitsong denom: ubtsg gas-prices: 0.01ubtsg - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 639 trusting-period: 504h images: @@ -95,7 +95,7 @@ bostrom: bech32-prefix: bostrom denom: boot gas-prices: 0.01boot - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 192h images: - repository: ghcr.io/strangelove-ventures/heighliner/bostrom @@ -109,7 +109,7 @@ carbon: bech32-prefix: swth denom: swth gas-prices: 0.01swth - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 720h images: - repository: ghcr.io/strangelove-ventures/heighliner/carbon @@ -123,7 +123,7 @@ cerberus: bech32-prefix: cerberus denom: ucrbrus gas-prices: 0.01ucrbrus - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 336.667h images: - repository: ghcr.io/strangelove-ventures/heighliner/cerberus @@ -137,7 +137,7 @@ cheqd: bech32-prefix: cheqd denom: ncheq gas-prices: 0.01ncheq - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 336.111h images: - repository: ghcr.io/strangelove-ventures/heighliner/cheqd @@ -151,7 +151,7 @@ chihuahua: bech32-prefix: chihuahua denom: uhuahua gas-prices: 0.01uhuahua - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/chihuahua @@ -165,7 +165,7 @@ comdex: bech32-prefix: comdex denom: ucmdx gas-prices: 0.01ucmdx - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/comdex @@ -194,7 +194,7 @@ crescent: bech32-prefix: cre denom: ucre gas-prices: 0.01ucre - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 336h images: - repository: ghcr.io/strangelove-ventures/heighliner/crescent @@ -208,7 +208,7 @@ cronos: bech32-prefix: crc denom: stake gas-prices: 0.01stake - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 60 trusting-period: 672h images: @@ -223,7 +223,7 @@ cryptoorgchain: bech32-prefix: cro denom: basecro gas-prices: 0.01basecro - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 394 trusting-period: 672h images: @@ -238,7 +238,7 @@ decentr: bech32-prefix: decentr denom: udec gas-prices: 0.01udec - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/decentr @@ -252,7 +252,7 @@ desmos: bech32-prefix: desmos denom: udsm gas-prices: 0.01udsm - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 852 trusting-period: 336h images: @@ -267,7 +267,7 @@ dig: bech32-prefix: dig denom: udig gas-prices: 0.01udig - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 336h images: - repository: ghcr.io/strangelove-ventures/heighliner/dig @@ -281,7 +281,7 @@ emoney: bech32-prefix: emoney denom: ungm gas-prices: 0.01ungm - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/emoney @@ -295,7 +295,7 @@ evmos: bech32-prefix: evmos denom: aevmos gas-prices: 0.01aevmos - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 60 trusting-period: 336h images: @@ -310,7 +310,7 @@ fetchhub: bech32-prefix: fetch denom: afet gas-prices: 0.01afet - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/fetchhub @@ -324,7 +324,7 @@ firmachain: bech32-prefix: firma denom: ufct gas-prices: 0.01ufct - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 7777777 trusting-period: 504h images: @@ -339,7 +339,7 @@ gaia: bech32-prefix: cosmos denom: uatom gas-prices: 0.01uatom - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/gaia @@ -353,7 +353,7 @@ gravitybridge: bech32-prefix: gravity denom: ugraviton gas-prices: 0.01ugraviton - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/gravitybridge @@ -423,7 +423,7 @@ impacthub: bech32-prefix: ixo denom: uixo gas-prices: 0.01uixo - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/impacthub @@ -437,7 +437,7 @@ injective: bech32-prefix: inj denom: inj gas-prices: 0.01inj - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 60 trusting-period: 504h images: @@ -452,7 +452,7 @@ irisnet: bech32-prefix: iaa denom: uiris gas-prices: 0.01uiris - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/irisnet @@ -466,7 +466,7 @@ juno: bech32-prefix: juno denom: ujuno gas-prices: 0.0025ujuno - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 672h images: - repository: ghcr.io/strangelove-ventures/heighliner/juno @@ -480,7 +480,7 @@ kichain: bech32-prefix: ki denom: uxki gas-prices: 0.01uxki - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 672h images: - repository: ghcr.io/strangelove-ventures/heighliner/kichain @@ -494,7 +494,7 @@ konstellation: bech32-prefix: darc denom: udarc gas-prices: 0.01udarc - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 672h images: - repository: ghcr.io/strangelove-ventures/heighliner/konstellation @@ -508,7 +508,7 @@ kujira: bech32-prefix: kujira denom: ukuji gas-prices: 0.01ukuji - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 336h images: - repository: ghcr.io/strangelove-ventures/heighliner/kujira @@ -522,7 +522,7 @@ likecoin: bech32-prefix: like denom: nanolike gas-prices: 0.01nanolike - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/likecoin @@ -536,7 +536,7 @@ lumnetwork: bech32-prefix: lum denom: ulum gas-prices: 0.01ulum - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 504h images: - repository: ghcr.io/strangelove-ventures/heighliner/lum @@ -550,7 +550,7 @@ neutron: bech32-prefix: neutron denom: untrn gas-prices: 0.01untrn - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 336h images: - repository: ghcr.io/strangelove-ventures/heighliner/neutron @@ -564,7 +564,7 @@ omniflixhub: bech32-prefix: omniflix denom: uflix gas-prices: 0.01uflix - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: "504h" images: - repository: ghcr.io/strangelove-ventures/heighliner/omniflix @@ -578,7 +578,7 @@ osmosis: bech32-prefix: osmo denom: uosmo gas-prices: 0.0025uosmo - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 336h images: - repository: ghcr.io/strangelove-ventures/heighliner/osmosis @@ -592,7 +592,7 @@ panacea: bech32-prefix: panacea denom: umed gas-prices: 0.01umed - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 371 trusting-period: "504h" images: @@ -607,7 +607,7 @@ penumbra: bech32-prefix: penumbrav2t denom: upenumbra gas-prices: 0.0upenumbra - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: 672h images: - repository: ghcr.io/strangelove-ventures/heighliner/tendermint @@ -622,7 +622,7 @@ persistence: bech32-prefix: persistence denom: uxprt gas-prices: 0.01uxprt - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 750 trusting-period: "504h" images: @@ -637,7 +637,7 @@ provenance: bech32-prefix: pb denom: nhash gas-prices: 0.01nhash - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 505 trusting-period: "504h" images: @@ -652,7 +652,7 @@ regen: bech32-prefix: regen denom: uregen gas-prices: 0.01uregen - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: "504h" images: - repository: ghcr.io/strangelove-ventures/heighliner/regen @@ -666,7 +666,7 @@ rizon: bech32-prefix: rizon denom: uatolo gas-prices: 0.01uatolo - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: "504h" images: - repository: ghcr.io/strangelove-ventures/heighliner/rizon @@ -680,7 +680,7 @@ secretnetwork: bech32-prefix: secret denom: uscrt gas-prices: 0.01uscrt - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 529 trusting-period: "504h" images: @@ -695,7 +695,7 @@ sentinel: bech32-prefix: sent denom: udvpn gas-prices: 0.01udvpn - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: "672h" images: - repository: ghcr.io/strangelove-ventures/heighliner/sentinel @@ -709,7 +709,7 @@ shentu: bech32-prefix: certik denom: uctk gas-prices: 0.01uctk - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: "504h" images: - repository: ghcr.io/strangelove-ventures/heighliner/shentu @@ -723,7 +723,7 @@ sifchain: bech32-prefix: sif denom: rowan gas-prices: 0.01rowan - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: "504h" images: - repository: ghcr.io/strangelove-ventures/heighliner/sifchain @@ -737,7 +737,7 @@ sommelier: bech32-prefix: somm denom: usomm gas-prices: 0.01usomm - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: "672h" images: - repository: ghcr.io/strangelove-ventures/heighliner/sommelier @@ -751,7 +751,7 @@ stargaze: bech32-prefix: stars denom: ustars gas-prices: 0.01ustars - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: "336h" images: - repository: ghcr.io/strangelove-ventures/heighliner/stargaze @@ -765,7 +765,7 @@ starname: bech32-prefix: star denom: uiov gas-prices: 0.01uiov - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 234 trusting-period: "504h" images: @@ -780,7 +780,7 @@ stride: bech32-prefix: stride denom: ustrd gas-prices: 0.01ustrd - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: "336h" images: - repository: ghcr.io/strangelove-ventures/heighliner/stride @@ -794,7 +794,7 @@ terpnetwork: bech32-prefix: terp denom: uterp gas-prices: 0.01uterp - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: "504h" images: - repository: ghcr.io/strangelove-ventures/heighliner/terpnetwork @@ -808,7 +808,7 @@ terra: bech32-prefix: terra denom: uluna gas-prices: 0.01uluna - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 330 trusting-period: "336h" images: @@ -823,7 +823,7 @@ umee: bech32-prefix: umee denom: uumee gas-prices: 0.01uumee - gas-adjustment: 1.3 + gas-adjustment: 2.0 trusting-period: "336h" images: - repository: ghcr.io/strangelove-ventures/heighliner/umee @@ -837,7 +837,7 @@ vidulum: bech32-prefix: vdl denom: uvdl gas-prices: 0.01uvdl - gas-adjustment: 1.3 + gas-adjustment: 2.0 coin-type: 370 trusting-period: "504h" images: diff --git a/examples/ibc/ics_test.go b/examples/ibc/ics_test.go index 78ffa4feb..c3c112260 100644 --- a/examples/ibc/ics_test.go +++ b/examples/ibc/ics_test.go @@ -33,13 +33,17 @@ func TestICS(t *testing.T) { { Name: "ics-provider", NumValidators: &vals, NumFullNodes: &fNodes, - Version: "v3.1.0", ChainConfig: ibc.ChainConfig{GasAdjustment: 1.5, TrustingPeriod: "336h"}, + Version: "v3.1.0", + ChainConfig: ibc.ChainConfig{ + GasAdjustment: 2.0, TrustingPeriod: "336h", + }, }, { // ics-consumer - Name: "neutron", Version: "v3.0.4", + Name: "neutron", Version: "v2.0.2", NumValidators: &vals, NumFullNodes: &fNodes, ChainConfig: ibc.ChainConfig{ TrustingPeriod: "336h", + GasAdjustment: 2.0, ModifyGenesis: cosmos.ModifyGenesis([]cosmos.GenesisKV{ cosmos.NewGenesisKV("consensus_params.block.max_gas", "100000000"), }), @@ -57,6 +61,7 @@ func TestICS(t *testing.T) { r := interchaintest.NewBuiltinRelayerFactory( ibc.CosmosRly, zaptest.NewLogger(t), + // relayer.CustomDockerImage("ghcr.io/cosmos/relayer", "v2.4.0", "1025:1025"), ).Build(t, client, network) // Prep Interchain diff --git a/go.mod b/go.mod index 40c642622..1656f7446 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/cosmos/gogoproto v1.4.12 github.com/cosmos/ibc-go/modules/capability v1.0.0 github.com/cosmos/ibc-go/v8 v8.2.0 - github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240423100140-781f691e7f89 + github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240424193412-7cd900ad2a74 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.1 github.com/docker/docker v24.0.9+incompatible @@ -51,6 +51,7 @@ require ( go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.22.0 + golang.org/x/mod v0.17.0 golang.org/x/sync v0.7.0 golang.org/x/tools v0.20.0 google.golang.org/grpc v1.63.2 @@ -244,7 +245,6 @@ require ( go.opentelemetry.io/otel/metric v1.22.0 // indirect go.opentelemetry.io/otel/trace v1.22.0 // indirect golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect - golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/sys v0.19.0 // indirect diff --git a/go.sum b/go.sum index b59c6b04e..5283849d1 100644 --- a/go.sum +++ b/go.sum @@ -397,8 +397,8 @@ github.com/cosmos/ibc-go/v8 v8.2.0 h1:7oCzyy1sZCcgpeQLnHxC56brsSz3KWwQGKXalXwXFz github.com/cosmos/ibc-go/v8 v8.2.0/go.mod h1:wj3qx75iC/XNnsMqbPDCIGs0G6Y3E/lo3bdqCyoCy+8= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= -github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240423100140-781f691e7f89 h1:VVn2oLuiGmQIC3ovazpI0Z8R3zgXhgAx/lfOT5EfNHY= -github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240423100140-781f691e7f89/go.mod h1:c4oYjNwdfPKAhxzkwzTkkWROXKeUNPvc4VJHyNWrRU8= +github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240424193412-7cd900ad2a74 h1:6atU/xizTL10q6EprP7oRuvfgUP2F6puvutnVoE+FRc= +github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240424193412-7cd900ad2a74/go.mod h1:h/RkwOppo5AJj+1pkQyfjqU1MPdpohD/S6oEeAXpGZY= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= diff --git a/relayer/rly/cosmos_relayer.go b/relayer/rly/cosmos_relayer.go index 1e79f931d..fb8268125 100644 --- a/relayer/rly/cosmos_relayer.go +++ b/relayer/rly/cosmos_relayer.go @@ -63,7 +63,7 @@ type CosmosRelayerChainConfig struct { const ( DefaultContainerImage = "ghcr.io/cosmos/relayer" - DefaultContainerVersion = "v2.5.0" + DefaultContainerVersion = "v2.5.2" ) // Capabilities returns the set of capabilities of the Cosmos relayer. From 23d348608e96637184a5f8bbeb490efaf02ed33c Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 24 Apr 2024 19:55:18 -0500 Subject: [PATCH 05/14] working ics test --- configuredChains.yaml | 14 ++++++++++++++ examples/ibc/ics_test.go | 20 ++++---------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/configuredChains.yaml b/configuredChains.yaml index a2a9e6794..ef3aa1745 100644 --- a/configuredChains.yaml +++ b/configuredChains.yaml @@ -402,6 +402,20 @@ icad: uid-gid: 1025:1025 no-host-mount: false +ics-consumer: + name: ics-consumer + type: cosmos + bin: interchain-security-cd + bech32-prefix: cosmos + denom: stake + gas-prices: 0.0stake + gas-adjustment: 1.1 + trusting-period: 96h + images: + - repository: ghcr.io/strangelove-ventures/heighliner/ics + uid-gid: 1025:1025 + no-host-mount: false + ics-provider: name: ics-provider type: cosmos diff --git a/examples/ibc/ics_test.go b/examples/ibc/ics_test.go index c3c112260..90715504b 100644 --- a/examples/ibc/ics_test.go +++ b/examples/ibc/ics_test.go @@ -7,7 +7,6 @@ import ( "time" interchaintest "github.com/strangelove-ventures/interchaintest/v8" - "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/ibc" "github.com/strangelove-ventures/interchaintest/v8/testreporter" "github.com/strangelove-ventures/interchaintest/v8/testutil" @@ -31,23 +30,12 @@ func TestICS(t *testing.T) { // Chain Factory cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ { - Name: "ics-provider", + Name: "ics-provider", Version: "v3.1.0", NumValidators: &vals, NumFullNodes: &fNodes, - Version: "v3.1.0", - ChainConfig: ibc.ChainConfig{ - GasAdjustment: 2.0, TrustingPeriod: "336h", - }, - }, - { // ics-consumer - Name: "neutron", Version: "v2.0.2", + ChainConfig: ibc.ChainConfig{GasAdjustment: 1.5}}, + { + Name: "ics-consumer", Version: "v3.1.0", NumValidators: &vals, NumFullNodes: &fNodes, - ChainConfig: ibc.ChainConfig{ - TrustingPeriod: "336h", - GasAdjustment: 2.0, - ModifyGenesis: cosmos.ModifyGenesis([]cosmos.GenesisKV{ - cosmos.NewGenesisKV("consensus_params.block.max_gas", "100000000"), - }), - }, }, }) From 16c086113569ecd377dea0e245558fa9ffec1d2b Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 24 Apr 2024 20:09:43 -0500 Subject: [PATCH 06/14] lint --- chain/cosmos/cosmos_chain.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/cosmos/cosmos_chain.go b/chain/cosmos/cosmos_chain.go index e55eb2281..7c8cf9e3c 100644 --- a/chain/cosmos/cosmos_chain.go +++ b/chain/cosmos/cosmos_chain.go @@ -47,7 +47,6 @@ import ( ) var ( - defaultUpgradePath = []string{"upgrade", "upgradedIBCState"} DefaultProviderUnbondingPeriod = 336 * time.Hour ) @@ -1157,6 +1156,7 @@ func (c *CosmosChain) transformCCVState(ctx context.Context, ccvState []byte, co } else { imageVersion = consumerVersion } + err := c.GetNode().WriteFile(ctx, ccvState, "ccvconsumer.json") if err != nil { return nil, fmt.Errorf("failed to write ccv state to file: %w", err) From df9a8ce42c2b3f63975682646699acfad472889d Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Wed, 24 Apr 2024 21:00:06 -0500 Subject: [PATCH 07/14] fix: `ConsumerAdditionProposalJSON` use trusting period hardcode --- LICENSE | 2 +- chain/cosmos/cosmos_chain.go | 15 ++++++++++----- local-interchain/go.mod | 2 +- local-interchain/go.sum | 4 ++-- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/LICENSE b/LICENSE index 261eeb9e9..ef1e8e097 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2024 Strangelove Ventures Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/chain/cosmos/cosmos_chain.go b/chain/cosmos/cosmos_chain.go index 7c8cf9e3c..a97446505 100644 --- a/chain/cosmos/cosmos_chain.go +++ b/chain/cosmos/cosmos_chain.go @@ -1085,6 +1085,11 @@ func (c *CosmosChain) StartProvider(testName string, ctx context.Context, additi return err } + trustingPeriod, err := time.ParseDuration(c.cfg.TrustingPeriod) + if err != nil { + return fmt.Errorf("failed to parse trusting period in 'StartProvider': %w", err) + } + for _, consumer := range c.Consumers { prop := ccvclient.ConsumerAdditionProposalJSON{ Title: fmt.Sprintf("Addition of %s consumer chain", consumer.cfg.Name), @@ -1101,7 +1106,7 @@ func (c *CosmosChain) StartProvider(testName string, ctx context.Context, additi TransferTimeoutPeriod: 3600000000000, ConsumerRedistributionFraction: "0.75", HistoricalEntries: 10000, - UnbondingPeriod: 1728000000000000, + UnbondingPeriod: trustingPeriod, Deposit: "100000000" + c.cfg.Denom, } @@ -1266,6 +1271,10 @@ func (c *CosmosChain) StartConsumer(testName string, ctx context.Context, additi consumerICS := c.GetNode().ICSVersion(ctx) providerICS := c.Provider.GetNode().ICSVersion(ctx) ccvStateMarshaled, err = c.transformCCVState(ctx, ccvStateMarshaled, consumerICS, providerICS) + c.log.Info("HERE STATE!", zap.String("GEN", string(ccvStateMarshaled))) + if err != nil { + return fmt.Errorf("failed to marshal ccv state to json: %w", err) + } // populate genesis file ccvconsumer module app_state. // fetch provider latest block (timestamp, root.hash, and next_validators_hash) to populate provider_consensus_state @@ -1323,10 +1332,6 @@ func (c *CosmosChain) StartConsumer(testName string, ctx context.Context, additi // ccvState.Params.Enabled = true // ccvStateMarshaled, err := c.cfg.EncodingConfig.Codec.MarshalJSON(ccvState) - c.log.Info("HERE STATE!", zap.String("GEN", string(ccvStateMarshaled))) - if err != nil { - return fmt.Errorf("failed to marshal ccv state to json: %w", err) - } var ccvStateUnmarshaled interface{} if err := json.Unmarshal(ccvStateMarshaled, &ccvStateUnmarshaled); err != nil { diff --git a/local-interchain/go.mod b/local-interchain/go.mod index a8a5fd215..01dc60831 100644 --- a/local-interchain/go.mod +++ b/local-interchain/go.mod @@ -82,7 +82,7 @@ require ( github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect github.com/cosmos/ibc-go/v8 v8.2.0 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect - github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240423100140-781f691e7f89 // indirect + github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240424193412-7cd900ad2a74 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/local-interchain/go.sum b/local-interchain/go.sum index 3606b7da6..5d7d86e5e 100644 --- a/local-interchain/go.sum +++ b/local-interchain/go.sum @@ -391,8 +391,8 @@ github.com/cosmos/ibc-go/v8 v8.2.0 h1:7oCzyy1sZCcgpeQLnHxC56brsSz3KWwQGKXalXwXFz github.com/cosmos/ibc-go/v8 v8.2.0/go.mod h1:wj3qx75iC/XNnsMqbPDCIGs0G6Y3E/lo3bdqCyoCy+8= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= -github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240423100140-781f691e7f89 h1:VVn2oLuiGmQIC3ovazpI0Z8R3zgXhgAx/lfOT5EfNHY= -github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240423100140-781f691e7f89/go.mod h1:c4oYjNwdfPKAhxzkwzTkkWROXKeUNPvc4VJHyNWrRU8= +github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240424193412-7cd900ad2a74 h1:6atU/xizTL10q6EprP7oRuvfgUP2F6puvutnVoE+FRc= +github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240424193412-7cd900ad2a74/go.mod h1:h/RkwOppo5AJj+1pkQyfjqU1MPdpohD/S6oEeAXpGZY= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= From 5f64d9a10009f737a72f60e8cd3e0040e458b16a Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 2 May 2024 10:41:07 -0500 Subject: [PATCH 08/14] ICS override config versions --- chain/cosmos/cosmos_chain.go | 81 +++++------------------------------- ibc/types.go | 11 +++++ 2 files changed, 22 insertions(+), 70 deletions(-) diff --git a/chain/cosmos/cosmos_chain.go b/chain/cosmos/cosmos_chain.go index a97446505..929e8f4a0 100644 --- a/chain/cosmos/cosmos_chain.go +++ b/chain/cosmos/cosmos_chain.go @@ -1139,7 +1139,7 @@ func (c *CosmosChain) StartProvider(testName string, ctx context.Context, additi return nil } -func (c *CosmosChain) transformCCVState(ctx context.Context, ccvState []byte, consumerVersion, providerVersion string) ([]byte, error) { +func (c *CosmosChain) transformCCVState(ctx context.Context, ccvState []byte, consumerVersion, providerVersion string, icsCfg ibc.ICSConfig) ([]byte, error) { // If they're both under 3.3.0, or if they're the same version, we don't need to transform the state. if semver.MajorMinor(providerVersion) == semver.MajorMinor(consumerVersion) || (semver.Compare(providerVersion, "v3.3.0") < 0 && semver.Compare(consumerVersion, "v3.3.0") < 0) { @@ -1162,6 +1162,15 @@ func (c *CosmosChain) transformCCVState(ctx context.Context, ccvState []byte, co imageVersion = consumerVersion } + if icsCfg.ProviderVerOverride != "" { + imageVersion = icsCfg.ProviderVerOverride + } + if icsCfg.ConsumerVerOverride != "" { + toVersion = icsCfg.ConsumerVerOverride + } + + c.log.Info("Transforming CCV state", zap.String("provider", providerVersion), zap.String("consumer", consumerVersion), zap.String("imageVersion", imageVersion), zap.String("toVersion", toVersion)) + err := c.GetNode().WriteFile(ctx, ccvState, "ccvconsumer.json") if err != nil { return nil, fmt.Errorf("failed to write ccv state to file: %w", err) @@ -1247,17 +1256,6 @@ func (c *CosmosChain) StartConsumer(testName string, ctx context.Context, additi } } - // providerHeight, err := c.Provider.Height(ctx) - // if err != nil { - // return fmt.Errorf("failed to query provider height") - // } - // providerHeightInt64 := int64(providerHeight) - - // block, err := c.Provider.getFullNode().Client.Block(ctx, &providerHeightInt64) - // if err != nil { - // return fmt.Errorf("failed to query provider block to initialize consumer client") - // } - genbz, err := validator0.GenesisFileContent(ctx) if err != nil { return err @@ -1270,69 +1268,12 @@ func (c *CosmosChain) StartConsumer(testName string, ctx context.Context, additi consumerICS := c.GetNode().ICSVersion(ctx) providerICS := c.Provider.GetNode().ICSVersion(ctx) - ccvStateMarshaled, err = c.transformCCVState(ctx, ccvStateMarshaled, consumerICS, providerICS) + ccvStateMarshaled, err = c.transformCCVState(ctx, ccvStateMarshaled, consumerICS, providerICS, chainCfg.InterchainSecurityConfig) c.log.Info("HERE STATE!", zap.String("GEN", string(ccvStateMarshaled))) if err != nil { return fmt.Errorf("failed to marshal ccv state to json: %w", err) } - // populate genesis file ccvconsumer module app_state. - // fetch provider latest block (timestamp, root.hash, and next_validators_hash) to populate provider_consensus_state - // populate provider_client_state with trusting and unbonding periods, latest_height.revision_height of height which is used for consensus state - // populate initial_val_set with provider val pubkeys and power - - // nextValidatorsHash := block.Block.NextValidatorsHash - // timestamp := block.Block.Time - // rootHash := block.Block.AppHash - - // page := int(1) - // perPage := int(1000) - // providerVals, err := c.Provider.getFullNode().Client.Validators(ctx, &providerHeightInt64, &page, &perPage) - // if err != nil { - // return fmt.Errorf("failed to get provider validators: %w", err) - // } - - // initialVals := make([]abcitypes.ValidatorUpdate, len(providerVals.Validators)) - // for i, val := range providerVals.Validators { - // initialVals[i] = abcitypes.ValidatorUpdate{ - // PubKey: crypto.PublicKey{Sum: &crypto.PublicKey_Ed25519{Ed25519: val.PubKey.Bytes()}}, - // Power: val.VotingPower, - // } - // } - - // providerCfg := c.Provider.Config() - - // clientState := ibctmtypes.NewClientState( - // providerCfg.ChainID, - // ibctmtypes.DefaultTrustLevel, - // DefaultProviderUnbondingPeriod/2, - // DefaultProviderUnbondingPeriod, // Needs to match provider unbonding period - // ccvprovidertypes.DefaultMaxClockDrift, - // clienttypes.Height{ - // RevisionHeight: uint64(providerHeight), - // RevisionNumber: clienttypes.ParseChainID(providerCfg.ChainID), - // }, - // commitmenttypes.GetSDKSpecs(), - // defaultUpgradePath, - // ) - - // root := commitmenttypes.MerkleRoot{ - // Hash: rootHash, - // } - - // consensusState := ibctmtypes.NewConsensusState(timestamp, root, nextValidatorsHash) - - // ccvState := ccvconsumertypes.NewInitialGenesisState( - // clientState, - // consensusState, - // initialVals, - // ccvconsumertypes.DefaultGenesisState().GetParams(), - // ) - - // ccvState.Params.Enabled = true - - // ccvStateMarshaled, err := c.cfg.EncodingConfig.Codec.MarshalJSON(ccvState) - var ccvStateUnmarshaled interface{} if err := json.Unmarshal(ccvStateMarshaled, &ccvStateUnmarshaled); err != nil { return fmt.Errorf("failed to unmarshal ccv state json: %w", err) diff --git a/ibc/types.go b/ibc/types.go index 015dfa7ce..bde9d5b63 100644 --- a/ibc/types.go +++ b/ibc/types.go @@ -62,6 +62,8 @@ type ChainConfig struct { UsingChainIDFlagCLI bool `yaml:"using-chain-id-flag-cli"` // Configuration describing additional sidecar processes. SidecarConfigs []SidecarConfig + // Configuration describing additional interchain security options. + InterchainSecurityConfig ICSConfig // CoinDecimals for the chains base micro/nano/atto token configuration. CoinDecimals *int64 // HostPortOverride exposes ports to the host. @@ -217,6 +219,10 @@ func (c ChainConfig) MergeChainSpecConfig(other ChainConfig) ChainConfig { c.ExposeAdditionalPorts = append(c.ExposeAdditionalPorts, other.ExposeAdditionalPorts...) } + if other.InterchainSecurityConfig != (ICSConfig{}) { + c.InterchainSecurityConfig = other.InterchainSecurityConfig + } + return c } @@ -402,3 +408,8 @@ type PathUpdateOptions struct { DstConnID *string DstChainID *string } + +type ICSConfig struct { + ProviderVerOverride string + ConsumerVerOverride string +} From 9a3e92f5890d2ba06bb1cd3e7515ca45002f4274 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Thu, 2 May 2024 11:22:53 -0500 Subject: [PATCH 09/14] minor nits --- chain/cosmos/cosmos_chain.go | 1 + examples/ibc/ics_test.go | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/cosmos/cosmos_chain.go b/chain/cosmos/cosmos_chain.go index 929e8f4a0..19b268742 100644 --- a/chain/cosmos/cosmos_chain.go +++ b/chain/cosmos/cosmos_chain.go @@ -1265,6 +1265,7 @@ func (c *CosmosChain) StartConsumer(testName string, ctx context.Context, additi if err != nil { return fmt.Errorf("failed to query provider for ccv state: %w", err) } + c.log.Info("BEFORE MIGRATION!", zap.String("GEN", string(ccvStateMarshaled))) consumerICS := c.GetNode().ICSVersion(ctx) providerICS := c.Provider.GetNode().ICSVersion(ctx) diff --git a/examples/ibc/ics_test.go b/examples/ibc/ics_test.go index 90715504b..f7cc04c5c 100644 --- a/examples/ibc/ics_test.go +++ b/examples/ibc/ics_test.go @@ -49,7 +49,6 @@ func TestICS(t *testing.T) { r := interchaintest.NewBuiltinRelayerFactory( ibc.CosmosRly, zaptest.NewLogger(t), - // relayer.CustomDockerImage("ghcr.io/cosmos/relayer", "v2.4.0", "1025:1025"), ).Build(t, client, network) // Prep Interchain From f456ced10d8422f89036a5d51d01488e74aa4b69 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Sat, 4 May 2024 16:35:54 -0500 Subject: [PATCH 10/14] revert: accidental penumbra change --- interchain.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/interchain.go b/interchain.go index f3d4e012a..87112e02d 100644 --- a/interchain.go +++ b/interchain.go @@ -336,6 +336,15 @@ func (ic *Interchain) Build(ctx context.Context, rep *testreporter.RelayerExecRe return fmt.Errorf("failed to track blocks: %w", err) } + // If any configured chain is an instance of Penumbra we need to initialize new pclientd instances for the + // newly created faucet account. + for c := range ic.chains { + err = CreatePenumbraClient(ctx, c, FaucetAccountKeyName) + if err != nil { + return err + } + } + if err := ic.configureRelayerKeys(ctx, rep); err != nil { // Error already wrapped with appropriate detail. return err From f2e746de351bed033d7678b89d602ecf3726838e Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Sat, 4 May 2024 16:41:01 -0500 Subject: [PATCH 11/14] parse propID for VoteOnProposalAllValidators --- chain/cosmos/cosmos_chain.go | 18 ++++++------------ local-interchain/interchain/start.go | 3 +-- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/chain/cosmos/cosmos_chain.go b/chain/cosmos/cosmos_chain.go index 19b268742..6a28b1939 100644 --- a/chain/cosmos/cosmos_chain.go +++ b/chain/cosmos/cosmos_chain.go @@ -1120,16 +1120,15 @@ func (c *CosmosChain) StartProvider(testName string, ctx context.Context, additi return err } - if err := c.VoteOnProposalAllValidators(ctx, propTx.ProposalID, ProposalVoteYes); err != nil { - return err - } - - // propTx.ProposalID propID, err := strconv.ParseUint(propTx.ProposalID, 10, 64) if err != nil { return fmt.Errorf("failed to parse proposal id: %w", err) } + if err := c.VoteOnProposalAllValidators(ctx, propID, ProposalVoteYes); err != nil { + return err + } + _, err = PollForProposalStatus(ctx, c, height, height+10, propID, govv1beta1.StatusPassed) if err != nil { return fmt.Errorf("proposal status did not change to passed in expected number of blocks: %w", err) @@ -1538,18 +1537,13 @@ func (c *CosmosChain) StartAllValSidecars(ctx context.Context) error { return eg.Wait() } -func (c *CosmosChain) VoteOnProposalAllValidators(ctx context.Context, proposalID string, vote string) error { - propID, err := strconv.ParseUint(proposalID, 10, 64) - if err != nil { - return fmt.Errorf("failed to parse proposalID %s: %w", proposalID, err) - } - +func (c *CosmosChain) VoteOnProposalAllValidators(ctx context.Context, proposalID uint64, vote string) error { var eg errgroup.Group for _, n := range c.Nodes() { if n.Validator { n := n eg.Go(func() error { - return n.VoteOnProposal(ctx, valKey, propID, vote) + return n.VoteOnProposal(ctx, valKey, proposalID, vote) }) } } diff --git a/local-interchain/interchain/start.go b/local-interchain/interchain/start.go index 56e39660f..5ddc106f7 100644 --- a/local-interchain/interchain/start.go +++ b/local-interchain/interchain/start.go @@ -134,8 +134,7 @@ func StartChain(installDir, chainCfgFile string, ac *types.AppStartConfig) { // Add Interchain Security chain pairs together if len(icsPair) > 0 { for provider, consumers := range icsPair { - var p ibc.Chain - var c ibc.Chain + var p, c ibc.Chain // a provider can have multiple consumers for _, consumer := range consumers { From 16d329f487bde67388cac4a75e5b469447f2540e Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Sat, 4 May 2024 16:44:19 -0500 Subject: [PATCH 12/14] hardcode ICS ver strings --- chain/cosmos/cosmos_chain.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/chain/cosmos/cosmos_chain.go b/chain/cosmos/cosmos_chain.go index 6a28b1939..4c82ae709 100644 --- a/chain/cosmos/cosmos_chain.go +++ b/chain/cosmos/cosmos_chain.go @@ -1138,19 +1138,24 @@ func (c *CosmosChain) StartProvider(testName string, ctx context.Context, additi return nil } +const ( + icsVer330 = "v3.3.0" + icsVer400 = "v4.0.0" +) + func (c *CosmosChain) transformCCVState(ctx context.Context, ccvState []byte, consumerVersion, providerVersion string, icsCfg ibc.ICSConfig) ([]byte, error) { // If they're both under 3.3.0, or if they're the same version, we don't need to transform the state. if semver.MajorMinor(providerVersion) == semver.MajorMinor(consumerVersion) || - (semver.Compare(providerVersion, "v3.3.0") < 0 && semver.Compare(consumerVersion, "v3.3.0") < 0) { + (semver.Compare(providerVersion, icsVer330) < 0 && semver.Compare(consumerVersion, icsVer330) < 0) { return ccvState, nil } var imageVersion, toVersion string // The trick here is that when we convert the state to a consumer < 3.3.0, we need a converter that knows about that version; those are >= 4.0.0, and need a --to flag. // Other than that, this is a question of using whichever version is newer. If it's the provider's, we need a --to flag to tell it the consumer version. // If it's the consumer's, we don't need a --to flag cause it'll assume the consumer version. - if semver.Compare(providerVersion, "v3.3.0") >= 0 && semver.Compare(providerVersion, consumerVersion) > 0 { - imageVersion = "v4.0.0" - if semver.Compare(providerVersion, "v4.0.0") > 0 { + if semver.Compare(providerVersion, icsVer330) >= 0 && semver.Compare(providerVersion, consumerVersion) > 0 { + imageVersion = icsVer400 + if semver.Compare(providerVersion, icsVer400) > 0 { imageVersion = providerVersion } toVersion = semver.Major(consumerVersion) From cd8c0ec57ff51f6dd3ebfea2defa3ded3b07d529 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Sat, 4 May 2024 16:56:22 -0500 Subject: [PATCH 13/14] use propID as uint64 for all test --- examples/cosmos/chain_core_test.go | 2 +- examples/cosmos/chain_param_change_test.go | 8 ++++---- examples/cosmos/chain_upgrade_ibc_test.go | 6 +++--- examples/hyperspace/hyperspace_test.go | 6 +++--- examples/polkadot/push_wasm_client_code_test.go | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/cosmos/chain_core_test.go b/examples/cosmos/chain_core_test.go index 3cb60f134..795ba8078 100644 --- a/examples/cosmos/chain_core_test.go +++ b/examples/cosmos/chain_core_test.go @@ -558,7 +558,7 @@ func testGov(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain, users require.EqualValues(t, v.Options[0].Option, govv1.VoteOption_VOTE_OPTION_YES) // pass vote with all validators - err = chain.VoteOnProposalAllValidators(ctx, "1", "yes") + err = chain.VoteOnProposalAllValidators(ctx, 1, "yes") require.NoError(t, err) // GovQueryProposalsV1 diff --git a/examples/cosmos/chain_param_change_test.go b/examples/cosmos/chain_param_change_test.go index d49713f4b..65a6c9222 100644 --- a/examples/cosmos/chain_param_change_test.go +++ b/examples/cosmos/chain_param_change_test.go @@ -74,14 +74,14 @@ func CosmosChainParamChangeTest(t *testing.T, name, version string) { paramTx, err := chain.ParamChangeProposal(ctx, chainUser.KeyName(), ¶m_change) require.NoError(t, err, "error submitting param change proposal tx") - err = chain.VoteOnProposalAllValidators(ctx, paramTx.ProposalID, cosmos.ProposalVoteYes) + propId, err := strconv.ParseUint(paramTx.ProposalID, 10, 64) + require.NoError(t, err, "failed to convert proposal ID to uint64") + + err = chain.VoteOnProposalAllValidators(ctx, propId, cosmos.ProposalVoteYes) require.NoError(t, err, "failed to submit votes") height, _ := chain.Height(ctx) - propId, err := strconv.ParseUint(paramTx.ProposalID, 10, 64) - require.NoError(t, err, "failed to convert proposal ID to uint64") - _, err = cosmos.PollForProposalStatus(ctx, chain, height, height+10, propId, govv1beta1.StatusPassed) require.NoError(t, err, "proposal status did not change to passed in expected number of blocks") diff --git a/examples/cosmos/chain_upgrade_ibc_test.go b/examples/cosmos/chain_upgrade_ibc_test.go index fc62f0d77..8d2ba6ec3 100644 --- a/examples/cosmos/chain_upgrade_ibc_test.go +++ b/examples/cosmos/chain_upgrade_ibc_test.go @@ -131,12 +131,12 @@ func CosmosChainUpgradeIBCTest(t *testing.T, chainName, initialVersion, upgradeC upgradeTx, err := chain.UpgradeProposal(ctx, chainUser.KeyName(), proposal) require.NoError(t, err, "error submitting software upgrade proposal tx") - err = chain.VoteOnProposalAllValidators(ctx, upgradeTx.ProposalID, cosmos.ProposalVoteYes) - require.NoError(t, err, "failed to submit votes") - propId, err := strconv.ParseUint(upgradeTx.ProposalID, 10, 64) require.NoError(t, err, "failed to convert proposal ID to uint64") + err = chain.VoteOnProposalAllValidators(ctx, propId, cosmos.ProposalVoteYes) + require.NoError(t, err, "failed to submit votes") + _, err = cosmos.PollForProposalStatus(ctx, chain, height, height+haltHeightDelta, propId, govv1beta1.StatusPassed) require.NoError(t, err, "proposal status did not change to passed in expected number of blocks") diff --git a/examples/hyperspace/hyperspace_test.go b/examples/hyperspace/hyperspace_test.go index 0dd738aad..615f80245 100644 --- a/examples/hyperspace/hyperspace_test.go +++ b/examples/hyperspace/hyperspace_test.go @@ -360,12 +360,12 @@ func pushWasmContractViaGov(t *testing.T, ctx context.Context, cosmosChain *cosm height, err := cosmosChain.Height(ctx) require.NoError(t, err, "error fetching height before submit upgrade proposal") - err = cosmosChain.VoteOnProposalAllValidators(ctx, proposalTx.ProposalID, cosmos.ProposalVoteYes) - require.NoError(t, err, "failed to submit votes") - propId, err := strconv.ParseUint(proposalTx.ProposalID, 10, 64) require.NoError(t, err, "failed to convert proposal ID to uint64") + err = cosmosChain.VoteOnProposalAllValidators(ctx, propId, cosmos.ProposalVoteYes) + require.NoError(t, err, "failed to submit votes") + _, err = cosmos.PollForProposalStatus(ctx, cosmosChain, height, height+heightDelta, propId, govv1beta1.StatusPassed) require.NoError(t, err, "proposal status did not change to passed in expected number of blocks") diff --git a/examples/polkadot/push_wasm_client_code_test.go b/examples/polkadot/push_wasm_client_code_test.go index f7ce8265d..2233b1f8b 100644 --- a/examples/polkadot/push_wasm_client_code_test.go +++ b/examples/polkadot/push_wasm_client_code_test.go @@ -138,12 +138,12 @@ func TestPushWasmClientCode(t *testing.T) { height, err := simdChain.Height(ctx) require.NoError(t, err, "error fetching height before submit upgrade proposal") - err = simdChain.VoteOnProposalAllValidators(ctx, proposalTx.ProposalID, cosmos.ProposalVoteYes) - require.NoError(t, err, "failed to submit votes") - propId, err := strconv.ParseUint(proposalTx.ProposalID, 10, 64) require.NoError(t, err, "failed to convert proposal ID to uint64") + err = simdChain.VoteOnProposalAllValidators(ctx, propId, cosmos.ProposalVoteYes) + require.NoError(t, err, "failed to submit votes") + _, err = cosmos.PollForProposalStatus(ctx, simdChain, height, height+heightDelta, propId, govv1beta1.StatusPassed) require.NoError(t, err, "proposal status did not change to passed in expected number of blocks") From 85b03ae968e8a62b36c6fa03663f2329cc1b8c33 Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Sat, 4 May 2024 21:32:30 -0500 Subject: [PATCH 14/14] license: `Strangelove Crypto, Inc.` --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index ef1e8e097..0058c90f2 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2024 Strangelove Ventures + Copyright 2024 Strangelove Crypto, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.