diff --git a/chain/cosmos/chain_node.go b/chain/cosmos/chain_node.go index 2ce6fdaf1..68fd0c493 100644 --- a/chain/cosmos/chain_node.go +++ b/chain/cosmos/chain_node.go @@ -225,7 +225,7 @@ func (tn *ChainNode) SetTestConfig(ctx context.Context) error { c["rpc"] = rpc - return testutil.ModifyTomlConfigFile( + if err := testutil.ModifyTomlConfigFile( ctx, tn.logger(), tn.DockerClient, @@ -233,6 +233,20 @@ func (tn *ChainNode) SetTestConfig(ctx context.Context) error { tn.VolumeName, "config/config.toml", c, + ); err != nil { + return err + } + + a := make(testutil.Toml) + a["minimum-gas-prices"] = tn.Chain.Config().GasPrices + return testutil.ModifyTomlConfigFile( + ctx, + tn.logger(), + tn.DockerClient, + tn.TestName, + tn.VolumeName, + "config/app.toml", + a, ) } @@ -570,18 +584,27 @@ type CosmosTx struct { RawLog string `json:"raw_log"` } -func (tn *ChainNode) SendIBCTransfer(ctx context.Context, channelID string, keyName string, amount ibc.WalletAmount, timeout *ibc.IBCTimeout) (string, error) { +func (tn *ChainNode) SendIBCTransfer( + ctx context.Context, + channelID string, + keyName string, + amount ibc.WalletAmount, + options ibc.TransferOptions, +) (string, error) { command := []string{ "ibc-transfer", "transfer", "transfer", channelID, amount.Address, fmt.Sprintf("%d%s", amount.Amount, amount.Denom), } - if timeout != nil { - if timeout.NanoSeconds > 0 { - command = append(command, "--packet-timeout-timestamp", fmt.Sprint(timeout.NanoSeconds)) - } else if timeout.Height > 0 { - command = append(command, "--packet-timeout-height", fmt.Sprintf("0-%d", timeout.Height)) + if options.Timeout != nil { + if options.Timeout.NanoSeconds > 0 { + command = append(command, "--packet-timeout-timestamp", fmt.Sprint(options.Timeout.NanoSeconds)) + } else if options.Timeout.Height > 0 { + command = append(command, "--packet-timeout-height", fmt.Sprintf("0-%d", options.Timeout.Height)) } } + if options.Memo != "" { + command = append(command, "--memo", options.Memo) + } return tn.ExecTx(ctx, keyName, command...) } diff --git a/chain/cosmos/cosmos_chain.go b/chain/cosmos/cosmos_chain.go index 48a3733a0..269d792df 100644 --- a/chain/cosmos/cosmos_chain.go +++ b/chain/cosmos/cosmos_chain.go @@ -227,8 +227,14 @@ func (c *CosmosChain) SendFunds(ctx context.Context, keyName string, amount ibc. } // Implements Chain interface -func (c *CosmosChain) SendIBCTransfer(ctx context.Context, channelID, keyName string, amount ibc.WalletAmount, timeout *ibc.IBCTimeout) (tx ibc.Tx, _ error) { - txHash, err := c.getFullNode().SendIBCTransfer(ctx, channelID, keyName, amount, timeout) +func (c *CosmosChain) SendIBCTransfer( + ctx context.Context, + channelID string, + keyName string, + amount ibc.WalletAmount, + options ibc.TransferOptions, +) (tx ibc.Tx, _ error) { + txHash, err := c.getFullNode().SendIBCTransfer(ctx, channelID, keyName, amount, options) if err != nil { return tx, fmt.Errorf("send ibc transfer: %w", err) } diff --git a/chain/cosmos/poll.go b/chain/cosmos/poll.go index 671c5f716..e6805c5c6 100644 --- a/chain/cosmos/poll.go +++ b/chain/cosmos/poll.go @@ -6,6 +6,7 @@ import ( "fmt" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/strangelove-ventures/ibctest/v6/ibc" "github.com/strangelove-ventures/ibctest/v6/testutil" ) @@ -58,3 +59,24 @@ func PollForMessage[T any](ctx context.Context, chain *CosmosChain, registry cod bp := testutil.BlockPoller[T]{CurrentHeight: chain.Height, PollFunc: doPoll} return bp.DoPoll(ctx, startHeight, maxHeight) } + +// PollForBalance polls until the balance matches +func PollForBalance(ctx context.Context, chain *CosmosChain, deltaBlocks uint64, balance ibc.WalletAmount) error { + h, err := chain.Height(ctx) + if err != nil { + return fmt.Errorf("failed to get height: %w", err) + } + doPoll := func(ctx context.Context, height uint64) (any, error) { + bal, err := chain.GetBalance(ctx, balance.Address, balance.Denom) + if err != nil { + return nil, err + } + if bal != balance.Amount { + return nil, fmt.Errorf("balance (%d) does not match expected: (%d)", bal, balance.Amount) + } + return nil, nil + } + bp := testutil.BlockPoller[any]{CurrentHeight: chain.Height, PollFunc: doPoll} + _, err = bp.DoPoll(ctx, h, h+deltaBlocks) + return err +} diff --git a/chain/penumbra/penumbra_app_node.go b/chain/penumbra/penumbra_app_node.go index ed0bbc696..6efb83c9a 100644 --- a/chain/penumbra/penumbra_app_node.go +++ b/chain/penumbra/penumbra_app_node.go @@ -188,7 +188,13 @@ func (p *PenumbraAppNode) SendFunds(ctx context.Context, keyName string, amount return errors.New("not yet implemented") } -func (p *PenumbraAppNode) SendIBCTransfer(ctx context.Context, channelID, keyName string, amount ibc.WalletAmount, timeout *ibc.IBCTimeout) (ibc.Tx, error) { +func (p *PenumbraAppNode) SendIBCTransfer( + ctx context.Context, + channelID string, + keyName string, + amount ibc.WalletAmount, + options ibc.TransferOptions, +) (ibc.Tx, error) { return ibc.Tx{}, errors.New("not yet implemented") } diff --git a/chain/penumbra/penumbra_chain.go b/chain/penumbra/penumbra_chain.go index a2c45f001..4138eb672 100644 --- a/chain/penumbra/penumbra_chain.go +++ b/chain/penumbra/penumbra_chain.go @@ -145,8 +145,14 @@ func (c *PenumbraChain) SendFunds(ctx context.Context, keyName string, amount ib } // Implements Chain interface -func (c *PenumbraChain) SendIBCTransfer(ctx context.Context, channelID, keyName string, amount ibc.WalletAmount, timeout *ibc.IBCTimeout) (ibc.Tx, error) { - return c.getRelayerNode().PenumbraAppNode.SendIBCTransfer(ctx, channelID, keyName, amount, timeout) +func (c *PenumbraChain) SendIBCTransfer( + ctx context.Context, + channelID string, + keyName string, + amount ibc.WalletAmount, + options ibc.TransferOptions, +) (ibc.Tx, error) { + return c.getRelayerNode().PenumbraAppNode.SendIBCTransfer(ctx, channelID, keyName, amount, options) } // Implements Chain interface diff --git a/chain/polkadot/polkadot_chain.go b/chain/polkadot/polkadot_chain.go index e0728b434..09a4390ec 100644 --- a/chain/polkadot/polkadot_chain.go +++ b/chain/polkadot/polkadot_chain.go @@ -538,7 +538,13 @@ func (c *PolkadotChain) SendFunds(ctx context.Context, keyName string, amount ib // SendIBCTransfer sends an IBC transfer returning a transaction or an error if the transfer failed. // Implements Chain interface. -func (c *PolkadotChain) SendIBCTransfer(ctx context.Context, channelID, keyName string, amount ibc.WalletAmount, timeout *ibc.IBCTimeout) (ibc.Tx, error) { +func (c *PolkadotChain) SendIBCTransfer( + ctx context.Context, + channelID string, + keyName string, + amount ibc.WalletAmount, + options ibc.TransferOptions, +) (ibc.Tx, error) { panic("not implemented yet") } diff --git a/conformance/flush.go b/conformance/flush.go index d2d05633a..47f1368a8 100644 --- a/conformance/flush.go +++ b/conformance/flush.go @@ -79,7 +79,7 @@ func TestRelayerFlushing(t *testing.T, ctx context.Context, cf ibctest.ChainFact Address: c1FaucetAddr, Denom: c0.Config().Denom, Amount: txAmount, - }, nil) + }, ibc.TransferOptions{}) req.NoError(err) req.NoError(tx.Validate()) diff --git a/conformance/test.go b/conformance/test.go index b2d05519b..03ca3b827 100644 --- a/conformance/test.go +++ b/conformance/test.go @@ -166,7 +166,7 @@ func sendIBCTransfersFromBothChainsWithTimeout( eg.Go(func() (err error) { for i, channel := range channels { srcChannelID := channel.ChannelID - srcTxs[i], err = srcChain.SendIBCTransfer(ctx, srcChannelID, srcUser.KeyName, testCoinSrcToDst, timeout) + srcTxs[i], err = srcChain.SendIBCTransfer(ctx, srcChannelID, srcUser.KeyName, testCoinSrcToDst, ibc.TransferOptions{Timeout: timeout}) if err != nil { return fmt.Errorf("failed to send ibc transfer from source: %w", err) } @@ -180,7 +180,7 @@ func sendIBCTransfersFromBothChainsWithTimeout( eg.Go(func() (err error) { for i, channel := range channels { dstChannelID := channel.Counterparty.ChannelID - dstTxs[i], err = dstChain.SendIBCTransfer(ctx, dstChannelID, dstUser.KeyName, testCoinDstToSrc, timeout) + dstTxs[i], err = dstChain.SendIBCTransfer(ctx, dstChannelID, dstUser.KeyName, testCoinDstToSrc, ibc.TransferOptions{Timeout: timeout}) if err != nil { return fmt.Errorf("failed to send ibc transfer from destination: %w", err) } diff --git a/docs/writeCustomTests.md b/docs/writeCustomTests.md index d30b069b7..5c5d0813b 100644 --- a/docs/writeCustomTests.md +++ b/docs/writeCustomTests.md @@ -216,13 +216,12 @@ osmosisRPC := osmosis.GetGRPCAddress() Here we send an IBC Transaction: ```go amountToSend := int64(1_000_000) -tx, err := gaia.SendIBCTransfer(ctx, gaiaChannelID, gaiaUser.KeyName, ibc.WalletAmount{ +transfer := ibc.WalletAmount{ Address: osmosisUser.Bech32Address(osmosis.Config().Bech32Prefix), Denom: gaia.Config().Denom, Amount: amountToSend, -}, - nil, -) +} +tx, err := gaia.SendIBCTransfer(ctx, gaiaChannelID, gaiaUser.KeyName, transfer, ibc.TransferOptions{}) ``` The `Exec` method allows any arbitrary command to be passed into a chain binary or relayer binary. diff --git a/examples/cosmos/light_client_test.go b/examples/cosmos/light_client_test.go index dcac3aa98..b06778042 100644 --- a/examples/cosmos/light_client_test.go +++ b/examples/cosmos/light_client_test.go @@ -80,13 +80,12 @@ func TestUpdateLightClients(t *testing.T) { amountToSend := int64(553255) // Unique amount to make log searching easier. dstAddress := osmoUser.Bech32Address(osmosis.Config().Bech32Prefix) - tx, err := gaia.SendIBCTransfer(ctx, chanID, gaiaUser.KeyName, ibc.WalletAmount{ + transfer := ibc.WalletAmount{ Address: dstAddress, Denom: gaia.Config().Denom, Amount: amountToSend, - }, - nil, - ) + } + tx, err := gaia.SendIBCTransfer(ctx, chanID, gaiaUser.KeyName, transfer, ibc.TransferOptions{}) require.NoError(t, err) require.NoError(t, tx.Validate()) diff --git a/examples/ibc/learn_ibc_test.go b/examples/ibc/learn_ibc_test.go index 1281df380..f6221d745 100644 --- a/examples/ibc/learn_ibc_test.go +++ b/examples/ibc/learn_ibc_test.go @@ -95,13 +95,12 @@ func TestLearn(t *testing.T) { // Send Transaction amountToSend := int64(1_000_000) dstAddress := osmosisUser.Bech32Address(osmosis.Config().Bech32Prefix) - tx, err := gaia.SendIBCTransfer(ctx, gaiaChannelID, gaiaUser.KeyName, ibc.WalletAmount{ + transfer := ibc.WalletAmount{ Address: dstAddress, Denom: gaia.Config().Denom, Amount: amountToSend, - }, - nil, - ) + } + tx, err := gaia.SendIBCTransfer(ctx, gaiaChannelID, gaiaUser.KeyName, transfer, ibc.TransferOptions{}) require.NoError(t, err) require.NoError(t, tx.Validate()) diff --git a/examples/ibc/packet_forward_test.go b/examples/ibc/packet_forward_test.go index f69d66c20..a9770c591 100644 --- a/examples/ibc/packet_forward_test.go +++ b/examples/ibc/packet_forward_test.go @@ -2,18 +2,36 @@ package ibc_test import ( "context" - "fmt" + "encoding/json" "testing" + "time" transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types" ibctest "github.com/strangelove-ventures/ibctest/v6" + "github.com/strangelove-ventures/ibctest/v6/chain/cosmos" "github.com/strangelove-ventures/ibctest/v6/ibc" + "github.com/strangelove-ventures/ibctest/v6/relayer" + "github.com/strangelove-ventures/ibctest/v6/relayer/rly" "github.com/strangelove-ventures/ibctest/v6/testreporter" "github.com/strangelove-ventures/ibctest/v6/testutil" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" ) +type PacketMetadata struct { + Forward *ForwardMetadata `json:"forward"` +} + +type ForwardMetadata struct { + Receiver string `json:"receiver"` + Port string `json:"port"` + Channel string `json:"channel"` + Timeout time.Duration `json:"timeout"` + Retries *uint8 `json:"retries,omitempty"` + Next *string `json:"next,omitempty"` + RefundSequence *uint64 `json:"refund_sequence,omitempty"` +} + func TestPacketForwardMiddleware(t *testing.T) { if testing.Short() { t.Skip("skipping in short mode") @@ -26,43 +44,54 @@ func TestPacketForwardMiddleware(t *testing.T) { ctx := context.Background() + chainID_A, chainID_B, chainID_C, chainID_D := "chain-a", "chain-b", "chain-c", "chain-d" + cf := ibctest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*ibctest.ChainSpec{ - {Name: "gaia", ChainName: "gaia-fork", Version: "bugfix-replace_default_transfer_with_router_module"}, - {Name: "osmosis", ChainName: "osmosis", Version: "v11.0.1"}, - {Name: "juno", ChainName: "juno", Version: "v9.0.0"}, + {Name: "gaia", Version: "strangelove-forward_middleware_memo_v3", ChainConfig: ibc.ChainConfig{ChainID: chainID_A, GasPrices: "0.0uatom"}}, + {Name: "gaia", Version: "strangelove-forward_middleware_memo_v3", ChainConfig: ibc.ChainConfig{ChainID: chainID_B, GasPrices: "0.0uatom"}}, + {Name: "gaia", Version: "strangelove-forward_middleware_memo_v3", ChainConfig: ibc.ChainConfig{ChainID: chainID_C, GasPrices: "0.0uatom"}}, + {Name: "gaia", Version: "strangelove-forward_middleware_memo_v3", ChainConfig: ibc.ChainConfig{ChainID: chainID_D, GasPrices: "0.0uatom"}}, }) chains, err := cf.Chains(t.Name()) require.NoError(t, err) - gaia, osmosis, juno := chains[0], chains[1], chains[2] + chainA, chainB, chainC, chainD := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain), chains[2].(*cosmos.CosmosChain), chains[3].(*cosmos.CosmosChain) r := ibctest.NewBuiltinRelayerFactory( ibc.CosmosRly, zaptest.NewLogger(t), - ).Build( - t, client, network, - ) + // TODO remove this line once default rly version includes https://github.com/cosmos/relayer/pull/1038 + relayer.CustomDockerImage("ghcr.io/cosmos/relayer", "main", rly.RlyDefaultUidGid), + ).Build(t, client, network) - const pathOsmoHub = "osmohub" - const pathJunoHub = "junohub" + const pathAB = "ab" + const pathBC = "bc" + const pathCD = "cd" ic := ibctest.NewInterchain(). - AddChain(osmosis). - AddChain(gaia). - AddChain(juno). + AddChain(chainA). + AddChain(chainB). + AddChain(chainC). + AddChain(chainD). AddRelayer(r, "relayer"). AddLink(ibctest.InterchainLink{ - Chain1: osmosis, - Chain2: gaia, + Chain1: chainA, + Chain2: chainB, Relayer: r, - Path: pathOsmoHub, + Path: pathAB, }). AddLink(ibctest.InterchainLink{ - Chain1: gaia, - Chain2: juno, + Chain1: chainB, + Chain2: chainC, Relayer: r, - Path: pathJunoHub, + Path: pathBC, + }). + AddLink(ibctest.InterchainLink{ + Chain1: chainC, + Chain2: chainD, + Relayer: r, + Path: pathCD, }) require.NoError(t, ic.Build(ctx, eRep, ibctest.InterchainBuildOptions{ @@ -78,16 +107,25 @@ func TestPacketForwardMiddleware(t *testing.T) { }) const userFunds = int64(10_000_000_000) - users := ibctest.GetAndFundTestUsers(t, ctx, t.Name(), userFunds, osmosis, gaia, juno) + users := ibctest.GetAndFundTestUsers(t, ctx, t.Name(), userFunds, chainA, chainB, chainC, chainD) + + abChan, err := ibc.GetTransferChannel(ctx, r, eRep, chainID_A, chainID_B) + require.NoError(t, err) - osmoChannels, err := r.GetChannels(ctx, eRep, osmosis.Config().ChainID) + baChan := abChan.Counterparty + + cbChan, err := ibc.GetTransferChannel(ctx, r, eRep, chainID_C, chainID_B) require.NoError(t, err) - junoChannels, err := r.GetChannels(ctx, eRep, juno.Config().ChainID) + bcChan := cbChan.Counterparty + + dcChan, err := ibc.GetTransferChannel(ctx, r, eRep, chainID_D, chainID_C) require.NoError(t, err) + cdChan := dcChan.Counterparty + // Start the relayer on both paths - err = r.StartRelayer(ctx, eRep, pathOsmoHub, pathJunoHub) + err = r.StartRelayer(ctx, eRep, pathAB, pathBC, pathCD) require.NoError(t, err) t.Cleanup( @@ -100,96 +138,482 @@ func TestPacketForwardMiddleware(t *testing.T) { ) // Get original account balances - osmosisUser, gaiaUser, junoUser := users[0], users[1], users[2] + userA, userB, userC, userD := users[0], users[1], users[2], users[3] - osmosisBalOG, err := osmosis.GetBalance(ctx, osmosisUser.Bech32Address(osmosis.Config().Bech32Prefix), osmosis.Config().Denom) - require.NoError(t, err) - - // Send packet from Osmosis->Hub->Juno - // receiver format: {intermediate_refund_address}|{foward_port}/{forward_channel}:{final_destination_address} const transferAmount int64 = 100000 - gaiaJunoChan := junoChannels[0].Counterparty - receiver := fmt.Sprintf("%s|%s/%s:%s", gaiaUser.Bech32Address(gaia.Config().Bech32Prefix), gaiaJunoChan.PortID, gaiaJunoChan.ChannelID, junoUser.Bech32Address(juno.Config().Bech32Prefix)) - transfer := ibc.WalletAmount{ - Address: receiver, - Denom: osmosis.Config().Denom, - Amount: transferAmount, - } - - osmosisGaiaChan := osmoChannels[0] - _, err = osmosis.SendIBCTransfer(ctx, osmosisGaiaChan.ChannelID, osmosisUser.KeyName, transfer, nil) - require.NoError(t, err) - - // Wait for transfer to be relayed - err = testutil.WaitForBlocks(ctx, 10, gaia) - require.NoError(t, err) - - // Check that the funds sent are gone from the acc on osmosis - osmosisBal, err := osmosis.GetBalance(ctx, osmosisUser.Bech32Address(osmosis.Config().Bech32Prefix), osmosis.Config().Denom) - require.NoError(t, err) - require.Equal(t, osmosisBalOG-transferAmount, osmosisBal) // Compose the prefixed denoms and ibc denom for asserting balances - gaiaOsmoChan := osmoChannels[0].Counterparty - junoGaiaChan := junoChannels[0] - firstHopDenom := transfertypes.GetPrefixedDenom(gaiaOsmoChan.PortID, gaiaOsmoChan.ChannelID, osmosis.Config().Denom) - secondHopDenom := transfertypes.GetPrefixedDenom(junoGaiaChan.PortID, junoGaiaChan.ChannelID, firstHopDenom) - dstIbcDenom := transfertypes.ParseDenomTrace(secondHopDenom) - - // Check that the funds sent are present in the acc on juno - junoBal, err := juno.GetBalance(ctx, junoUser.Bech32Address(juno.Config().Bech32Prefix), dstIbcDenom.IBCDenom()) - require.NoError(t, err) - require.Equal(t, transferAmount, junoBal) - - // Send packet back from Juno->Hub->Osmosis - receiver = fmt.Sprintf("%s|%s/%s:%s", gaiaUser.Bech32Address(gaia.Config().Bech32Prefix), gaiaOsmoChan.PortID, gaiaOsmoChan.ChannelID, osmosisUser.Bech32Address(osmosis.Config().Bech32Prefix)) - transfer = ibc.WalletAmount{ - Address: receiver, - Denom: dstIbcDenom.IBCDenom(), - Amount: transferAmount, - } - - _, err = juno.SendIBCTransfer(ctx, junoGaiaChan.ChannelID, junoUser.KeyName, transfer, nil) - require.NoError(t, err) - - // Wait for transfer to be relayed - err = testutil.WaitForBlocks(ctx, 10, gaia) - require.NoError(t, err) - - // Check that the funds sent are gone from the acc on juno - junoBal, err = juno.GetBalance(ctx, junoUser.Bech32Address(juno.Config().Bech32Prefix), dstIbcDenom.IBCDenom()) - require.NoError(t, err) - require.Equal(t, int64(0), junoBal) + firstHopDenom := transfertypes.GetPrefixedDenom(baChan.PortID, baChan.ChannelID, chainA.Config().Denom) + secondHopDenom := transfertypes.GetPrefixedDenom(cbChan.PortID, cbChan.ChannelID, firstHopDenom) + thirdHopDenom := transfertypes.GetPrefixedDenom(dcChan.PortID, dcChan.ChannelID, secondHopDenom) + + firstHopDenomTrace := transfertypes.ParseDenomTrace(firstHopDenom) + secondHopDenomTrace := transfertypes.ParseDenomTrace(secondHopDenom) + thirdHopDenomTrace := transfertypes.ParseDenomTrace(thirdHopDenom) + + firstHopIBCDenom := firstHopDenomTrace.IBCDenom() + secondHopIBCDenom := secondHopDenomTrace.IBCDenom() + thirdHopIBCDenom := thirdHopDenomTrace.IBCDenom() + + firstHopEscrowAccount := transfertypes.GetEscrowAddress(abChan.PortID, abChan.ChannelID).String() + secondHopEscrowAccount := transfertypes.GetEscrowAddress(bcChan.PortID, bcChan.ChannelID).String() + thirdHopEscrowAccount := transfertypes.GetEscrowAddress(cdChan.PortID, abChan.ChannelID).String() + + t.Run("multi-hop a->b->c->d", func(t *testing.T) { + // Send packet from Chain A->Chain B->Chain C->Chain D + + transfer := ibc.WalletAmount{ + Address: userB.Bech32Address(chainB.Config().Bech32Prefix), + Denom: chainA.Config().Denom, + Amount: transferAmount, + } + + secondHopMetadata := &PacketMetadata{ + Forward: &ForwardMetadata{ + Receiver: userD.Bech32Address(chainD.Config().Bech32Prefix), + Channel: cdChan.ChannelID, + Port: cdChan.PortID, + }, + } + nextBz, err := json.Marshal(secondHopMetadata) + require.NoError(t, err) + next := string(nextBz) + + firstHopMetadata := &PacketMetadata{ + Forward: &ForwardMetadata{ + Receiver: userC.Bech32Address(chainC.Config().Bech32Prefix), + Channel: bcChan.ChannelID, + Port: bcChan.PortID, + Next: &next, + }, + } + + memo, err := json.Marshal(firstHopMetadata) + require.NoError(t, err) + + chainAHeight, err := chainA.Height(ctx) + require.NoError(t, err) + + transferTx, err := chainA.SendIBCTransfer(ctx, abChan.ChannelID, userA.KeyName, transfer, ibc.TransferOptions{Memo: string(memo)}) + require.NoError(t, err) + _, err = testutil.PollForAck(ctx, chainA, chainAHeight, chainAHeight+30, transferTx.Packet) + require.NoError(t, err) + err = testutil.WaitForBlocks(ctx, 1, chainA) + require.NoError(t, err) + + chainABalance, err := chainA.GetBalance(ctx, userA.Bech32Address(chainA.Config().Bech32Prefix), chainA.Config().Denom) + require.NoError(t, err) + + chainBBalance, err := chainB.GetBalance(ctx, userB.Bech32Address(chainB.Config().Bech32Prefix), firstHopIBCDenom) + require.NoError(t, err) + + chainCBalance, err := chainC.GetBalance(ctx, userC.Bech32Address(chainC.Config().Bech32Prefix), secondHopIBCDenom) + require.NoError(t, err) + + chainDBalance, err := chainD.GetBalance(ctx, userD.Bech32Address(chainD.Config().Bech32Prefix), thirdHopIBCDenom) + require.NoError(t, err) + + require.Equal(t, userFunds-transferAmount, chainABalance) + require.Equal(t, int64(0), chainBBalance) + require.Equal(t, int64(0), chainCBalance) + require.Equal(t, transferAmount, chainDBalance) + + firstHopEscrowBalance, err := chainA.GetBalance(ctx, firstHopEscrowAccount, chainA.Config().Denom) + require.NoError(t, err) + + secondHopEscrowBalance, err := chainB.GetBalance(ctx, secondHopEscrowAccount, firstHopIBCDenom) + require.NoError(t, err) + + thirdHopEscrowBalance, err := chainC.GetBalance(ctx, thirdHopEscrowAccount, secondHopIBCDenom) + require.NoError(t, err) + + require.Equal(t, transferAmount, firstHopEscrowBalance) + require.Equal(t, transferAmount, secondHopEscrowBalance) + require.Equal(t, transferAmount, thirdHopEscrowBalance) + }) - // Check that the funds sent are present in the acc on osmosis - osmosisBal, err = osmosis.GetBalance(ctx, osmosisUser.Bech32Address(osmosis.Config().Bech32Prefix), osmosis.Config().Denom) - require.NoError(t, err) - require.Equal(t, osmosisBalOG, osmosisBal) - - // Send a malformed packet with invalid receiver address from Osmosis->Hub->Juno - // This should succeed in the first hop and fail to make the second hop; funds should end up in the intermediary account. - receiver = fmt.Sprintf("%s|%s/%s:%s", gaiaUser.Bech32Address(gaia.Config().Bech32Prefix), gaiaJunoChan.PortID, gaiaJunoChan.ChannelID, "xyz1t8eh66t2w5k67kwurmn5gqhtq6d2ja0vp7jmmq") - transfer = ibc.WalletAmount{ - Address: receiver, - Denom: osmosis.Config().Denom, - Amount: transferAmount, - } + t.Run("multi-hop denom unwind d->c->b->a", func(t *testing.T) { + // Send packet back from Chain D->Chain C->Chain B->Chain A + transfer := ibc.WalletAmount{ + Address: userC.Bech32Address(chainC.Config().Bech32Prefix), + Denom: thirdHopIBCDenom, + Amount: transferAmount, + } + + secondHopMetadata := &PacketMetadata{ + Forward: &ForwardMetadata{ + Receiver: userA.Bech32Address(chainA.Config().Bech32Prefix), + Channel: baChan.ChannelID, + Port: baChan.PortID, + }, + } + + nextBz, err := json.Marshal(secondHopMetadata) + require.NoError(t, err) + + next := string(nextBz) + + firstHopMetadata := &PacketMetadata{ + Forward: &ForwardMetadata{ + Receiver: userB.Bech32Address(chainB.Config().Bech32Prefix), + Channel: cbChan.ChannelID, + Port: cbChan.PortID, + Next: &next, + }, + } + + memo, err := json.Marshal(firstHopMetadata) + require.NoError(t, err) + + chainDHeight, err := chainD.Height(ctx) + require.NoError(t, err) + + transferTx, err := chainD.SendIBCTransfer(ctx, dcChan.ChannelID, userD.KeyName, transfer, ibc.TransferOptions{Memo: string(memo)}) + require.NoError(t, err) + _, err = testutil.PollForAck(ctx, chainD, chainDHeight, chainDHeight+30, transferTx.Packet) + require.NoError(t, err) + err = testutil.WaitForBlocks(ctx, 1, chainA) + require.NoError(t, err) + + // assert balances for user controlled wallets + chainDBalance, err := chainD.GetBalance(ctx, userD.Bech32Address(chainD.Config().Bech32Prefix), thirdHopIBCDenom) + require.NoError(t, err) + + chainCBalance, err := chainC.GetBalance(ctx, userC.Bech32Address(chainC.Config().Bech32Prefix), secondHopIBCDenom) + require.NoError(t, err) + + chainBBalance, err := chainB.GetBalance(ctx, userB.Bech32Address(chainB.Config().Bech32Prefix), firstHopIBCDenom) + require.NoError(t, err) + + chainABalance, err := chainA.GetBalance(ctx, userA.Bech32Address(chainA.Config().Bech32Prefix), chainA.Config().Denom) + require.NoError(t, err) + + require.Equal(t, int64(0), chainDBalance) + require.Equal(t, int64(0), chainCBalance) + require.Equal(t, int64(0), chainBBalance) + require.Equal(t, userFunds, chainABalance) + + // assert balances for IBC escrow accounts + firstHopEscrowBalance, err := chainA.GetBalance(ctx, firstHopEscrowAccount, chainA.Config().Denom) + require.NoError(t, err) + + secondHopEscrowBalance, err := chainB.GetBalance(ctx, secondHopEscrowAccount, firstHopIBCDenom) + require.NoError(t, err) + + thirdHopEscrowBalance, err := chainC.GetBalance(ctx, thirdHopEscrowAccount, secondHopIBCDenom) + require.NoError(t, err) + + require.Equal(t, int64(0), firstHopEscrowBalance) + require.Equal(t, int64(0), secondHopEscrowBalance) + require.Equal(t, int64(0), thirdHopEscrowBalance) + }) - _, err = osmosis.SendIBCTransfer(ctx, osmosisGaiaChan.ChannelID, osmosisUser.KeyName, transfer, nil) - require.NoError(t, err) + t.Run("forward ack error refund", func(t *testing.T) { + // Send a malformed packet with invalid receiver address from Chain A->Chain B->Chain C + // This should succeed in the first hop and fail to make the second hop; funds should then be refunded to Chain A. + transfer := ibc.WalletAmount{ + Address: userB.Bech32Address(chainB.Config().Bech32Prefix), + Denom: chainA.Config().Denom, + Amount: transferAmount, + } + + metadata := &PacketMetadata{ + Forward: &ForwardMetadata{ + Receiver: "xyz1t8eh66t2w5k67kwurmn5gqhtq6d2ja0vp7jmmq", // malformed receiver address on Chain C + Channel: bcChan.ChannelID, + Port: bcChan.PortID, + }, + } + + memo, err := json.Marshal(metadata) + require.NoError(t, err) + + chainAHeight, err := chainA.Height(ctx) + require.NoError(t, err) + + transferTx, err := chainA.SendIBCTransfer(ctx, abChan.ChannelID, userA.KeyName, transfer, ibc.TransferOptions{Memo: string(memo)}) + require.NoError(t, err) + _, err = testutil.PollForAck(ctx, chainA, chainAHeight, chainAHeight+25, transferTx.Packet) + require.NoError(t, err) + err = testutil.WaitForBlocks(ctx, 1, chainA) + require.NoError(t, err) + + // assert balances for user controlled wallets + chainABalance, err := chainA.GetBalance(ctx, userA.Bech32Address(chainA.Config().Bech32Prefix), chainA.Config().Denom) + require.NoError(t, err) + + chainBBalance, err := chainB.GetBalance(ctx, userB.Bech32Address(chainB.Config().Bech32Prefix), firstHopIBCDenom) + require.NoError(t, err) + + chainCBalance, err := chainC.GetBalance(ctx, userC.Bech32Address(chainC.Config().Bech32Prefix), secondHopIBCDenom) + require.NoError(t, err) + + require.Equal(t, userFunds, chainABalance) + require.Equal(t, int64(0), chainBBalance) + require.Equal(t, int64(0), chainCBalance) + + // assert balances for IBC escrow accounts + firstHopEscrowBalance, err := chainA.GetBalance(ctx, firstHopEscrowAccount, chainA.Config().Denom) + require.NoError(t, err) + + secondHopEscrowBalance, err := chainB.GetBalance(ctx, secondHopEscrowAccount, firstHopIBCDenom) + require.NoError(t, err) + + require.Equal(t, int64(0), firstHopEscrowBalance) + require.Equal(t, int64(0), secondHopEscrowBalance) + }) - // Wait for transfer to be relayed - err = testutil.WaitForBlocks(ctx, 10, gaia) - require.NoError(t, err) + t.Run("forward timeout refund", func(t *testing.T) { + // Send packet from Chain A->Chain B->Chain C with the timeout so low for B->C transfer that it can not make it from B to C, which should result in a refund from B to A after two retries. + transfer := ibc.WalletAmount{ + Address: userB.Bech32Address(chainB.Config().Bech32Prefix), + Denom: chainA.Config().Denom, + Amount: transferAmount, + } + + retries := uint8(2) + metadata := &PacketMetadata{ + Forward: &ForwardMetadata{ + Receiver: userC.Bech32Address(chainC.Config().Bech32Prefix), + Channel: bcChan.ChannelID, + Port: bcChan.PortID, + Retries: &retries, + Timeout: 1 * time.Second, + }, + } + + memo, err := json.Marshal(metadata) + require.NoError(t, err) + + chainAHeight, err := chainA.Height(ctx) + require.NoError(t, err) + + transferTx, err := chainA.SendIBCTransfer(ctx, abChan.ChannelID, userA.KeyName, transfer, ibc.TransferOptions{Memo: string(memo)}) + require.NoError(t, err) + _, err = testutil.PollForAck(ctx, chainA, chainAHeight, chainAHeight+25, transferTx.Packet) + require.NoError(t, err) + err = testutil.WaitForBlocks(ctx, 1, chainA) + require.NoError(t, err) + + // assert balances for user controlled wallets + chainABalance, err := chainA.GetBalance(ctx, userA.Bech32Address(chainA.Config().Bech32Prefix), chainA.Config().Denom) + require.NoError(t, err) + + chainBBalance, err := chainB.GetBalance(ctx, userB.Bech32Address(chainB.Config().Bech32Prefix), firstHopIBCDenom) + require.NoError(t, err) + + chainCBalance, err := chainC.GetBalance(ctx, userC.Bech32Address(chainC.Config().Bech32Prefix), secondHopIBCDenom) + require.NoError(t, err) + + require.Equal(t, userFunds, chainABalance) + require.Equal(t, int64(0), chainBBalance) + require.Equal(t, int64(0), chainCBalance) + + firstHopEscrowBalance, err := chainA.GetBalance(ctx, firstHopEscrowAccount, chainA.Config().Denom) + require.NoError(t, err) + + secondHopEscrowBalance, err := chainB.GetBalance(ctx, secondHopEscrowAccount, firstHopIBCDenom) + require.NoError(t, err) + + require.Equal(t, int64(0), firstHopEscrowBalance) + require.Equal(t, int64(0), secondHopEscrowBalance) + }) - // Check that the funds sent are gone from the acc on osmosis - osmosisBal, err = osmosis.GetBalance(ctx, osmosisUser.Bech32Address(osmosis.Config().Bech32Prefix), osmosis.Config().Denom) - require.NoError(t, err) - require.Equal(t, osmosisBalOG-transferAmount, osmosisBal) + t.Run("multi-hop ack error refund", func(t *testing.T) { + // Send a malformed packet with invalid receiver address from Chain A->Chain B->Chain C->Chain D + // This should succeed in the first hop and second hop, then fail to make the third hop. + // Funds should be refunded to Chain B and then to Chain A via acknowledgements with errors. + transfer := ibc.WalletAmount{ + Address: userB.Bech32Address(chainB.Config().Bech32Prefix), + Denom: chainA.Config().Denom, + Amount: transferAmount, + } + + secondHopMetadata := &PacketMetadata{ + Forward: &ForwardMetadata{ + Receiver: "xyz1t8eh66t2w5k67kwurmn5gqhtq6d2ja0vp7jmmq", // malformed receiver address on chain D + Channel: cdChan.ChannelID, + Port: cdChan.PortID, + }, + } + + nextBz, err := json.Marshal(secondHopMetadata) + require.NoError(t, err) + + next := string(nextBz) + + firstHopMetadata := &PacketMetadata{ + Forward: &ForwardMetadata{ + Receiver: userC.Bech32Address(chainC.Config().Bech32Prefix), + Channel: bcChan.ChannelID, + Port: bcChan.PortID, + Next: &next, + }, + } + + memo, err := json.Marshal(firstHopMetadata) + require.NoError(t, err) + + chainAHeight, err := chainA.Height(ctx) + require.NoError(t, err) + + transferTx, err := chainA.SendIBCTransfer(ctx, abChan.ChannelID, userA.KeyName, transfer, ibc.TransferOptions{Memo: string(memo)}) + require.NoError(t, err) + _, err = testutil.PollForAck(ctx, chainA, chainAHeight, chainAHeight+30, transferTx.Packet) + require.NoError(t, err) + err = testutil.WaitForBlocks(ctx, 1, chainA) + require.NoError(t, err) + + // assert balances for user controlled wallets + chainDBalance, err := chainD.GetBalance(ctx, userD.Bech32Address(chainD.Config().Bech32Prefix), thirdHopIBCDenom) + require.NoError(t, err) + + chainCBalance, err := chainC.GetBalance(ctx, userC.Bech32Address(chainC.Config().Bech32Prefix), secondHopIBCDenom) + require.NoError(t, err) + + chainBBalance, err := chainB.GetBalance(ctx, userB.Bech32Address(chainB.Config().Bech32Prefix), firstHopIBCDenom) + require.NoError(t, err) + + chainABalance, err := chainA.GetBalance(ctx, userA.Bech32Address(chainA.Config().Bech32Prefix), chainA.Config().Denom) + require.NoError(t, err) + + require.Equal(t, userFunds, chainABalance) + require.Equal(t, int64(0), chainBBalance) + require.Equal(t, int64(0), chainCBalance) + require.Equal(t, int64(0), chainDBalance) + + // assert balances for IBC escrow accounts + firstHopEscrowBalance, err := chainA.GetBalance(ctx, firstHopEscrowAccount, chainA.Config().Denom) + require.NoError(t, err) + + secondHopEscrowBalance, err := chainB.GetBalance(ctx, secondHopEscrowAccount, firstHopIBCDenom) + require.NoError(t, err) + + thirdHopEscrowBalance, err := chainC.GetBalance(ctx, thirdHopEscrowAccount, secondHopIBCDenom) + require.NoError(t, err) + + require.Equal(t, int64(0), firstHopEscrowBalance) + require.Equal(t, int64(0), secondHopEscrowBalance) + require.Equal(t, int64(0), thirdHopEscrowBalance) + }) - // Check that the funds sent ended up in the acc on gaia - intermediaryIBCDenom := transfertypes.ParseDenomTrace(firstHopDenom) - gaiaBal, err := gaia.GetBalance(ctx, gaiaUser.Bech32Address(gaia.Config().Bech32Prefix), intermediaryIBCDenom.IBCDenom()) - require.NoError(t, err) - require.Equal(t, transferAmount, gaiaBal) + t.Run("multi-hop through native chain ack error refund", func(t *testing.T) { + // send normal IBC transfer from B->A to get funds in IBC denom, then do multihop A->B(native)->C->D + // this lets us test the burn from escrow account on chain C and the escrow to escrow transfer on chain B. + + // Compose the prefixed denoms and ibc denom for asserting balances + baDenom := transfertypes.GetPrefixedDenom(abChan.PortID, abChan.ChannelID, chainB.Config().Denom) + bcDenom := transfertypes.GetPrefixedDenom(cbChan.PortID, cbChan.ChannelID, chainB.Config().Denom) + cdDenom := transfertypes.GetPrefixedDenom(dcChan.PortID, dcChan.ChannelID, bcDenom) + + baDenomTrace := transfertypes.ParseDenomTrace(baDenom) + bcDenomTrace := transfertypes.ParseDenomTrace(bcDenom) + cdDenomTrace := transfertypes.ParseDenomTrace(cdDenom) + + baIBCDenom := baDenomTrace.IBCDenom() + bcIBCDenom := bcDenomTrace.IBCDenom() + cdIBCDenom := cdDenomTrace.IBCDenom() + + transfer := ibc.WalletAmount{ + Address: userA.Bech32Address(chainA.Config().Bech32Prefix), + Denom: chainB.Config().Denom, + Amount: transferAmount, + } + + chainBHeight, err := chainB.Height(ctx) + require.NoError(t, err) + + transferTx, err := chainB.SendIBCTransfer(ctx, baChan.ChannelID, userB.KeyName, transfer, ibc.TransferOptions{}) + require.NoError(t, err) + _, err = testutil.PollForAck(ctx, chainB, chainBHeight, chainBHeight+10, transferTx.Packet) + require.NoError(t, err) + err = testutil.WaitForBlocks(ctx, 1, chainB) + require.NoError(t, err) + + // assert balance for user controlled wallet + chainABalance, err := chainA.GetBalance(ctx, userA.Bech32Address(chainA.Config().Bech32Prefix), baIBCDenom) + require.NoError(t, err) + + baEscrowBalance, err := chainB.GetBalance(ctx, transfertypes.GetEscrowAddress(baChan.PortID, baChan.ChannelID).String(), chainB.Config().Denom) + require.NoError(t, err) + + require.Equal(t, transferAmount, chainABalance) + require.Equal(t, transferAmount, baEscrowBalance) + + // Send a malformed packet with invalid receiver address from Chain A->Chain B->Chain C->Chain D + // This should succeed in the first hop and second hop, then fail to make the third hop. + // Funds should be refunded to Chain B and then to Chain A via acknowledgements with errors. + transfer = ibc.WalletAmount{ + Address: userB.Bech32Address(chainB.Config().Bech32Prefix), + Denom: baIBCDenom, + Amount: transferAmount, + } + + secondHopMetadata := &PacketMetadata{ + Forward: &ForwardMetadata{ + Receiver: "xyz1t8eh66t2w5k67kwurmn5gqhtq6d2ja0vp7jmmq", // malformed receiver address on chain D + Channel: cdChan.ChannelID, + Port: cdChan.PortID, + }, + } + + nextBz, err := json.Marshal(secondHopMetadata) + require.NoError(t, err) + + next := string(nextBz) + + firstHopMetadata := &PacketMetadata{ + Forward: &ForwardMetadata{ + Receiver: userC.Bech32Address(chainC.Config().Bech32Prefix), + Channel: bcChan.ChannelID, + Port: bcChan.PortID, + Next: &next, + }, + } + + memo, err := json.Marshal(firstHopMetadata) + require.NoError(t, err) + + chainAHeight, err := chainA.Height(ctx) + require.NoError(t, err) + + transferTx, err = chainA.SendIBCTransfer(ctx, abChan.ChannelID, userA.KeyName, transfer, ibc.TransferOptions{Memo: string(memo)}) + require.NoError(t, err) + _, err = testutil.PollForAck(ctx, chainA, chainAHeight, chainAHeight+30, transferTx.Packet) + require.NoError(t, err) + err = testutil.WaitForBlocks(ctx, 1, chainA) + require.NoError(t, err) + + // assert balances for user controlled wallets + chainDBalance, err := chainD.GetBalance(ctx, userD.Bech32Address(chainD.Config().Bech32Prefix), cdIBCDenom) + require.NoError(t, err) + + chainCBalance, err := chainC.GetBalance(ctx, userC.Bech32Address(chainC.Config().Bech32Prefix), bcIBCDenom) + require.NoError(t, err) + + chainBBalance, err := chainB.GetBalance(ctx, userB.Bech32Address(chainB.Config().Bech32Prefix), chainB.Config().Denom) + require.NoError(t, err) + + chainABalance, err = chainA.GetBalance(ctx, userA.Bech32Address(chainA.Config().Bech32Prefix), baIBCDenom) + require.NoError(t, err) + + require.Equal(t, transferAmount, chainABalance) + require.Equal(t, userFunds-transferAmount, chainBBalance) + require.Equal(t, int64(0), chainCBalance) + require.Equal(t, int64(0), chainDBalance) + + // assert balances for IBC escrow accounts + cdEscrowBalance, err := chainC.GetBalance(ctx, transfertypes.GetEscrowAddress(cdChan.PortID, cdChan.ChannelID).String(), bcIBCDenom) + require.NoError(t, err) + + bcEscrowBalance, err := chainB.GetBalance(ctx, transfertypes.GetEscrowAddress(bcChan.PortID, bcChan.ChannelID).String(), chainB.Config().Denom) + require.NoError(t, err) + + baEscrowBalance, err = chainB.GetBalance(ctx, transfertypes.GetEscrowAddress(baChan.PortID, baChan.ChannelID).String(), chainB.Config().Denom) + require.NoError(t, err) + + require.Equal(t, transferAmount, baEscrowBalance) + require.Equal(t, int64(0), bcEscrowBalance) + require.Equal(t, int64(0), cdEscrowBalance) + }) } diff --git a/go.mod b/go.mod index a049ab164..186684da6 100644 --- a/go.mod +++ b/go.mod @@ -9,35 +9,36 @@ require ( github.com/atotto/clipboard v0.1.4 github.com/avast/retry-go/v4 v4.0.4 github.com/centrifuge/go-substrate-rpc-client/v4 v4.0.4 - github.com/cosmos/cosmos-sdk v0.46.1 - github.com/cosmos/ibc-go/v6 v6.0.0-alpha1 + github.com/cosmos/cosmos-sdk v0.46.2 + github.com/cosmos/ibc-go/v6 v6.0.0-20221104144119-b1f494c64328 github.com/davecgh/go-spew v1.1.1 github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 github.com/docker/docker v20.10.17+incompatible github.com/docker/go-connections v0.4.0 github.com/gdamore/tcell/v2 v2.4.1-0.20210905002822-f057f0a857a1 github.com/google/go-cmp v0.5.8 + github.com/hashicorp/go-version v1.6.0 github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 github.com/libp2p/go-libp2p-core v0.15.1 github.com/mr-tron/base58 v1.2.0 github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8 - github.com/stretchr/testify v1.8.0 + github.com/stretchr/testify v1.8.1 github.com/tendermint/tendermint v0.34.21 go.uber.org/multierr v1.8.0 go.uber.org/zap v1.21.0 golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 golang.org/x/tools v0.1.12 - google.golang.org/grpc v1.49.0 + google.golang.org/grpc v1.50.1 gopkg.in/yaml.v3 v3.0.1 modernc.org/sqlite v1.17.3 ) require ( - cloud.google.com/go v0.100.2 // indirect - cloud.google.com/go/compute v1.6.1 // indirect - cloud.google.com/go/iam v0.3.0 // indirect - cloud.google.com/go/storage v1.14.0 // indirect + cloud.google.com/go v0.102.1 // indirect + cloud.google.com/go/compute v1.7.0 // indirect + cloud.google.com/go/iam v0.4.0 // indirect + cloud.google.com/go/storage v1.22.1 // indirect cosmossdk.io/errors v1.0.0-beta.7 // indirect cosmossdk.io/math v1.0.0-beta.3 // indirect filippo.io/edwards25519 v1.0.0-rc.1 // indirect @@ -45,7 +46,7 @@ require ( github.com/99designs/keyring v1.2.1 // indirect github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect - github.com/armon/go-metrics v0.4.0 // indirect + github.com/armon/go-metrics v0.4.1 // indirect github.com/aws/aws-sdk-go v1.40.45 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -54,13 +55,14 @@ require ( github.com/btcsuite/btcd v0.22.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/confio/ics23/go v0.7.0 // indirect github.com/cosmos/btcutil v1.0.4 // indirect github.com/cosmos/cosmos-proto v1.0.0-alpha7 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gorocksdb v1.2.0 // indirect - github.com/cosmos/iavl v0.19.1 // indirect + github.com/cosmos/iavl v0.19.2-0.20220916140702-9b6be3095313 // indirect github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect github.com/cosmos/ledger-go v0.9.2 // indirect github.com/danieljoos/wincred v1.1.2 // indirect @@ -92,7 +94,9 @@ require ( github.com/google/btree v1.0.1 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect github.com/googleapis/gax-go/v2 v2.4.0 // indirect + github.com/googleapis/go-type-adapters v1.0.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -105,11 +109,10 @@ require ( github.com/hashicorp/go-getter v1.6.1 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/ipfs/go-cid v0.0.7 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect @@ -120,7 +123,8 @@ require ( github.com/libp2p/go-openssl v0.0.7 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/manifoldco/promptui v0.9.0 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect @@ -140,7 +144,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pierrec/xxHash v0.1.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -161,11 +165,11 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.5.0 // indirect + github.com/spf13/cobra v1.6.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.12.0 // indirect - github.com/subosito/gotenv v1.4.0 // indirect + github.com/spf13/viper v1.13.0 // indirect + github.com/subosito/gotenv v1.4.1 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect github.com/tendermint/btcd v0.1.1 // indirect github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect @@ -181,16 +185,16 @@ require ( golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/net v0.0.0-20220726230323-06994584191e // indirect - golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect - golang.org/x/sys v0.0.0-20220727055044-e65921a090b8 // indirect + golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 // indirect + golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect - google.golang.org/api v0.81.0 // indirect + golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect + google.golang.org/api v0.93.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b // indirect + google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959 // indirect google.golang.org/protobuf v1.28.1 // indirect - gopkg.in/ini.v1 v1.66.6 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gotest.tools/v3 v3.3.0 // indirect diff --git a/go.sum b/go.sum index 488e1712e..32d35ac89 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,10 @@ cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+Y cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1 h1:vpK6iQWv/2uUeFJth4/cBHsQAGjn1iIE6AAlxipRaA0= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -43,12 +45,14 @@ cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTB cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.4.0 h1:YBYU00SCDzZJdHqVc4I5d6lsklcYIjQZa1YmEz4jlSE= +cloud.google.com/go/iam v0.4.0/go.mod h1:cbaZxyScUhxl7ZAkNWiALgihfP75wS/fUsVNaa1r3vA= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -58,8 +62,9 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0 h1:6RRlFMv1omScs6iq2hfE3IvgE+l6RfJPampq8UZc5TU= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1 h1:F6IlQJZrZM++apn9V5/VfS3gbTUYg98PS3EMQAzqtfg= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= @@ -109,8 +114,8 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.4.0 h1:yCQqn7dwca4ITXb+CbubHmedzaQYHhNhrEXLYUeEe8Q= -github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/avast/retry-go/v4 v4.0.4 h1:38hLf0DsRXh+hOF6HbTni0+5QGTNdw9zbaMD7KAO830= @@ -170,8 +175,11 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= @@ -200,15 +208,17 @@ github.com/cosmos/btcutil v1.0.4 h1:n7C2ngKXo7UC9gNyMNLbzqz7Asuf+7Qv4gnX/rOdQ44= github.com/cosmos/btcutil v1.0.4/go.mod h1:Ffqc8Hn6TJUdDgHBwIZLtrLQC1KdJ9jGJl/TvgUaxbU= github.com/cosmos/cosmos-proto v1.0.0-alpha7 h1:yqYUOHF2jopwZh4dVQp3xgqwftE5/2hkrwIV6vkUbO0= github.com/cosmos/cosmos-proto v1.0.0-alpha7/go.mod h1:dosO4pSAbJF8zWCzCoTWP7nNsjcvSUBQmniFxDg5daw= -github.com/cosmos/cosmos-sdk v0.46.1 h1:7vUZXMyrmEb4xtBYpz1TobtrcnpgiZTi+tVjc0XWB4o= -github.com/cosmos/cosmos-sdk v0.46.1/go.mod h1:2+o8Qw8qnE02V+lQVZDJFQ8tri/hsiA5GmWaPERqVa0= +github.com/cosmos/cosmos-sdk v0.46.2 h1:3dUNqbLas94ud5aTcJKCwxVOmNXpuGBtVQTMrYczTwY= +github.com/cosmos/cosmos-sdk v0.46.2/go.mod h1:0aUPGPU6PWaDEaHNjtgrpNhgxo9bAUrQ7BO7XCvFOfs= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= -github.com/cosmos/iavl v0.19.1 h1:3gaq9b6SjiB0KBTygRnAvEGml2pQlu1TH8uma5g63Ys= -github.com/cosmos/iavl v0.19.1/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= +github.com/cosmos/iavl v0.19.2-0.20220916140702-9b6be3095313 h1:R7CnaI/0OLwOusy7n9750n8fqQ3yCQ8OJQI2L3ws9RA= +github.com/cosmos/iavl v0.19.2-0.20220916140702-9b6be3095313/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= +github.com/cosmos/ibc-go/v6 v6.0.0-20221104144119-b1f494c64328 h1:AOYqtFV6sls3gIbDL0SVAsDeMU7neFVwQNBg/Q5Dfkg= +github.com/cosmos/ibc-go/v6 v6.0.0-20221104144119-b1f494c64328/go.mod h1:z48BvFJ36CTRVWIK5Z7d49UhZkgLwzTivUrKke1cfkk= github.com/cosmos/ibc-go/v6 v6.0.0-alpha1 h1:FpmkSFqRGwFZPL4HNLJ0V2L4/ILyG+tcVy59+EBn7q4= github.com/cosmos/ibc-go/v6 v6.0.0-alpha1/go.mod h1:F2p2yeQlr4+L/YslhlY+Rk1uHXAJ2yKPPo6/uDUsYpc= github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4= @@ -440,6 +450,9 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0 h1:zO8WHNx/MYiAKJ3d5spxZXZE6KHmIQGQcAzwUzV7qQw= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -448,6 +461,8 @@ github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/Oth github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= @@ -505,8 +520,9 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 h1:H+uM0Bv88eur3ZSsd2NGKg3YIiuXxwxtlN7HjE66UTU= github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845/go.mod h1:c1tRKs5Tx7E2+uHGSyyncziFjvGpgv4H2HrqXeUQ/Uk= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= @@ -592,6 +608,8 @@ github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamh github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= +github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -602,8 +620,8 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -704,8 +722,8 @@ github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChl github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= -github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= +github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= +github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= @@ -810,8 +828,8 @@ github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -819,15 +837,16 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= -github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU= +github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/strangelove-ventures/go-subkey v1.0.7 h1:cOP/Lajg3uxV/tvspu0m6+0Cu+DJgygkEAbx/s+f35I= github.com/strangelove-ventures/go-subkey v1.0.7/go.mod h1:E34izOIEm+sZ1YmYawYRquqBQWeZBjVB4pF7bMuhc1c= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -837,10 +856,11 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= -github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= +github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= @@ -1026,8 +1046,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220726230323-06994584191e h1:wOQNKh1uuDGRnmgF0jDxh7ctgGy/3P4rYWQRVJD4/Yg= golang.org/x/net v0.0.0-20220726230323-06994584191e/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1048,8 +1068,10 @@ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 h1:+jnHzr9VPj32ykQVai5DNahi9+NSp7yYuCsl5eAQtL0= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1061,7 +1083,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1069,6 +1091,7 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1156,11 +1179,14 @@ golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220727055044-e65921a090b8 h1:dyU22nBWzrmTQxtNrr4dzVOvaw35nUYE279vF9UmsI8= -golang.org/x/sys v0.0.0-20220727055044-e65921a090b8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1252,8 +1278,9 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= @@ -1297,8 +1324,10 @@ google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.81.0 h1:o8WF5AvfidafWbFjsRyupxyEQJNUWxLZJCK5NXrxZZ8= -google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.93.0 h1:T2xt9gi0gHdxdnRkVQhT8mIvPaXKNsDNWz+L696M66M= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1353,6 +1382,7 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= @@ -1387,9 +1417,14 @@ google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b h1:SfSkJugek6xm7lWywqth4r2iTrYLpD8lOj1nMIIhMNM= -google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959 h1:hw4Y42zL1VyVKxPgRHHh191fpVBGV8sNVmcow5Z8VXY= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1421,8 +1456,9 @@ google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5 google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw= -google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1450,8 +1486,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= -gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= diff --git a/ibc/chain.go b/ibc/chain.go index 7a6cbe979..57bb8a015 100644 --- a/ibc/chain.go +++ b/ibc/chain.go @@ -57,7 +57,7 @@ type Chain interface { SendFunds(ctx context.Context, keyName string, amount WalletAmount) error // SendIBCTransfer sends an IBC transfer returning a transaction or an error if the transfer failed. - SendIBCTransfer(ctx context.Context, channelID, keyName string, amount WalletAmount, timeout *IBCTimeout) (Tx, error) + SendIBCTransfer(ctx context.Context, channelID, keyName string, amount WalletAmount, options TransferOptions) (Tx, error) // Height returns the current block height or an error if unable to get current height. Height(ctx context.Context) (uint64, error) @@ -74,3 +74,9 @@ type Chain interface { // Timeouts returns all timeouts in a block at height. Timeouts(ctx context.Context, height uint64) ([]PacketTimeout, error) } + +// TransferOptions defines the options for an IBC packet transfer. +type TransferOptions struct { + Timeout *IBCTimeout + Memo string +} diff --git a/ibc/relayer.go b/ibc/relayer.go index c2ad78e2d..372820bd8 100644 --- a/ibc/relayer.go +++ b/ibc/relayer.go @@ -53,6 +53,9 @@ type Relayer interface { // GetConnections returns a slice of IBC connection details composed of the details for each connection on a specified chain. GetConnections(ctx context.Context, rep RelayerExecReporter, chainID string) (ConnectionOutputs, error) + // GetClients returns a slice of IBC client details composed of the details for each client on a specified chain. + GetClients(ctx context.Context, rep RelayerExecReporter, chainID string) (ClientOutputs, error) + // After configuration is initialized, begin relaying. // This method is intended to create a background worker that runs the relayer. // You must call StopRelayer to cleanly stop the relaying. @@ -95,6 +98,82 @@ type Relayer interface { Exec(ctx context.Context, rep RelayerExecReporter, cmd []string, env []string) RelayerExecResult } +// GetTransferChannel will return the transfer channel assuming only one client, +// one connection, and one channel with "transfer" port exists between two chains. +func GetTransferChannel(ctx context.Context, r Relayer, rep RelayerExecReporter, srcChainID, dstChainID string) (*ChannelOutput, error) { + srcClients, err := r.GetClients(ctx, rep, srcChainID) + if err != nil { + return nil, fmt.Errorf("failed to get clients on source chain: %w", err) + } + + if len(srcClients) == 0 { + return nil, fmt.Errorf("no clients exist on source chain: %w", err) + } + + var srcClientID string + for _, client := range srcClients { + // TODO continue for expired clients + if client.ClientState.ChainID == dstChainID { + if srcClientID != "" { + return nil, fmt.Errorf("found multiple clients on %s tracking %s", srcChainID, dstChainID) + } + srcClientID = client.ClientID + } + } + + if srcClientID == "" { + return nil, fmt.Errorf("unable to find client on %s tracking %s", srcChainID, dstChainID) + } + + srcConnections, err := r.GetConnections(ctx, rep, srcChainID) + if err != nil { + return nil, fmt.Errorf("failed to get connections on source chain: %w", err) + } + + if len(srcConnections) == 0 { + return nil, fmt.Errorf("no connections exist on source chain: %w", err) + } + + var srcConnectionID string + for _, connection := range srcConnections { + if connection.ClientID == srcClientID { + if srcConnectionID != "" { + return nil, fmt.Errorf("found multiple connections on %s for client %s", srcChainID, srcClientID) + } + srcConnectionID = connection.ID + } + } + + if srcConnectionID == "" { + return nil, fmt.Errorf("unable to find connection on %s for client %s", srcChainID, srcClientID) + } + + srcChannels, err := r.GetChannels(ctx, rep, srcChainID) + if err != nil { + return nil, fmt.Errorf("failed to get channels on source chain: %w", err) + } + + if len(srcChannels) == 0 { + return nil, fmt.Errorf("no channels exist on source chain: %w", err) + } + + var srcChan *ChannelOutput + for _, channel := range srcChannels { + if len(channel.ConnectionHops) == 1 && channel.ConnectionHops[0] == srcConnectionID && channel.PortID == "transfer" { + if srcChan != nil { + return nil, fmt.Errorf("found multiple transfer channels on %s for connection %s", srcChainID, srcConnectionID) + } + srcChan = &channel + } + } + + if srcChan == nil { + return nil, fmt.Errorf("no transfer channel found between chains: %s - %s", srcChainID, dstChainID) + } + + return srcChan, nil +} + // RelyaerExecResult holds the details of a call to Relayer.Exec. type RelayerExecResult struct { // This type is a redeclaration of dockerutil.ContainerExecResult. diff --git a/ibc/types.go b/ibc/types.go index 692a4ce56..18e3344c5 100644 --- a/ibc/types.go +++ b/ibc/types.go @@ -204,6 +204,17 @@ type ConnectionOutput struct { type ConnectionOutputs []*ConnectionOutput +type ClientOutput struct { + ClientID string `json:"client_id"` + ClientState ClientState `json:"client_state"` +} + +type ClientState struct { + ChainID string `json:"chain_id"` +} + +type ClientOutputs []*ClientOutput + type Wallet struct { Mnemonic string `json:"mnemonic"` Address string `json:"address"` diff --git a/interchain_test.go b/interchain_test.go index 8bf64db19..0585c254f 100644 --- a/interchain_test.go +++ b/interchain_test.go @@ -288,7 +288,16 @@ func TestCosmosChain_BroadcastTx(t *testing.T) { b := cosmos.NewBroadcaster(t, gaia0.(*cosmos.CosmosChain)) transferAmount := types.Coin{Denom: gaia0.Config().Denom, Amount: types.NewInt(sendAmount)} - msg := transfertypes.NewMsgTransfer("transfer", "channel-0", transferAmount, testUser.Bech32Address(gaia0.Config().Bech32Prefix), testUser.Bech32Address(gaia1.Config().Bech32Prefix), clienttypes.NewHeight(1, 1000), 0) + msg := transfertypes.NewMsgTransfer( + "transfer", + "channel-0", + transferAmount, + testUser.Bech32Address(gaia0.Config().Bech32Prefix), + testUser.Bech32Address(gaia1.Config().Bech32Prefix), + clienttypes.NewHeight(1, 1000), + 0, + "", + ) resp, err := cosmos.BroadcastTx(ctx, b, testUser, msg) require.NoError(t, err) assertTransactionIsValid(t, resp) diff --git a/internal/blockdb/messages_view_test.go b/internal/blockdb/messages_view_test.go index 56792ca85..0878a03c1 100644 --- a/internal/blockdb/messages_view_test.go +++ b/internal/blockdb/messages_view_test.go @@ -255,11 +255,12 @@ WHERE type = "/ibc.core.channel.v1.MsgChannelOpenConfirm" AND chain_id = ? // Send the IBC transfer. Relayer isn't running, so this will just create a MsgTransfer. const txAmount = 13579 // Arbitrary amount that is easy to find in logs. - tx, err := gaia0.SendIBCTransfer(ctx, gaia0ChannelID, ibctest.FaucetAccountKeyName, ibc.WalletAmount{ + transfer := ibc.WalletAmount{ Address: gaia1FaucetAddr, Denom: gaia0.Config().Denom, Amount: txAmount, - }, nil) + } + tx, err := gaia0.SendIBCTransfer(ctx, gaia0ChannelID, ibctest.FaucetAccountKeyName, transfer, ibc.TransferOptions{}) require.NoError(t, err) require.NoError(t, tx.Validate()) diff --git a/relayer/docker.go b/relayer/docker.go index e9882ffc4..551fbbbf0 100644 --- a/relayer/docker.go +++ b/relayer/docker.go @@ -282,6 +282,16 @@ func (r *DockerRelayer) GetConnections(ctx context.Context, rep ibc.RelayerExecR return r.c.ParseGetConnectionsOutput(string(res.Stdout), string(res.Stderr)) } +func (r *DockerRelayer) GetClients(ctx context.Context, rep ibc.RelayerExecReporter, chainID string) (ibc.ClientOutputs, error) { + cmd := r.c.GetClients(chainID, r.HomeDir()) + res := r.Exec(ctx, rep, cmd, nil) + if res.Err != nil { + return nil, res.Err + } + + return r.c.ParseGetClientsOutput(string(res.Stdout), string(res.Stderr)) +} + func (r *DockerRelayer) LinkPath(ctx context.Context, rep ibc.RelayerExecReporter, pathName string, channelOpts ibc.CreateChannelOptions, clientOpts ibc.CreateClientOptions) error { cmd := r.c.LinkPath(pathName, r.HomeDir(), channelOpts, clientOpts) res := r.Exec(ctx, rep, cmd, nil) @@ -637,6 +647,10 @@ type RelayerCommander interface { // to produce the connection output values. ParseGetConnectionsOutput(stdout, stderr string) (ibc.ConnectionOutputs, error) + // ParseGetClientsOutput processes the output of GetClients + // to produce the client output values. + ParseGetClientsOutput(stdout, stderr string) (ibc.ClientOutputs, error) + // Init is the command to run on the first call to AddChainConfiguration. // If the returned command is nil or empty, nothing will be executed. Init(homeDir string) []string @@ -654,6 +668,7 @@ type RelayerCommander interface { UpdatePath(pathName, homeDir string, filter ibc.ChannelFilter) []string GetChannels(chainID, homeDir string) []string GetConnections(chainID, homeDir string) []string + GetClients(chainID, homeDir string) []string LinkPath(pathName, homeDir string, channelOpts ibc.CreateChannelOptions, clientOpts ibc.CreateClientOptions) []string RestoreKey(chainID, keyName, coinType, mnemonic, homeDir string) []string StartRelayer(homeDir string, pathNames ...string) []string diff --git a/relayer/rly/cosmos_relayer.go b/relayer/rly/cosmos_relayer.go index e2bbb80f4..a98ae6c22 100644 --- a/relayer/rly/cosmos_relayer.go +++ b/relayer/rly/cosmos_relayer.go @@ -202,6 +202,13 @@ func (commander) GetConnections(chainID, homeDir string) []string { } } +func (commander) GetClients(chainID, homeDir string) []string { + return []string{ + "rly", "q", "clients", chainID, + "--home", homeDir, + } +} + func (commander) LinkPath(pathName, homeDir string, channelOpts ibc.CreateChannelOptions, clientOpt ibc.CreateClientOptions) []string { return []string{ "rly", "tx", "link", pathName, @@ -307,6 +314,28 @@ func (c commander) ParseGetConnectionsOutput(stdout, stderr string) (ibc.Connect return connections, nil } +func (c commander) ParseGetClientsOutput(stdout, stderr string) (ibc.ClientOutputs, error) { + var clients ibc.ClientOutputs + for _, client := range strings.Split(stdout, "\n") { + if strings.TrimSpace(client) == "" { + continue + } + + var clientOutput ibc.ClientOutput + if err := json.Unmarshal([]byte(client), &clientOutput); err != nil { + c.log.Error( + "Error parsing client json", + zap.Error(err), + ) + + continue + } + clients = append(clients, &clientOutput) + } + + return clients, nil +} + func (commander) Init(homeDir string) []string { return []string{ "rly", "config", "init",