diff --git a/go.work.sum b/go.work.sum index a4accb27..5713d0c8 100644 --- a/go.work.sum +++ b/go.work.sum @@ -311,6 +311,8 @@ github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKz github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk= github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= +github.com/KYVENetwork/interchaintest/v8 v8.0.0-20240520124515-fd4cc797e6fd h1:lKJ7X9Q+KbQviDxpY4OaalC8/oZ64rXfTNTny4jfuE0= +github.com/KYVENetwork/interchaintest/v8 v8.0.0-20240520124515-fd4cc797e6fd/go.mod h1:pupV0YN3A56/u9kHj9U1F8MdDUEolBIn05F0W1q/0oI= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= diff --git a/interchaintest/go.mod b/interchaintest/go.mod index d87f4b57..a3219b3c 100644 --- a/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -8,6 +8,7 @@ require ( cosmossdk.io/math v1.3.0 github.com/KYVENetwork/chain v0.0.0-00010101000000-000000000000 github.com/cosmos/cosmos-sdk v0.50.5 + github.com/cosmos/ibc-go/v8 v8.2.0 github.com/docker/docker v24.0.7+incompatible github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 github.com/onsi/ginkgo/v2 v2.17.1 @@ -29,6 +30,7 @@ require ( cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.3.1 // indirect cosmossdk.io/store v1.1.0 // indirect + cosmossdk.io/x/evidence v0.1.0 // indirect cosmossdk.io/x/feegrant v0.1.0 // indirect cosmossdk.io/x/tx v0.13.1 // indirect cosmossdk.io/x/upgrade v0.1.1 // indirect @@ -56,6 +58,7 @@ 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/apd/v2 v2.0.2 // 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 @@ -71,7 +74,6 @@ require ( github.com/cosmos/gogoproto v1.4.12 // indirect github.com/cosmos/iavl v1.1.1 // indirect github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect - github.com/cosmos/ibc-go/v8 v8.1.1 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/danieljoos/wincred v1.1.2 // indirect @@ -242,6 +244,7 @@ require ( google.golang.org/protobuf v1.33.0 // 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 gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect @@ -275,7 +278,7 @@ replace ( // needed for strangelove's interchaintest github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 // use kyve flavored strangelove-ventures/interchaintest - github.com/strangelove-ventures/interchaintest/v8 => github.com/KYVENetwork/interchaintest/v8 v8.0.0-20240422073541-22e23c056376 + github.com/strangelove-ventures/interchaintest/v8 => github.com/KYVENetwork/interchaintest/v8 v8.0.0-20240520124515-fd4cc797e6fd // replace broken goleveldb github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) diff --git a/interchaintest/go.sum b/interchaintest/go.sum index 514042f7..e19ff6db 100644 --- a/interchaintest/go.sum +++ b/interchaintest/go.sum @@ -239,8 +239,8 @@ github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69m github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= github.com/KYVENetwork/cosmos-sdk v0.50.5-kyve-rc2 h1:SUX6bCgG72BuWAkr7vE2VKFGU4SqBaE0uKUd3qeIk2o= github.com/KYVENetwork/cosmos-sdk v0.50.5-kyve-rc2/go.mod h1:sM3HLOjUE6rwAiuwEOEtPd2DUcXG+uCktW+CdID+ZMM= -github.com/KYVENetwork/interchaintest/v8 v8.0.0-20240422073541-22e23c056376 h1:I/yGiXZzQwWfVUdT9+jvGHiRkWAft3U3s1eOFQfel8I= -github.com/KYVENetwork/interchaintest/v8 v8.0.0-20240422073541-22e23c056376/go.mod h1:pupV0YN3A56/u9kHj9U1F8MdDUEolBIn05F0W1q/0oI= +github.com/KYVENetwork/interchaintest/v8 v8.0.0-20240520124515-fd4cc797e6fd h1:lKJ7X9Q+KbQviDxpY4OaalC8/oZ64rXfTNTny4jfuE0= +github.com/KYVENetwork/interchaintest/v8 v8.0.0-20240520124515-fd4cc797e6fd/go.mod h1:pupV0YN3A56/u9kHj9U1F8MdDUEolBIn05F0W1q/0oI= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= @@ -393,8 +393,8 @@ github.com/cosmos/iavl v1.1.1 h1:64nTi8s3gEoGqhA8TyAWFWfz7/pg0anKzHNSc1ETc7Q= github.com/cosmos/iavl v1.1.1/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= -github.com/cosmos/ibc-go/v8 v8.1.1 h1:N2+GA86yACcXnKWCKtqdbCwP0/Eo8pH79+6e7TicULU= -github.com/cosmos/ibc-go/v8 v8.1.1/go.mod h1:o1ipS95xpdjqNcB8Drq0eI3Sn4FRLigjll42ec1ECuU= +github.com/cosmos/ibc-go/v8 v8.2.0 h1:7oCzyy1sZCcgpeQLnHxC56brsSz3KWwQGKXalXwXFzE= +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/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= diff --git a/interchaintest/ibc/ibc_test.go b/interchaintest/ibc/ibc_test.go new file mode 100644 index 00000000..ef5a7ca8 --- /dev/null +++ b/interchaintest/ibc/ibc_test.go @@ -0,0 +1,155 @@ +package relayer_test + +import ( + "context" + "cosmossdk.io/math" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + "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" + "testing" + + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" + "go.uber.org/zap/zaptest" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +/* + +TEST CASES - IBC + +* Transfer Kyve tokens to Osmosis + +*/ + +func TestProposalHandler(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "interchaintest/IBC Test Suite") +} + +var _ = Describe("ibc", Ordered, func() { + var kyve *cosmos.CosmosChain + var osmosis *cosmos.CosmosChain + + var ctx context.Context + var interchain *interchaintest.Interchain + + var ibcPath string + var eRep *testreporter.RelayerExecReporter + var rel ibc.Relayer + + BeforeAll(func() { + ctx = context.Background() + ibcPath = "kyve-osmosis" + + fw, err := interchaintest.CreateLogFile(GinkgoT().Name() + ".log") + Expect(err).To(BeNil()) + + rep := testreporter.NewReporter(fw) + eRep = rep.RelayerExecReporter(GinkgoT()) + + numFullNodes := 1 + numValidators := 2 + logger := zaptest.NewLogger(GinkgoT()) + factory := interchaintest.NewBuiltinChainFactory( + logger, + []*interchaintest.ChainSpec{ + mainnetChainSpec(numValidators, numFullNodes), + {Name: "osmosis", Version: "v25.0.0", NumValidators: &numValidators, NumFullNodes: &numFullNodes}, + }, + ) + + chains, err := factory.Chains(GinkgoT().Name()) + Expect(err).To(BeNil()) + kyve, osmosis = chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain) + + client, network := interchaintest.DockerSetup(GinkgoT()) + + rel = interchaintest.NewBuiltinRelayerFactory( + // TODO: make the relayer work + ibc.Hermes, + logger, + //relayer.CustomDockerImage("ghcr.io/informalsystems/hermes", "v1.8.0", rly.RlyDefaultUidGid), + //relayer.CustomDockerImage("ghcr.io/cosmos/relayer", "v2.4.2", rly.RlyDefaultUidGid), + ).Build(GinkgoT(), client, network) + + interchain = interchaintest.NewInterchain(). + AddChain(kyve). + AddChain(osmosis). + AddRelayer(rel, "relayer"). + AddLink(interchaintest.InterchainLink{ + Chain1: kyve, + Chain2: osmosis, + Path: ibcPath, + Relayer: rel, + }) + + err = interchain.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ + TestName: GinkgoT().Name(), + Client: client, + NetworkID: network, + SkipPathCreation: true, + BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), + }) + Expect(err).To(BeNil()) + }) + + AfterAll(func() { + _ = rel.StopRelayer(ctx, eRep) + _ = kyve.StopAllNodes(ctx) + _ = osmosis.StopAllNodes(ctx) + _ = interchain.Close() + }) + + It("Transfer Kyve tokens to Osmosis", func() { + // ARRANGE + var wallet = interchaintest.GetAndFundTestUsers( + GinkgoT(), ctx, GinkgoT().Name(), math.NewInt(10_000_000_000), kyve, + )[0].(*cosmos.CosmosWallet) + + osmosisReceiver := wallet.FormattedAddressWithPrefix(osmosis.Config().Bech32Prefix) + + // Wait a few blocks + err := testutil.WaitForBlocks(ctx, 3, kyve, osmosis) + Expect(err).To(BeNil()) + + err = rel.StartRelayer(ctx, eRep) + Expect(err).To(BeNil()) + + kyveChans, err := rel.GetChannels(ctx, eRep, kyve.Config().ChainID) + Expect(err).To(BeNil()) + Expect(kyveChans).To(HaveLen(1)) + kyveChan := kyveChans[0] + + // ACT + transfer := ibc.WalletAmount{ + Address: osmosisReceiver, + Denom: kyve.Config().Denom, + Amount: math.NewInt(1_000_000_000), + } + tx, err := kyve.SendIBCTransfer(ctx, ibcPath, wallet.KeyName(), transfer, ibc.TransferOptions{}) + Expect(err).To(BeNil()) + + height, err := kyve.Height(ctx) + Expect(err).To(BeNil()) + + _, err = testutil.PollForAck(ctx, kyve, height, height+10, tx.Packet) + Expect(err).To(BeNil()) + + // ASSERT + userBalance, err := kyve.GetBalance(ctx, wallet.FormattedAddress(), kyve.Config().Denom) + Expect(err).To(BeNil()) + Expect(userBalance).To(Equal(math.NewInt(9_000_000_000))) + + prefixedDenom := transfertypes.GetPrefixedDenom(kyveChan.Counterparty.PortID, kyveChan.Counterparty.ChannelID, kyve.Config().Denom) + denomTrace := transfertypes.ParseDenomTrace(prefixedDenom) + ibcDenom := denomTrace.IBCDenom() + + receiverBalance, err := osmosis.GetBalance(ctx, osmosisReceiver, ibcDenom) + Expect(err).To(BeNil()) + Expect(receiverBalance).To(Equal(math.NewInt(1_000_000_000))) + }) +}) diff --git a/interchaintest/ibc/ibc_utils_test.go b/interchaintest/ibc/ibc_utils_test.go new file mode 100644 index 00000000..fc6cafba --- /dev/null +++ b/interchaintest/ibc/ibc_utils_test.go @@ -0,0 +1,81 @@ +package relayer_test + +import ( + "cosmossdk.io/math" + "encoding/json" + "github.com/KYVENetwork/chain/app" + sdk "github.com/cosmos/cosmos-sdk/types" + sdktestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" + bankTypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/icza/dyno" + "github.com/strangelove-ventures/interchaintest/v8" + "github.com/strangelove-ventures/interchaintest/v8/ibc" + "strconv" +) + +const ( + uidGid = "1025:1025" +) + +func encodingConfig() *sdktestutil.TestEncodingConfig { + cfg := sdktestutil.TestEncodingConfig{} + a := app.Setup() + + cfg.Codec = a.AppCodec() + cfg.TxConfig = authtx.NewTxConfig(a.AppCodec(), authtx.DefaultSignModes) + cfg.InterfaceRegistry = a.InterfaceRegistry() + cfg.Amino = a.LegacyAmino() + + return &cfg +} + +func mainnetChainSpec(numValidators int, numFullNodes int) *interchaintest.ChainSpec { + return &interchaintest.ChainSpec{ + NumValidators: &numValidators, + NumFullNodes: &numFullNodes, + ChainConfig: ibc.ChainConfig{ + Type: "cosmos", + Name: "kyve", + ChainID: "kyve-1", + Bin: "kyved", + Bech32Prefix: "kyve", + Denom: "ukyve", + GasPrices: "0.02ukyve", + GasAdjustment: 5, + TrustingPeriod: "112h", + NoHostMount: false, + EncodingConfig: encodingConfig(), + ModifyGenesis: ModifyGenesis, + Images: []ibc.DockerImage{{ + Repository: "kyve", + Version: "local", + UidGid: uidGid, + }}, + }, + } +} + +func ModifyGenesis(config ibc.ChainConfig, genbz []byte) ([]byte, error) { + genesis := make(map[string]interface{}) + _ = json.Unmarshal(genbz, &genesis) + + teamSupply := math.NewInt(165_000_000_000_000) + balances, _ := dyno.GetSlice(genesis, "app_state", "bank", "balances") + balances = append(balances, bankTypes.Balance{ + Address: "kyve1e29j95xmsw3zmvtrk4st8e89z5n72v7nf70ma4", + Coins: sdk.NewCoins(sdk.NewCoin(config.Denom, teamSupply)), + }) + _ = dyno.Set(genesis, balances, "app_state", "bank", "balances") + totalSupply, _ := dyno.GetSlice(genesis, "app_state", "bank", "supply") + + // update total supply + coin := totalSupply[0].(map[string]interface{}) + amountStr := coin["amount"].(string) + amount, _ := strconv.Atoi(amountStr) + totalSupply[0] = sdk.NewCoin(config.Denom, math.NewInt(int64(amount)+teamSupply.Int64())) + _ = dyno.Set(genesis, totalSupply, "app_state", "bank", "supply") + + newGenesis, _ := json.Marshal(genesis) + return newGenesis, nil +}