From 96e69049519c0080d3773e6d818b6ff2652b208f Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Tue, 24 Jun 2025 03:29:34 +0300 Subject: [PATCH 1/5] test: add ibc v2 relaying --- e2e/go.mod | 20 +- e2e/go.sum | 48 ++-- e2e/tests/transfer/v2/transfer_ibc_v2_test.go | 248 ++++++++++++++++++ e2e/testsuite/codec.go | 26 +- e2e/testsuite/testsuite.go | 8 +- e2e/testsuite/tx.go | 2 +- simapp/app.go | 7 + simapp/go.mod | 2 +- 8 files changed, 315 insertions(+), 46 deletions(-) create mode 100644 e2e/tests/transfer/v2/transfer_ibc_v2_test.go diff --git a/e2e/go.mod b/e2e/go.mod index d8413822910..da2c80e607c 100644 --- a/e2e/go.mod +++ b/e2e/go.mod @@ -21,6 +21,7 @@ require ( github.com/cosmos/ibc-go/modules/light-clients/08-wasm/v10 v10.3.0 github.com/cosmos/ibc-go/v10 v10.3.0 github.com/cosmos/interchaintest/v10 v10.0.0 + github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api v0.0.0-20250623235625-56ef46c6fd40 github.com/docker/docker v28.0.0+incompatible github.com/iancoleman/orderedmap v0.3.0 github.com/moby/moby v27.5.1+incompatible @@ -63,7 +64,7 @@ require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/StackExchange/wmi v1.2.1 // indirect - github.com/avast/retry-go/v4 v4.5.1 // indirect + github.com/avast/retry-go/v4 v4.6.1 // indirect github.com/aws/aws-sdk-go v1.49.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect @@ -73,6 +74,7 @@ require ( github.com/bytedance/sonic v1.13.2 // indirect github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cenkalti/backoff/v5 v5.0.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cloudwego/base64x v0.1.5 // indirect @@ -193,7 +195,7 @@ require ( github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect github.com/oklog/run v1.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc5 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -240,13 +242,13 @@ require ( go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect - go.opentelemetry.io/otel v1.35.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel v1.36.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect - go.opentelemetry.io/otel/metric v1.35.0 // indirect - go.opentelemetry.io/otel/sdk v1.35.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect - go.opentelemetry.io/otel/trace v1.35.0 // indirect + go.opentelemetry.io/otel/metric v1.36.0 // indirect + go.opentelemetry.io/otel/sdk v1.36.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect + go.opentelemetry.io/otel/trace v1.36.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.uber.org/mock v0.5.2 // indirect go.uber.org/multierr v1.11.0 // indirect @@ -259,7 +261,7 @@ require ( golang.org/x/sys v0.33.0 // indirect golang.org/x/term v0.32.0 // indirect golang.org/x/text v0.25.0 // indirect - golang.org/x/time v0.10.0 // indirect + golang.org/x/time v0.12.0 // indirect golang.org/x/tools v0.31.0 // indirect google.golang.org/api v0.222.0 // indirect google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect diff --git a/e2e/go.sum b/e2e/go.sum index 54aad3b8c54..4d9de530fe6 100644 --- a/e2e/go.sum +++ b/e2e/go.sum @@ -717,8 +717,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o= -github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc= +github.com/avast/retry-go/v4 v4.6.1 h1:VkOLRubHdisGrHnTu89g08aQEWEgRU7LVEop3GbIcMk= +github.com/avast/retry-go/v4 v4.6.1/go.mod h1:V6oF8njAwxJ5gRo1Q7Cxab24xs5NCWZBeaHHBklR8mA= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= @@ -762,6 +762,8 @@ github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= +github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= @@ -862,6 +864,8 @@ github.com/cosmos/interchaintest/v10 v10.0.0 h1:DEsXOS10x191Q3EU4RkOnyqahGCTnLaB github.com/cosmos/interchaintest/v10 v10.0.0/go.mod h1:caS4BRkAg8NkiZ8BsHEzjNBibt2OVdTctW5Ezz+Jqxs= github.com/cosmos/ledger-cosmos-go v0.14.0 h1:WfCHricT3rPbkPSVKRH+L4fQGKYHuGOK9Edpel8TYpE= github.com/cosmos/ledger-cosmos-go v0.14.0/go.mod h1:E07xCWSBl3mTGofZ2QnL4cIUzMbbGVyik84QYKbX3RA= +github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api v0.0.0-20250623235625-56ef46c6fd40 h1:hKStdUlDVvXK/YBQFcrxdvPzt25ZGO645/aYKz7lDEg= +github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api v0.0.0-20250623235625-56ef46c6fd40/go.mod h1:BBkJG45CKaxbJ+JFN1uQGD3N66nw2iynCeGUOzoeJY8= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= @@ -1407,8 +1411,8 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/moby v27.5.1+incompatible h1:/pN59F/t3U7Q4FPzV88nzqf7Fp0qqCSL2KzhZaiKcKw= github.com/moby/moby v27.5.1+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= -github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= -github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= +github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -1461,8 +1465,8 @@ github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeD github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= -github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= @@ -1736,24 +1740,24 @@ go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= -go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= -go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= +go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 h1:nRVXXvf78e00EwY6Wp0YII8ww2JVWshZ20HfTlE11AM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= -go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= -go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= -go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= -go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= -go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= -go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= -go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= -go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= +go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= +go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= +go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= +go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= +go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= +go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -2155,8 +2159,8 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= -golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/e2e/tests/transfer/v2/transfer_ibc_v2_test.go b/e2e/tests/transfer/v2/transfer_ibc_v2_test.go new file mode 100644 index 00000000000..1e378609d3c --- /dev/null +++ b/e2e/tests/transfer/v2/transfer_ibc_v2_test.go @@ -0,0 +1,248 @@ +//go:build !test_e2e + +package v2 + +import ( + "context" + "encoding/hex" + "errors" + "fmt" + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/gogoproto/proto" + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testsuite/query" + "github.com/cosmos/ibc-go/e2e/testvalues" + transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + clienttypesv2 "github.com/cosmos/ibc-go/v10/modules/core/02-client/v2/types" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" + ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" + "github.com/cosmos/interchaintest/v10/chain/cosmos" + "github.com/cosmos/interchaintest/v10/ibc" + "github.com/cosmos/interchaintest/v10/testutil" + "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/config" + "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/container" + "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/dockerutil" + "github.com/stretchr/testify/suite" + "go.uber.org/zap" +) + +type IBCV2TransferTestSuite struct { + testsuite.E2ETestSuite +} + +func TestIBCV2TransferTestSuite(t *testing.T) { + suite.Run(t, new(IBCV2TransferTestSuite)) +} + +func (s *IBCV2TransferTestSuite) SetupSuite() { + s.SetupChains(context.TODO(), 2, nil) +} + +func (s *IBCV2TransferTestSuite) TestIBCV2Transfer() { + t := s.T() + ctx := context.TODO() + logger := zap.NewExample() + + chainA, chainB := s.GetChains() + userA := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + userB := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + relayerUserA := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + relayerUserB := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + firstClientID := "07-tendermint-0" + + // Set up docker util + docker, err := dockerutil.DockerWithExistingSetup(ctx, logger, t.Name(), s.DockerClient, s.Network) + s.Require().NoError(err) + + // Spin up relayer API + relayerConfig := config.NewConfig(config.CreateCosmosCosmosModules(config.CosmosToCosmosConfigInfo{ + ChainAID: chainA.Config().ChainID, + ChainBID: chainB.Config().ChainID, + ChainATmRPC: chainA.GetRPCAddress(), + ChainBTmRPC: chainB.GetRPCAddress(), + ChainAUser: relayerUserA.FormattedAddress(), + ChainBUser: relayerUserB.FormattedAddress(), + })) + relayerConfig.Address = "0.0.0.0" + relayerAPIContainer, err := container.SpinUpRelayerApiContainer(ctx, logger, docker, "ibc-go-relayer", relayerConfig, []string{"v1.2.0"}) + s.Require().NoError(err) + t.Cleanup(func() { + ctx := context.TODO() + if err := docker.Cleanup(ctx, true); err != nil { + t.Logf("error cleaning up docker: %s", err) + } + }) + + // Create light clients on chainA and chainB + createClientTxOnA, err := relayerAPIContainer.GetCreateClientTx(ctx, chainB.Config().ChainID, chainA.Config().ChainID) + s.Require().NoError(err) + createClientOnAResp, err := s.BroadcastSdkTxBody(ctx, chainA, relayerUserA, createClientTxOnA, 5) + s.Require().NoError(err) + s.AssertTxSuccess(createClientOnAResp) + createClientTxOnB, err := relayerAPIContainer.GetCreateClientTx(ctx, chainA.Config().ChainID, chainB.Config().ChainID) + s.Require().NoError(err) + createClientOnBResp, err := s.BroadcastSdkTxBody(ctx, chainB, relayerUserB, createClientTxOnB, 5) + s.Require().NoError(err) + s.AssertTxSuccess(createClientOnBResp) + + // Register counterparty client on chainA and chainB + merklePathPrefix := [][]byte{[]byte(ibcexported.StoreKey), []byte("")} + registerCounterpartyOnAResp := s.BroadcastMessages(ctx, chainA, relayerUserA, &clienttypesv2.MsgRegisterCounterparty{ + ClientId: firstClientID, + CounterpartyClientId: firstClientID, + CounterpartyMerklePrefix: merklePathPrefix, + Signer: relayerUserA.FormattedAddress(), + }) + s.AssertTxSuccess(registerCounterpartyOnAResp) + registerCounterpartyOnBResp := s.BroadcastMessages(ctx, chainB, relayerUserB, &clienttypesv2.MsgRegisterCounterparty{ + ClientId: firstClientID, + CounterpartyClientId: firstClientID, + CounterpartyMerklePrefix: merklePathPrefix, + Signer: relayerUserB.FormattedAddress(), + }) + s.AssertTxSuccess(registerCounterpartyOnBResp) + + // Initiate transfer from chainA to chainB + timeoutTimestamp := uint64(time.Now().Add(5 * time.Minute).Unix()) + msg := &transfertypes.MsgTransfer{ + SourcePort: transfertypes.PortID, + SourceChannel: firstClientID, + Token: testvalues.DefaultTransferAmount(chainA.Config().Denom), + Sender: userA.FormattedAddress(), + Receiver: userB.FormattedAddress(), + TimeoutTimestamp: timeoutTimestamp, + Memo: "", + } + transferOnAResp := s.BroadcastMessages(ctx, chainA, userA, msg) + s.AssertTxSuccess(transferOnAResp) + err = testutil.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) + + // Verify tokens are escrowed on chainA + chainABalance, err := s.GetChainANativeBalance(ctx, userA) + s.Require().NoError(err) + expectedChainABalance := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expectedChainABalance, chainABalance) + + // Relay the packet from chainA to chainB + transferOnARespTxHash, err := hex.DecodeString(transferOnAResp.TxHash) + s.Require().NoError(err) + receiveTx, err := relayerAPIContainer.GetRelayTx(ctx, chainA.Config().ChainID, chainB.Config().ChainID, firstClientID, firstClientID, transferOnARespTxHash) + s.Require().NoError(err) + err = testutil.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) + receiveOnBResp, err := s.BroadcastSdkTxBody(ctx, chainB, relayerUserB, receiveTx, 5) + s.Require().NoError(err) + s.AssertTxSuccess(receiveOnBResp) + + // Verify tokens are transferred to chainB + ibcDenom := transfertypes.NewDenom(chainA.Config().Denom, transfertypes.NewHop(transfertypes.PortID, firstClientID)).IBCDenom() + chainBBalanceResp, err := query.GRPCQuery[banktypes.QueryBalanceResponse](ctx, chainB, &banktypes.QueryBalanceRequest{ + Address: userB.FormattedAddress(), + Denom: ibcDenom, + }) + s.Require().NoError(err) + s.Require().NotNil(chainBBalanceResp.Balance) + s.Require().Equal(testvalues.IBCTransferAmount, chainBBalanceResp.Balance.Amount.Int64()) + + // Relay ack back from chainB to chainA + err = testutil.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) + relayOnBRespTxHash, err := hex.DecodeString(receiveOnBResp.TxHash) + s.Require().NoError(err) + relayAckTx, err := relayerAPIContainer.GetRelayTx(ctx, chainB.Config().ChainID, chainA.Config().ChainID, firstClientID, firstClientID, relayOnBRespTxHash) + s.Require().NoError(err) + err = testutil.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) + relayAckOnAResp, err := s.BroadcastSdkTxBody(ctx, chainA, relayerUserA, relayAckTx, 5) + s.Require().NoError(err) + s.AssertTxSuccess(relayAckOnAResp) + err = testutil.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) + + // Verify packet commitment is deleted (i.e. packet is acknowledged) on chainA + _, err = query.GRPCQuery[channeltypesv2.QueryPacketCommitmentResponse](ctx, chainA, &channeltypesv2.QueryPacketCommitmentRequest{ + ClientId: firstClientID, + Sequence: 1, + }) + s.Require().ErrorContains(err, "packet commitment hash not found") +} + +// TODO: Move or replace with existing stuff, moved over from solidity-ibc-eureka for convenience for now +func (s *IBCV2TransferTestSuite) BroadcastSdkTxBody(ctx context.Context, chain ibc.Chain, user ibc.Wallet, txBodyBz []byte, retries int) (sdk.TxResponse, error) { + var txBody txtypes.TxBody + err := proto.Unmarshal(txBodyBz, &txBody) + s.Require().NoError(err) + + var msgs []sdk.Msg + for _, msg := range txBody.Messages { + var sdkMsg sdk.Msg + err = chain.Config().EncodingConfig.InterfaceRegistry.UnpackAny(msg, &sdkMsg) + s.Require().NoError(err) + + msgs = append(msgs, sdkMsg) + } + + s.Require().NotZero(len(msgs)) + + var resp sdk.TxResponse + for range retries { + resp, err = s.BroadcastSdkMessages(ctx, chain.(*cosmos.CosmosChain), user, 500_000, msgs...) + if err == nil && resp.Code == 0 { + return resp, nil + } + if err != nil { + s.T().Logf("error broadcasting tx: %s", err) + } else { + s.T().Logf("tx failed with code %d: %s", resp.Code, resp.RawLog) + } + time.Sleep(5 * time.Second) + s.T().Logf("retrying tx") + } + return sdk.TxResponse{}, errors.New("failed to broadcast tx") +} + +// TODO: Move or replace with existing stuff, moved over from solidity-ibc-eureka for convenience for now +// BroadcastMessages broadcasts the provided messages to the given chain and signs them on behalf of the provided user. +// Once the broadcast response is returned, we wait for two blocks to be created on chain. +func (s *IBCV2TransferTestSuite) BroadcastSdkMessages(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, gas uint64, msgs ...sdk.Msg) (sdk.TxResponse, error) { + sdk.GetConfig().SetBech32PrefixForAccount(chain.Config().Bech32Prefix, chain.Config().Bech32Prefix+sdk.PrefixPublic) + sdk.GetConfig().SetBech32PrefixForValidator( + chain.Config().Bech32Prefix+sdk.PrefixValidator+sdk.PrefixOperator, + chain.Config().Bech32Prefix+sdk.PrefixValidator+sdk.PrefixOperator+sdk.PrefixPublic, + ) + + broadcaster := cosmos.NewBroadcaster(s.T(), chain) + + broadcaster.ConfigureClientContextOptions(func(clientContext client.Context) client.Context { + return clientContext. + WithCodec(chain.Config().EncodingConfig.Codec). + WithChainID(chain.Config().ChainID). + WithTxConfig(chain.Config().EncodingConfig.TxConfig) + }) + + broadcaster.ConfigureFactoryOptions(func(factory tx.Factory) tx.Factory { + return factory.WithGas(gas) + }) + + resp, err := cosmos.BroadcastTx(ctx, broadcaster, user, msgs...) + if err != nil { + return sdk.TxResponse{}, err + } + + // wait for 2 blocks for the transaction to be included + s.Require().NoError(testutil.WaitForBlocks(ctx, 2, chain)) + + if resp.Code != 0 { + return sdk.TxResponse{}, fmt.Errorf("tx failed with code %d: %s", resp.Code, resp.RawLog) + } + + return resp, nil +} diff --git a/e2e/testsuite/codec.go b/e2e/testsuite/codec.go index 01f553735cb..36783237226 100644 --- a/e2e/testsuite/codec.go +++ b/e2e/testsuite/codec.go @@ -29,8 +29,9 @@ import ( packetforwardtypes "github.com/cosmos/ibc-go/v10/modules/apps/packet-forward-middleware/types" ratelimitingtypes "github.com/cosmos/ibc-go/v10/modules/apps/rate-limiting/types" transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" - v7migrations "github.com/cosmos/ibc-go/v10/modules/core/02-client/migrations/v7" + clientmigrationsv7 "github.com/cosmos/ibc-go/v10/modules/core/02-client/migrations/v7" clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" + clienttypesv2 "github.com/cosmos/ibc-go/v10/modules/core/02-client/v2/types" connectiontypes "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" @@ -61,18 +62,25 @@ func SDKEncodingConfig() *testutil.TestEncodingConfig { func codecAndEncodingConfig() (*codec.ProtoCodec, testutil.TestEncodingConfig) { cfg := testutil.MakeTestEncodingConfig() - // ibc types - icacontrollertypes.RegisterInterfaces(cfg.InterfaceRegistry) - icahosttypes.RegisterInterfaces(cfg.InterfaceRegistry) - solomachine.RegisterInterfaces(cfg.InterfaceRegistry) - v7migrations.RegisterInterfaces(cfg.InterfaceRegistry) - transfertypes.RegisterInterfaces(cfg.InterfaceRegistry) + // ibc core types clienttypes.RegisterInterfaces(cfg.InterfaceRegistry) - channeltypes.RegisterInterfaces(cfg.InterfaceRegistry) + clienttypesv2.RegisterInterfaces(cfg.InterfaceRegistry) + clientmigrationsv7.RegisterInterfaces(cfg.InterfaceRegistry) connectiontypes.RegisterInterfaces(cfg.InterfaceRegistry) + channeltypes.RegisterInterfaces(cfg.InterfaceRegistry) + channeltypesv2.RegisterInterfaces(cfg.InterfaceRegistry) + + // ibc light clients types ibctmtypes.RegisterInterfaces(cfg.InterfaceRegistry) + solomachine.RegisterInterfaces(cfg.InterfaceRegistry) wasmtypes.RegisterInterfaces(cfg.InterfaceRegistry) - channeltypesv2.RegisterInterfaces(cfg.InterfaceRegistry) + + // ibc apps types + transfertypes.RegisterInterfaces(cfg.InterfaceRegistry) + icacontrollertypes.RegisterInterfaces(cfg.InterfaceRegistry) + icahosttypes.RegisterInterfaces(cfg.InterfaceRegistry) + + // ibc middleware types packetforwardtypes.RegisterInterfaces(cfg.InterfaceRegistry) ratelimitingtypes.RegisterInterfaces(cfg.InterfaceRegistry) diff --git a/e2e/testsuite/testsuite.go b/e2e/testsuite/testsuite.go index 55d435b7397..429ea2f20c9 100644 --- a/e2e/testsuite/testsuite.go +++ b/e2e/testsuite/testsuite.go @@ -58,7 +58,7 @@ type E2ETestSuite struct { relayerWallets relayer.Map logger *zap.Logger DockerClient *dockerclient.Client - network string + Network string // pathNameIndex is the latest index to be used for generating chains pathNameIndex int64 @@ -103,7 +103,7 @@ func (s *E2ETestSuite) initDockerClient() { client, network := interchaintest.DockerSetup(s.T()) s.logger = zap.NewExample() s.DockerClient = client - s.network = network + s.Network = network } // configureGenesisDebugExport sets, if needed, env variables to enable exporting of Genesis debug files. @@ -152,7 +152,7 @@ func (s *E2ETestSuite) configureGenesisDebugExport() { func (s *E2ETestSuite) initializeRelayerPool(n int) []ibc.Relayer { var relayers []ibc.Relayer for range n { - relayers = append(relayers, relayer.New(s.T(), *LoadConfig().GetActiveRelayerConfig(), s.logger, s.DockerClient, s.network)) + relayers = append(relayers, relayer.New(s.T(), *LoadConfig().GetActiveRelayerConfig(), s.logger, s.DockerClient, s.Network)) } return relayers } @@ -188,7 +188,7 @@ func (s *E2ETestSuite) SetupChains(ctx context.Context, chainCount int, channelO buildOpts := interchaintest.InterchainBuildOptions{ TestName: s.T().Name(), Client: s.DockerClient, - NetworkID: s.network, + NetworkID: s.Network, // we skip path creation because we are just creating the chains and not connections/channels SkipPathCreation: true, } diff --git a/e2e/testsuite/tx.go b/e2e/testsuite/tx.go index e6d83112385..d1122cd859e 100644 --- a/e2e/testsuite/tx.go +++ b/e2e/testsuite/tx.go @@ -121,7 +121,7 @@ func (s *E2ETestSuite) AssertTxFailure(resp sdk.TxResponse, expectedError *error // AssertTxSuccess verifies that an sdk.TxResponse has succeeded. func (s *E2ETestSuite) AssertTxSuccess(resp sdk.TxResponse) { errorMsg := addDebuggingInformation(fmt.Sprintf("%+v", resp)) - s.Require().Equal(resp.Code, uint32(0), errorMsg) + s.Require().Equal(uint32(0), resp.Code, errorMsg) s.Require().NotEmpty(resp.TxHash, errorMsg) s.Require().NotEqual(int64(0), resp.GasUsed, errorMsg) s.Require().NotEqual(int64(0), resp.GasWanted, errorMsg) diff --git a/simapp/app.go b/simapp/app.go index 8e385eb6b4d..f9cea7f6b24 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -112,8 +112,10 @@ import ( "github.com/cosmos/ibc-go/v10/modules/apps/transfer" ibctransferkeeper "github.com/cosmos/ibc-go/v10/modules/apps/transfer/keeper" ibctransfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + transferv2 "github.com/cosmos/ibc-go/v10/modules/apps/transfer/v2" ibc "github.com/cosmos/ibc-go/v10/modules/core" porttypes "github.com/cosmos/ibc-go/v10/modules/core/05-port/types" + ibcapi "github.com/cosmos/ibc-go/v10/modules/core/api" ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v10/modules/core/keeper" solomachine "github.com/cosmos/ibc-go/v10/modules/light-clients/06-solomachine" @@ -377,6 +379,7 @@ func NewSimApp( // Create IBC Router ibcRouter := porttypes.NewRouter() + ibcRouterV2 := ibcapi.NewRouter() // Middleware Stacks @@ -430,8 +433,12 @@ func NewSimApp( AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). AddRoute(icahosttypes.SubModuleName, icaHostStack) + // register the transfer v2 module. + ibcRouterV2.AddRoute(ibctransfertypes.PortID, transferv2.NewIBCModule(app.TransferKeeper)) + // Set the IBC Routers app.IBCKeeper.SetRouter(ibcRouter) + app.IBCKeeper.SetRouterV2(ibcRouterV2) clientKeeper := app.IBCKeeper.ClientKeeper storeProvider := clientKeeper.GetStoreProvider() diff --git a/simapp/go.mod b/simapp/go.mod index e87545a3ac1..050707b1631 100644 --- a/simapp/go.mod +++ b/simapp/go.mod @@ -23,7 +23,7 @@ require ( github.com/cosmos/cosmos-db v1.1.3 github.com/cosmos/cosmos-sdk v0.53.2 github.com/cosmos/gogoproto v1.7.0 - github.com/cosmos/ibc-go/v10 v10.0.0 + github.com/cosmos/ibc-go/v10 v10.3.0 github.com/spf13/cast v1.9.2 github.com/spf13/cobra v1.9.1 github.com/spf13/viper v1.20.1 From 25e112291fe91929695dd566f007c1873f6261f3 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Tue, 24 Jun 2025 04:03:05 +0300 Subject: [PATCH 2/5] use standard image --- e2e/tests/transfer/v2/transfer_ibc_v2_test.go | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/e2e/tests/transfer/v2/transfer_ibc_v2_test.go b/e2e/tests/transfer/v2/transfer_ibc_v2_test.go index 1e378609d3c..06b45a47951 100644 --- a/e2e/tests/transfer/v2/transfer_ibc_v2_test.go +++ b/e2e/tests/transfer/v2/transfer_ibc_v2_test.go @@ -10,12 +10,22 @@ import ( "testing" "time" + "github.com/cosmos/gogoproto/proto" + "github.com/cosmos/interchaintest/v10/chain/cosmos" + "github.com/cosmos/interchaintest/v10/ibc" + "github.com/cosmos/interchaintest/v10/testutil" + "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/config" + "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/container" + "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/dockerutil" + "github.com/stretchr/testify/suite" + "go.uber.org/zap" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" txtypes "github.com/cosmos/cosmos-sdk/types/tx" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/gogoproto/proto" + "github.com/cosmos/ibc-go/e2e/testsuite" "github.com/cosmos/ibc-go/e2e/testsuite/query" "github.com/cosmos/ibc-go/e2e/testvalues" @@ -23,14 +33,6 @@ import ( clienttypesv2 "github.com/cosmos/ibc-go/v10/modules/core/02-client/v2/types" channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" - "github.com/cosmos/interchaintest/v10/chain/cosmos" - "github.com/cosmos/interchaintest/v10/ibc" - "github.com/cosmos/interchaintest/v10/testutil" - "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/config" - "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/container" - "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/dockerutil" - "github.com/stretchr/testify/suite" - "go.uber.org/zap" ) type IBCV2TransferTestSuite struct { @@ -71,7 +73,7 @@ func (s *IBCV2TransferTestSuite) TestIBCV2Transfer() { ChainBUser: relayerUserB.FormattedAddress(), })) relayerConfig.Address = "0.0.0.0" - relayerAPIContainer, err := container.SpinUpRelayerApiContainer(ctx, logger, docker, "ibc-go-relayer", relayerConfig, []string{"v1.2.0"}) + relayerAPIContainer, err := container.SpinUpRelayerApiContainer(ctx, logger, docker, "v0.6.0", relayerConfig, []string{"v1.2.0"}) s.Require().NoError(err) t.Cleanup(func() { ctx := context.TODO() @@ -190,7 +192,7 @@ func (s *IBCV2TransferTestSuite) BroadcastSdkTxBody(ctx context.Context, chain i msgs = append(msgs, sdkMsg) } - s.Require().NotZero(len(msgs)) + s.Require().NotEmpty(msgs) var resp sdk.TxResponse for range retries { From e771540707fea983ce7c427ad667dc9faead017c Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Tue, 24 Jun 2025 07:04:47 +0300 Subject: [PATCH 3/5] lint + use depot --- .github/workflows/build-wasm-simd-image-from-tag.yml | 4 ++-- modules/core/04-channel/v2/keeper/packet_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-wasm-simd-image-from-tag.yml b/.github/workflows/build-wasm-simd-image-from-tag.yml index 432d5cbc824..d4070dc0562 100644 --- a/.github/workflows/build-wasm-simd-image-from-tag.yml +++ b/.github/workflows/build-wasm-simd-image-from-tag.yml @@ -22,9 +22,9 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-24.04 + - os: depot-ubuntu-24.04-4 platform: linux/amd64 - - os: ubuntu-24.04-arm + - os: depot-ubuntu-24.04-arm-4 platform: linux/arm64 runs-on: ${{ matrix.os }} steps: diff --git a/modules/core/04-channel/v2/keeper/packet_test.go b/modules/core/04-channel/v2/keeper/packet_test.go index c81a59db009..293b3c8491b 100644 --- a/modules/core/04-channel/v2/keeper/packet_test.go +++ b/modules/core/04-channel/v2/keeper/packet_test.go @@ -9,7 +9,7 @@ import ( clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" clientv2types "github.com/cosmos/ibc-go/v10/modules/core/02-client/v2/types" - v11 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/migrations/v11" + "github.com/cosmos/ibc-go/v10/modules/core/04-channel/migrations/v11" channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" commitmenttypes "github.com/cosmos/ibc-go/v10/modules/core/23-commitment/types" From a068180d1f430ca38d588e6b860f73563bf5893d Mon Sep 17 00:00:00 2001 From: Aditya Sripal <14364734+AdityaSripal@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:14:10 +0200 Subject: [PATCH 4/5] write alias e2e test --- e2e/tests/transfer/v2/alias_test.go | 219 ++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 e2e/tests/transfer/v2/alias_test.go diff --git a/e2e/tests/transfer/v2/alias_test.go b/e2e/tests/transfer/v2/alias_test.go new file mode 100644 index 00000000000..8cf5dcffe02 --- /dev/null +++ b/e2e/tests/transfer/v2/alias_test.go @@ -0,0 +1,219 @@ +//go:build !test_e2e + +package v2 + +import ( + "context" + "encoding/hex" + "testing" + "time" + + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testsuite/query" + "github.com/cosmos/ibc-go/e2e/testvalues" + transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" + "github.com/cosmos/interchaintest/v10/ibc" + "github.com/cosmos/interchaintest/v10/testutil" + "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/config" + "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/container" + "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/dockerutil" + "go.uber.org/zap" +) + +func (s *IBCV2TransferTestSuite) TestAlias() { + t := s.T() + ctx := context.TODO() + logger := zap.NewExample() + + testName := t.Name() + + // NOTE: t.Parallel() should be called before SetupPath in all tests. + // t.Name() must be stored in a variable before t.Parallel() otherwise t.Name() is not + // deterministic. + t.Parallel() + + chainA, chainB := s.GetChains() + userA := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + userAAddress := userA.FormattedAddress() + userB := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + userBAddress := userB.FormattedAddress() + relayerUserA := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + relayerUserB := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + // Create a V1 path between chain A and chain B + s.CreatePaths(ibc.DefaultClientOpts(), s.TransferChannelOptions(), testName) + v1Relayer := s.GetRelayerForTest(testName) + channelA := s.GetChannelBetweenChains(testName, chainA, chainB) + + // Set up docker util + docker, err := dockerutil.DockerWithExistingSetup(ctx, logger, t.Name(), s.DockerClient, s.Network) + s.Require().NoError(err) + + // Spin up relayer API + relayerConfig := config.NewConfig(config.CreateCosmosCosmosModules(config.CosmosToCosmosConfigInfo{ + ChainAID: chainA.Config().ChainID, + ChainBID: chainB.Config().ChainID, + ChainATmRPC: chainA.GetRPCAddress(), + ChainBTmRPC: chainB.GetRPCAddress(), + ChainAUser: relayerUserA.FormattedAddress(), + ChainBUser: relayerUserB.FormattedAddress(), + })) + relayerConfig.Address = "0.0.0.0" + relayerAPIContainer, err := container.SpinUpRelayerApiContainer(ctx, logger, docker, "v0.6.0", relayerConfig, []string{"v1.2.0"}) + s.Require().NoError(err) + t.Cleanup(func() { + ctx := context.TODO() + if err := docker.Cleanup(ctx, true); err != nil { + t.Logf("error cleaning up docker: %s", err) + } + }) + + /// STAGE 1: Initiate transfer from chainA to chainB + // with IBC V2 protocol using the v1 channel ID + + timeoutTimestamp := uint64(time.Now().Add(5 * time.Minute).Unix()) + msg := &transfertypes.MsgTransfer{ + SourcePort: transfertypes.PortID, + SourceChannel: channelA.ChannelID, + Token: testvalues.DefaultTransferAmount(chainA.Config().Denom), + Sender: userA.FormattedAddress(), + Receiver: userB.FormattedAddress(), + TimeoutTimestamp: timeoutTimestamp, + Memo: "", + } + transferOnAResp := s.BroadcastMessages(ctx, chainA, userA, msg) + s.AssertTxSuccess(transferOnAResp) + err = testutil.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) + + // Verify tokens are escrowed on chainA + chainABalance, err := s.GetChainANativeBalance(ctx, userA) + s.Require().NoError(err) + expectedChainABalance := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expectedChainABalance, chainABalance) + + // Relay the packet from chainA to chainB + // with IBC V2 protocol using the v1 channel IDs + transferOnARespTxHash, err := hex.DecodeString(transferOnAResp.TxHash) + s.Require().NoError(err) + receiveTx, err := relayerAPIContainer.GetRelayTx(ctx, chainA.Config().ChainID, chainB.Config().ChainID, channelA.ChannelID, channelA.Counterparty.ChannelID, transferOnARespTxHash) + s.Require().NoError(err) + err = testutil.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) + receiveOnBResp, err := s.BroadcastSdkTxBody(ctx, chainB, relayerUserB, receiveTx, 5) + s.Require().NoError(err) + s.AssertTxSuccess(receiveOnBResp) + + // Verify tokens are transferred to chainB + ibcDenom := transfertypes.NewDenom(chainA.Config().Denom, transfertypes.NewHop(transfertypes.PortID, channelA.Counterparty.ChannelID)).IBCDenom() + chainBBalanceResp, err := query.GRPCQuery[banktypes.QueryBalanceResponse](ctx, chainB, &banktypes.QueryBalanceRequest{ + Address: userB.FormattedAddress(), + Denom: ibcDenom, + }) + s.Require().NoError(err) + s.Require().NotNil(chainBBalanceResp.Balance) + s.Require().Equal(testvalues.IBCTransferAmount, chainBBalanceResp.Balance.Amount.Int64()) + + // Relay ack back from chainB to chainA + err = testutil.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) + relayOnBRespTxHash, err := hex.DecodeString(receiveOnBResp.TxHash) + s.Require().NoError(err) + relayAckTx, err := relayerAPIContainer.GetRelayTx(ctx, chainB.Config().ChainID, chainA.Config().ChainID, channelA.Counterparty.ChannelID, channelA.ChannelID, relayOnBRespTxHash) + s.Require().NoError(err) + err = testutil.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) + relayAckOnAResp, err := s.BroadcastSdkTxBody(ctx, chainA, relayerUserA, relayAckTx, 5) + s.Require().NoError(err) + s.AssertTxSuccess(relayAckOnAResp) + err = testutil.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) + + // Verify packet commitment is deleted (i.e. packet is acknowledged) on chainA + // again we use the v1 channel ID in place of the client ID in IBC V2 protocol + _, err = query.GRPCQuery[channeltypesv2.QueryPacketCommitmentResponse](ctx, chainA, &channeltypesv2.QueryPacketCommitmentRequest{ + ClientId: channelA.ChannelID, + Sequence: 1, + }) + s.Require().ErrorContains(err, "packet commitment hash not found") + + /// STAGE 2: Use the v1 protocol to send the same tokens back to chain A + + t.Run("IBC token transfer of vouchers from chainB back to chainA, receiver chain is source of tokens", func(t *testing.T) { + transferTxResp := s.Transfer(ctx, chainB, userB, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, testvalues.DefaultTransferAmount(ibcDenom), userBAddress, userAAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") + s.AssertTxSuccess(transferTxResp) + }) + + t.Run("vouchers are burned", func(t *testing.T) { + actualBalance, err := testsuite.GetChainBalanceForDenom(ctx, chainB, ibcDenom, userB) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + + // TODO: cannot query total escrow if tests in parallel are using the same denom. + // if testvalues.TotalEscrowFeatureReleases.IsSupported(chainAVersion) { + // actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) + // s.Require().NoError(err) + // + // expectedTotalEscrow := sdk.NewCoin(chainADenom, sdkmath.NewInt(testvalues.IBCTransferAmount)) + // s.Require().Equal(expectedTotalEscrow, actualTotalEscrow) + // } + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(v1Relayer, testName) + }) + + t.Run("v1 packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainB, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, 1) + + actualBalance, err := query.Balance(ctx, chainA, userAAddress, chainA.Config().Denom) + s.Require().NoError(err) + + // sender should have the same balance as before the first transfer + // since we have now sent the tokens back to chain A using IBC v1 + expected := testvalues.StartingTokenAmount + s.Require().Equal(expected, actualBalance.Int64()) + }) + + /// STAGE 3: Use the v1 protocol to send the original tokens back to chainB + // Ensure that the sequence number is incremented correctly + + t.Run("native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) { + transferTxResp := s.Transfer(ctx, chainA, userA, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainA.Config().Denom), userAAddress, userBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.AssertTxSuccess(transferTxResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, userA) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + + // TODO: cannot query total escrow if tests in parallel are using the same denom. + // if testvalues.TotalEscrowFeatureReleases.IsSupported(chainAVersion) { + // actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) + // s.Require().NoError(err) + // + // expectedTotalEscrow := sdk.NewCoin(chainADenom, sdkmath.NewInt(testvalues.IBCTransferAmount)) + // s.Require().Equal(expectedTotalEscrow, actualTotalEscrow) + // } + }) + + t.Run("packets are relayed", func(t *testing.T) { + // ensure that the sequence number is incremented correctly + // since the first packet on this channel was sent using IBC V2 protocol + s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 2) + + actualBalance, err := query.Balance(ctx, chainB, userBAddress, ibcDenom) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance.Int64()) + }) + +} From 13ce2f34f66c907d64807eab86670ce98e982eb0 Mon Sep 17 00:00:00 2001 From: Aditya Sripal <14364734+AdityaSripal@users.noreply.github.com> Date: Wed, 25 Jun 2025 12:59:24 +0200 Subject: [PATCH 5/5] make alias test runnable --- e2e/tests/transfer/v2/alias_test.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/e2e/tests/transfer/v2/alias_test.go b/e2e/tests/transfer/v2/alias_test.go index 8cf5dcffe02..da63a75fd47 100644 --- a/e2e/tests/transfer/v2/alias_test.go +++ b/e2e/tests/transfer/v2/alias_test.go @@ -8,21 +8,41 @@ import ( "testing" "time" + testifysuite "github.com/stretchr/testify/suite" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/ibc-go/e2e/testsuite" "github.com/cosmos/ibc-go/e2e/testsuite/query" "github.com/cosmos/ibc-go/e2e/testvalues" + transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" + "github.com/cosmos/interchaintest/v10/ibc" "github.com/cosmos/interchaintest/v10/testutil" + "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/config" "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/container" "github.com/cosmos/solidity-ibc-eureka/packages/go-relayer-api/dockerutil" + "go.uber.org/zap" ) -func (s *IBCV2TransferTestSuite) TestAlias() { +func TestAliasTestSuite(t *testing.T) { + testifysuite.Run(t, new(AliasTestSuite)) +} + +type AliasTestSuite struct { + IBCV2TransferTestSuite +} + +// SetupSuite sets up chains for the current test suite +func (s *AliasTestSuite) SetupTest() { + s.SetupChains(context.TODO(), 2, nil) +} + +func (s *AliasTestSuite) TestAlias() { t := s.T() ctx := context.TODO() logger := zap.NewExample() @@ -82,6 +102,7 @@ func (s *IBCV2TransferTestSuite) TestAlias() { Receiver: userB.FormattedAddress(), TimeoutTimestamp: timeoutTimestamp, Memo: "", + UseAliasing: true, // Enable aliasing for the transfer } transferOnAResp := s.BroadcastMessages(ctx, chainA, userA, msg) s.AssertTxSuccess(transferOnAResp)