diff --git a/Dockerfile b/Dockerfile index 07546c6b8f6..01937d61174 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,4 +17,4 @@ COPY --from=gaiad-builder /go/bin/gaiad /usr/local/bin/ EXPOSE 26656 26657 1317 9090 USER 0 -ENTRYPOINT ["gaiad", "start"] +ENTRYPOINT ["gaiad", "start"] \ No newline at end of file diff --git a/e2e.Dockerfile b/e2e.Dockerfile index d6facae2f8e..2c7eb0e1124 100644 --- a/e2e.Dockerfile +++ b/e2e.Dockerfile @@ -11,7 +11,8 @@ RUN apk add --no-cache $PACKAGES RUN CGO_ENABLED=0 make install # Add to a distroless container -FROM cgr.dev/chainguard/static:$IMG_TAG +FROM alpine:$IMG_TAG +RUN adduser -D nonroot ARG IMG_TAG COPY --from=gaiad-builder /go/bin/gaiad /usr/local/bin/ EXPOSE 26656 26657 1317 9090 diff --git a/go.mod b/go.mod index 567c0f94dda..15837fde7d5 100644 --- a/go.mod +++ b/go.mod @@ -4,36 +4,40 @@ go 1.20 require ( cosmossdk.io/api v0.3.1 - cosmossdk.io/errors v1.0.0-beta.7 cosmossdk.io/math v1.0.1 cosmossdk.io/simapp v0.0.0-20230602123434-616841b9704d cosmossdk.io/tools/rosetta v0.2.1 github.com/cometbft/cometbft v0.37.1 github.com/cometbft/cometbft-db v0.8.0 github.com/cosmos/cosmos-sdk v0.47.3 + github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/gogoproto v1.4.10 github.com/cosmos/ibc-go/v7 v7.1.0 github.com/cosmos/interchain-security/v3 v3.0.0-rc0 github.com/gorilla/mux v1.8.0 + github.com/rakyll/statik v0.1.7 + github.com/spf13/cast v1.5.1 + github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.16.0 github.com/strangelove-ventures/packet-forward-middleware/v7 v7.0.0-20230412224111-136e94e98861 github.com/stretchr/testify v1.8.4 ) +require ( + cosmossdk.io/errors v1.0.0-beta.7 + github.com/ory/dockertest/v3 v3.10.0 +) + require ( cloud.google.com/go v0.110.0 // indirect cloud.google.com/go/compute v1.19.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v0.13.0 // indirect cloud.google.com/go/storage v1.29.0 // indirect - github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/golang/protobuf v1.5.3 // indirect // github.com/gravity-devs/liquidity v1.6.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/rakyll/statik v0.1.7 - github.com/spf13/cast v1.5.1 - github.com/spf13/cobra v1.7.0 google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect google.golang.org/grpc v1.55.0 // indirect ) @@ -45,7 +49,10 @@ require ( filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/Microsoft/go-winio v0.6.0 // indirect + github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -59,6 +66,7 @@ require ( github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect github.com/confio/ics23/go v0.9.0 // indirect + github.com/containerd/continuity v0.3.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect @@ -74,6 +82,10 @@ require ( github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect + github.com/docker/cli v20.10.17+incompatible // indirect + github.com/docker/docker v20.10.19+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect @@ -96,6 +108,7 @@ require ( github.com/google/go-cmp v0.5.9 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/google/s2a-go v0.1.3 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.8.0 // indirect @@ -115,6 +128,7 @@ require ( github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/huandu/skiplist v1.2.0 // indirect github.com/iancoleman/orderedmap v0.2.0 // indirect + github.com/imdario/mergo v0.3.13 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect @@ -133,8 +147,11 @@ require ( github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/onsi/gomega v1.26.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc2 // indirect github.com/opencontainers/runc v1.1.5 // indirect github.com/oxyno-zeta/gomock-extra-matcher v1.1.0 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect @@ -149,6 +166,7 @@ require ( github.com/rs/cors v1.8.3 // indirect github.com/rs/zerolog v1.29.1 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect @@ -156,12 +174,16 @@ require ( github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.6.0 // indirect github.com/ulikunitz/xz v0.5.11 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.14.1 // indirect go.etcd.io/bbolt v1.3.7 // indirect go.opencensus.io v0.24.0 // indirect golang.org/x/crypto v0.9.0 // indirect golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect + golang.org/x/mod v0.9.0 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect golang.org/x/sys v0.8.0 // indirect @@ -189,11 +211,8 @@ replace ( // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.8.1 - // Liquidity force withdrawal: https://www.mintscan.io/cosmos/proposals/801 - // github.com/gravity-devs/liquidity => github.com/gravity-devs/liquidity v1.6.0-forced-withdrawal-rc1 - - // Comet - github.com/tendermint/tendermint => github.com/cometbft/cometbft v0.34.29 + // following versions might cause unexpected behavior + github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // latest grpc doesn't work with with our modified proto compiler, so we need to enforce // the following version across all dependencies. diff --git a/go.sum b/go.sum index 7e0d2592f7b..d323d9de5d6 100644 --- a/go.sum +++ b/go.sum @@ -425,6 +425,7 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3 github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= @@ -434,7 +435,9 @@ github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3 github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= +github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -578,6 +581,7 @@ github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1 github.com/consensys/gnark-crypto v0.5.3/go.mod h1:hOdPlWQV1gDLp7faZVeg8Y0iEPFaOUnCc4XeCCk96p0= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -620,6 +624,8 @@ github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJF github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= @@ -656,10 +662,16 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M= +github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.19+incompatible h1:lzEmjivyNHFHMNAFLXORMBXyGIhw/UP4DvJwvyKYq64= +github.com/docker/docker v20.10.19+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -693,7 +705,6 @@ github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= @@ -736,8 +747,8 @@ github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4 github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= @@ -858,13 +869,14 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.3 h1:FAgZmpLl/SXurPEZyCMPBIiiYeTbqfjlbdnCNTAkbGE= github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -976,6 +988,8 @@ github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36 github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -1126,6 +1140,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1155,7 +1171,6 @@ github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= @@ -1165,21 +1180,18 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= 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-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= +github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -1194,6 +1206,8 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4= +github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg= github.com/oxyno-zeta/gomock-extra-matcher v1.1.0 h1:Yyk5ov0ZPKBXtVEeIWtc4J2XVrHuNoIK+0F2BUJgtsc= github.com/oxyno-zeta/gomock-extra-matcher v1.1.0/go.mod h1:UMGTHYEmJ1dRq8LDZ7VTAYO4nqM3GD1UGC3RJEUxEz0= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= @@ -1303,6 +1317,7 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1352,7 +1367,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -1361,9 +1375,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= -github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= @@ -1399,6 +1412,12 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -1514,6 +1533,7 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1562,7 +1582,6 @@ golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1693,7 +1712,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1740,6 +1758,7 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1801,6 +1820,7 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1839,7 +1859,6 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -2106,10 +2125,12 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/tests/e2e/address.go b/tests/e2e/address.go index 09a8d2e986a..33079aa8ce8 100644 --- a/tests/e2e/address.go +++ b/tests/e2e/address.go @@ -1,34 +1,33 @@ package e2e -// -// import ( -// "fmt" -// "math/rand" -// "strconv" -// -// "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" -// crypto "github.com/cosmos/cosmos-sdk/crypto/types" -// sdk "github.com/cosmos/cosmos-sdk/types" -//) -// -//// HDPath generates an HD path based on the wallet index -// func HDPath(index int) string { -// return fmt.Sprintf("m/44'/118'/0'/0/%d", index) -//} -// -//// PubKey returns a sample account PubKey -// func PubKey() crypto.PubKey { -// seed := []byte(strconv.Itoa(rand.Int())) -// return ed25519.GenPrivKeyFromSecret(seed).PubKey() -//} -// -//// AccAddress returns a sample account address -// func AccAddress() sdk.AccAddress { -// addr := PubKey().Address() -// return sdk.AccAddress(addr) -//} -// -//// Address returns a sample string account address -// func Address() string { -// return AccAddress().String() -//} +import ( + "fmt" + "math/rand" + "strconv" + + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + crypto "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// HDPath generates an HD path based on the wallet index +func HDPath(index int) string { + return fmt.Sprintf("m/44'/118'/0'/0/%d", index) +} + +// PubKey returns a sample account PubKey +func PubKey() crypto.PubKey { + seed := []byte(strconv.Itoa(rand.Int())) + return ed25519.GenPrivKeyFromSecret(seed).PubKey() +} + +// AccAddress returns a sample account address +func AccAddress() sdk.AccAddress { + addr := PubKey().Address() + return sdk.AccAddress(addr) +} + +// Address returns a sample string account address +func Address() string { + return AccAddress().String() +} diff --git a/tests/e2e/chain.go b/tests/e2e/chain.go index b5ff7995c4b..81706d36a5c 100644 --- a/tests/e2e/chain.go +++ b/tests/e2e/chain.go @@ -1,124 +1,138 @@ package e2e -// import ( -// "fmt" -// "os" - -// "github.com/cosmos/cosmos-sdk/client" -// "github.com/cosmos/cosmos-sdk/codec" -// sdk "github.com/cosmos/cosmos-sdk/types" -// authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" -// evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" -// stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" -// tmrand "github.com/tendermint/tendermint/libs/rand" - -// gaia "github.com/cosmos/gaia/v11/app" -// "github.com/cosmos/gaia/v11/app/params" -// ) - -// const ( -// keyringPassphrase = "testpassphrase" -// keyringAppName = "testnet" -// ) - -// var ( -// encodingConfig params.EncodingConfig -// cdc codec.Codec -// txConfig client.TxConfig -// ) - -// func init() { -// encodingConfig = gaia.MakeTestEncodingConfig() -// authvesting.RegisterInterfaces(encodingConfig.InterfaceRegistry) -// stakingtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) -// evidencetypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) -// cdc = encodingConfig.Codec -// txConfig = encodingConfig.TxConfig -// } - -// type chain struct { -// dataDir string -// id string -// validators []*validator -// accounts []*account //nolint:unused -// // initial accounts in genesis -// genesisAccounts []*account -// genesisVestingAccounts map[string]sdk.AccAddress -// } - -// func newChain() (*chain, error) { -// tmpDir, err := os.MkdirTemp("", "gaia-e2e-testnet-") -// if err != nil { -// return nil, err -// } - -// return &chain{ -// id: "chain-" + tmrand.Str(6), -// dataDir: tmpDir, -// }, nil -// } - -// func (c *chain) configDir() string { -// return fmt.Sprintf("%s/%s", c.dataDir, c.id) -// } - -// func (c *chain) createAndInitValidators(count int) error { -// for i := 0; i < count; i++ { -// node := c.createValidator(i) - -// // generate genesis files -// if err := node.init(); err != nil { -// return err -// } - -// c.validators = append(c.validators, node) - -// // create keys -// if err := node.createKey("val"); err != nil { -// return err -// } -// if err := node.createNodeKey(); err != nil { -// return err -// } -// if err := node.createConsensusKey(); err != nil { -// return err -// } -// } - -// return nil -// } - -// func (c *chain) createAndInitValidatorsWithMnemonics(count int, mnemonics []string) error { //nolint:unused // this is called during e2e tests -// for i := 0; i < count; i++ { -// // create node -// node := c.createValidator(i) - -// // generate genesis files -// if err := node.init(); err != nil { -// return err -// } - -// c.validators = append(c.validators, node) - -// // create keys -// if err := node.createKeyFromMnemonic("val", mnemonics[i]); err != nil { -// return err -// } -// if err := node.createNodeKey(); err != nil { -// return err -// } -// if err := node.createConsensusKey(); err != nil { -// return err -// } -// } - -// return nil -// } - -// func (c *chain) createValidator(index int) *validator { -// return &validator{ -// chain: c, -// index: index, -// moniker: fmt.Sprintf("%s-gaia-%d", c.id, index), -// } -// } +import ( + "fmt" + "os" + + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + + tmrand "github.com/cometbft/cometbft/libs/rand" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" + distribtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + govv1types "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + govv1beta1types "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + gaiaparams "github.com/cosmos/gaia/v11/app/params" +) + +const ( + keyringPassphrase = "testpassphrase" + keyringAppName = "testnet" +) + +var ( + encodingConfig gaiaparams.EncodingConfig + cdc codec.Codec + txConfig client.TxConfig +) + +func init() { + encodingConfig = gaiaparams.MakeEncodingConfig() + authtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + authvesting.RegisterInterfaces(encodingConfig.InterfaceRegistry) + stakingtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + evidencetypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + cryptocodec.RegisterInterfaces(encodingConfig.InterfaceRegistry) + govv1types.RegisterInterfaces(encodingConfig.InterfaceRegistry) + govv1beta1types.RegisterInterfaces(encodingConfig.InterfaceRegistry) + + upgradetypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + distribtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + + cdc = encodingConfig.Marshaler + txConfig = encodingConfig.TxConfig +} + +type chain struct { + dataDir string + id string + validators []*validator + accounts []*account //nolint:unused + // initial accounts in genesis + genesisAccounts []*account + genesisVestingAccounts map[string]sdk.AccAddress +} + +func newChain() (*chain, error) { + tmpDir, err := os.MkdirTemp("", "gaia-e2e-testnet-") + if err != nil { + return nil, err + } + + return &chain{ + id: "chain-" + tmrand.Str(6), + dataDir: tmpDir, + }, nil +} + +func (c *chain) configDir() string { + return fmt.Sprintf("%s/%s", c.dataDir, c.id) +} + +func (c *chain) createAndInitValidators(count int) error { + for i := 0; i < count; i++ { + node := c.createValidator(i) + + // generate genesis files + if err := node.init(); err != nil { + return err + } + + c.validators = append(c.validators, node) + + // create keys + if err := node.createKey("val"); err != nil { + return err + } + if err := node.createNodeKey(); err != nil { + return err + } + if err := node.createConsensusKey(); err != nil { + return err + } + } + + return nil +} + +func (c *chain) createAndInitValidatorsWithMnemonics(count int, mnemonics []string) error { //nolint:unused // this is called during e2e tests + for i := 0; i < count; i++ { + // create node + node := c.createValidator(i) + + // generate genesis files + if err := node.init(); err != nil { + return err + } + + c.validators = append(c.validators, node) + + // create keys + if err := node.createKeyFromMnemonic("val", mnemonics[i]); err != nil { + return err + } + if err := node.createNodeKey(); err != nil { + return err + } + if err := node.createConsensusKey(); err != nil { + return err + } + } + + return nil +} + +func (c *chain) createValidator(index int) *validator { + return &validator{ + chain: c, + index: index, + moniker: fmt.Sprintf("%s-gaia-%d", c.id, index), + } +} diff --git a/tests/e2e/docker/hermes.Dockerfile b/tests/e2e/docker/hermes.Dockerfile index 54795ef313a..f6086acf861 100644 --- a/tests/e2e/docker/hermes.Dockerfile +++ b/tests/e2e/docker/hermes.Dockerfile @@ -1,4 +1,4 @@ -FROM informalsystems/hermes:1.3.0 AS hermes-builder +FROM informalsystems/hermes:1.4.0 AS hermes-builder FROM debian:buster-slim USER root diff --git a/tests/e2e/e2e_bank_test.go b/tests/e2e/e2e_bank_test.go index 4827b1b28a3..bb9e7ffbc2f 100644 --- a/tests/e2e/e2e_bank_test.go +++ b/tests/e2e/e2e_bank_test.go @@ -1,60 +1,59 @@ package e2e -// -// import ( -// "fmt" -// "time" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -//) -// -// func (s *IntegrationTestSuite) testBankTokenTransfer() { -// s.Run("send_photon_between_accounts", func() { -// var err error -// senderAddress := s.chainA.validators[0].keyInfo.GetAddress() -// sender := senderAddress.String() -// -// recipientAddress := s.chainA.validators[1].keyInfo.GetAddress() -// recipient := recipientAddress.String() -// -// chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) -// -// var ( -// beforeSenderUAtomBalance sdk.Coin -// beforeRecipientUAtomBalance sdk.Coin -// ) -// -// s.Require().Eventually( -// func() bool { -// beforeSenderUAtomBalance, err = getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) -// s.Require().NoError(err) -// -// beforeRecipientUAtomBalance, err = getSpecificBalance(chainAAPIEndpoint, recipient, uatomDenom) -// s.Require().NoError(err) -// -// return beforeSenderUAtomBalance.IsValid() && beforeRecipientUAtomBalance.IsValid() -// }, -// 10*time.Second, -// 5*time.Second, -// ) -// -// s.execBankSend(s.chainA, 0, sender, recipient, tokenAmount.String(), standardFees.String(), false) -// -// s.Require().Eventually( -// func() bool { -// afterSenderUAtomBalance, err := getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) -// s.Require().NoError(err) -// -// afterRecipientUAtomBalance, err := getSpecificBalance(chainAAPIEndpoint, recipient, uatomDenom) -// s.Require().NoError(err) -// -// decremented := beforeSenderUAtomBalance.Sub(tokenAmount).Sub(standardFees).IsEqual(afterSenderUAtomBalance) -// incremented := beforeRecipientUAtomBalance.Add(tokenAmount).IsEqual(afterRecipientUAtomBalance) -// -// return decremented && incremented -// }, -// time.Minute, -// 5*time.Second, -// ) -// }) -//} +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (s *IntegrationTestSuite) testBankTokenTransfer() { + s.Run("send_photon_between_accounts", func() { + var err error + senderAddress, _ := s.chainA.validators[0].keyInfo.GetAddress() + sender := senderAddress.String() + + recipientAddress, _ := s.chainA.validators[1].keyInfo.GetAddress() + recipient := recipientAddress.String() + + chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + + var ( + beforeSenderUAtomBalance sdk.Coin + beforeRecipientUAtomBalance sdk.Coin + ) + + s.Require().Eventually( + func() bool { + beforeSenderUAtomBalance, err = getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) + s.Require().NoError(err) + + beforeRecipientUAtomBalance, err = getSpecificBalance(chainAAPIEndpoint, recipient, uatomDenom) + s.Require().NoError(err) + + return beforeSenderUAtomBalance.IsValid() && beforeRecipientUAtomBalance.IsValid() + }, + 10*time.Second, + 5*time.Second, + ) + + s.execBankSend(s.chainA, 0, sender, recipient, tokenAmount.String(), standardFees.String(), false) + + s.Require().Eventually( + func() bool { + afterSenderUAtomBalance, err := getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) + s.Require().NoError(err) + + afterRecipientUAtomBalance, err := getSpecificBalance(chainAAPIEndpoint, recipient, uatomDenom) + s.Require().NoError(err) + + decremented := beforeSenderUAtomBalance.Sub(tokenAmount).Sub(standardFees).IsEqual(afterSenderUAtomBalance) + incremented := beforeRecipientUAtomBalance.Add(tokenAmount).IsEqual(afterRecipientUAtomBalance) + + return decremented && incremented + }, + time.Minute, + 5*time.Second, + ) + }) +} diff --git a/tests/e2e/e2e_distribution_test.go b/tests/e2e/e2e_distribution_test.go index ff1471e4516..e00359c274d 100644 --- a/tests/e2e/e2e_distribution_test.go +++ b/tests/e2e/e2e_distribution_test.go @@ -1,89 +1,88 @@ package e2e -// -// import ( -// "fmt" -// "time" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -//) -// -// func (s *IntegrationTestSuite) testDistribution() { -// chainEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) -// -// validatorB := s.chainA.validators[1] -// validatorBAddr := validatorB.keyInfo.GetAddress() -// -// valOperAddressA := sdk.ValAddress(validatorBAddr).String() -// -// delegatorAddress := s.chainA.genesisAccounts[2].keyInfo.GetAddress().String() -// -// newWithdrawalAddress := s.chainA.genesisAccounts[3].keyInfo.GetAddress().String() -// fees := sdk.NewCoin(uatomDenom, sdk.NewInt(1000)) -// -// beforeBalance, err := getSpecificBalance(chainEndpoint, newWithdrawalAddress, uatomDenom) -// s.Require().NoError(err) -// if beforeBalance.IsNil() { -// beforeBalance = sdk.NewCoin(uatomDenom, sdk.NewInt(0)) -// } -// -// s.execSetWithdrawAddress(s.chainA, 0, fees.String(), delegatorAddress, newWithdrawalAddress, gaiaHomePath) -// -// // Verify -// s.Require().Eventually( -// func() bool { -// res, err := queryDelegatorWithdrawalAddress(chainEndpoint, delegatorAddress) -// s.Require().NoError(err) -// -// return res.WithdrawAddress == newWithdrawalAddress -// }, -// 10*time.Second, -// 5*time.Second, -// ) -// -// s.execWithdrawReward(s.chainA, 0, delegatorAddress, valOperAddressA, gaiaHomePath) -// s.Require().Eventually( -// func() bool { -// afterBalance, err := getSpecificBalance(chainEndpoint, newWithdrawalAddress, uatomDenom) -// s.Require().NoError(err) -// -// return afterBalance.IsGTE(beforeBalance) -// }, -// 10*time.Second, -// 5*time.Second, -// ) -//} -// -///* -// fundCommunityPool tests the funding of the community pool on behalf of the distribution module. -// Test Benchmarks: -// 1. Validation that balance of the distribution module account before funding -// 2. Execution funding the community pool -// 3. Verification that correct funds have been deposited to distribution module account -// */ -// func (s *IntegrationTestSuite) fundCommunityPool() { -// chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) -// sender := s.chainA.validators[0].keyInfo.GetAddress() -// -// beforeDistUatomBalance, _ := getSpecificBalance(chainAAPIEndpoint, distModuleAddress, tokenAmount.Denom) -// if beforeDistUatomBalance.IsNil() { -// // Set balance to 0 if previous balance does not exist -// beforeDistUatomBalance = sdk.NewInt64Coin(uatomDenom, 0) -// } -// -// s.execDistributionFundCommunityPool(s.chainA, 0, sender.String(), tokenAmount.String(), standardFees.String()) -// -// // there are still tokens being added to the community pool through block production rewards but they should be less than 500 tokens -// marginOfErrorForBlockReward := sdk.NewInt64Coin(uatomDenom, 500) -// -// s.Require().Eventually( -// func() bool { -// afterDistPhotonBalance, err := getSpecificBalance(chainAAPIEndpoint, distModuleAddress, tokenAmount.Denom) -// s.Require().NoErrorf(err, "Error getting balance: %s", afterDistPhotonBalance) -// -// return afterDistPhotonBalance.Sub(beforeDistUatomBalance.Add(tokenAmount.Add(standardFees))).IsLT(marginOfErrorForBlockReward) -// }, -// 15*time.Second, -// 5*time.Second, -// ) -//} +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (s *IntegrationTestSuite) testDistribution() { + chainEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + + validatorB := s.chainA.validators[1] + validatorBAddr, _ := validatorB.keyInfo.GetAddress() + + valOperAddressA := sdk.ValAddress(validatorBAddr).String() + + delegatorAddress, _ := s.chainA.genesisAccounts[2].keyInfo.GetAddress() + + newWithdrawalAddress, _ := s.chainA.genesisAccounts[3].keyInfo.GetAddress() + fees := sdk.NewCoin(uatomDenom, sdk.NewInt(1000)) + + beforeBalance, err := getSpecificBalance(chainEndpoint, newWithdrawalAddress.String(), uatomDenom) + s.Require().NoError(err) + if beforeBalance.IsNil() { + beforeBalance = sdk.NewCoin(uatomDenom, sdk.NewInt(0)) + } + + s.execSetWithdrawAddress(s.chainA, 0, fees.String(), delegatorAddress.String(), newWithdrawalAddress.String(), gaiaHomePath) + + // Verify + s.Require().Eventually( + func() bool { + res, err := queryDelegatorWithdrawalAddress(chainEndpoint, delegatorAddress.String()) + s.Require().NoError(err) + + return res.WithdrawAddress == newWithdrawalAddress.String() + }, + 10*time.Second, + 5*time.Second, + ) + + s.execWithdrawReward(s.chainA, 0, delegatorAddress.String(), valOperAddressA, gaiaHomePath) + s.Require().Eventually( + func() bool { + afterBalance, err := getSpecificBalance(chainEndpoint, newWithdrawalAddress.String(), uatomDenom) + s.Require().NoError(err) + + return afterBalance.IsGTE(beforeBalance) + }, + 10*time.Second, + 5*time.Second, + ) +} + +/* +fundCommunityPool tests the funding of the community pool on behalf of the distribution module. +Test Benchmarks: +1. Validation that balance of the distribution module account before funding +2. Execution funding the community pool +3. Verification that correct funds have been deposited to distribution module account +*/ +func (s *IntegrationTestSuite) fundCommunityPool() { + chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + sender, _ := s.chainA.validators[0].keyInfo.GetAddress() + + beforeDistUatomBalance, _ := getSpecificBalance(chainAAPIEndpoint, distModuleAddress, tokenAmount.Denom) + if beforeDistUatomBalance.IsNil() { + // Set balance to 0 if previous balance does not exist + beforeDistUatomBalance = sdk.NewInt64Coin(uatomDenom, 0) + } + + s.execDistributionFundCommunityPool(s.chainA, 0, sender.String(), tokenAmount.String(), standardFees.String()) + + // there are still tokens being added to the community pool through block production rewards but they should be less than 500 tokens + marginOfErrorForBlockReward := sdk.NewInt64Coin(uatomDenom, 500) + + s.Require().Eventually( + func() bool { + afterDistPhotonBalance, err := getSpecificBalance(chainAAPIEndpoint, distModuleAddress, tokenAmount.Denom) + s.Require().NoErrorf(err, "Error getting balance: %s", afterDistPhotonBalance) + + return afterDistPhotonBalance.Sub(beforeDistUatomBalance.Add(tokenAmount.Add(standardFees))).IsLT(marginOfErrorForBlockReward) + }, + 15*time.Second, + 5*time.Second, + ) +} diff --git a/tests/e2e/e2e_encode_test.go b/tests/e2e/e2e_encode_test.go index 89ac30c97eb..073c6e2a11d 100644 --- a/tests/e2e/e2e_encode_test.go +++ b/tests/e2e/e2e_encode_test.go @@ -1,51 +1,50 @@ package e2e -// -// import ( -// "encoding/base64" -// "path/filepath" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -//) -// -// const ( -// rawTxFile = "tx_raw.json" -//) -// -// func (s *IntegrationTestSuite) testEncode() { -// chain := s.chainA -// _, encoded, err := buildRawTx() -// s.Require().NoError(err) -// -// got := s.execEncode(chain, filepath.Join(gaiaHomePath, rawTxFile)) -// s.T().Logf("encoded tx: %s", got) -// s.Require().Equal(encoded, got) -//} -// -// func (s *IntegrationTestSuite) testDecode() { -// chain := s.chainA -// rawTx, encoded, err := buildRawTx() -// s.Require().NoError(err) -// -// got := s.execDecode(chain, encoded) -// s.T().Logf("raw tx: %s", got) -// s.Require().Equal(string(rawTx), got) -//} -// -//// buildRawTx build a dummy tx using the TxBuilder and -//// return the JSON and encoded tx's -// func buildRawTx() ([]byte, string, error) { -// builder := txConfig.NewTxBuilder() -// builder.SetGasLimit(gas) -// builder.SetFeeAmount(sdk.NewCoins(standardFees)) -// builder.SetMemo("foomemo") -// tx, err := txConfig.TxJSONEncoder()(builder.GetTx()) -// if err != nil { -// return nil, "", err -// } -// txBytes, err := txConfig.TxEncoder()(builder.GetTx()) -// if err != nil { -// return nil, "", err -// } -// return tx, base64.StdEncoding.EncodeToString(txBytes), err -//} +import ( + "encoding/base64" + "path/filepath" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + rawTxFile = "tx_raw.json" +) + +func (s *IntegrationTestSuite) testEncode() { + chain := s.chainA + _, encoded, err := buildRawTx() + s.Require().NoError(err) + + got := s.execEncode(chain, filepath.Join(gaiaHomePath, rawTxFile)) + s.T().Logf("encoded tx: %s", got) + s.Require().Equal(encoded, got) +} + +func (s *IntegrationTestSuite) testDecode() { + chain := s.chainA + rawTx, encoded, err := buildRawTx() + s.Require().NoError(err) + + got := s.execDecode(chain, encoded) + s.T().Logf("raw tx: %s", got) + s.Require().Equal(string(rawTx), got) +} + +// buildRawTx build a dummy tx using the TxBuilder and +// return the JSON and encoded tx's +func buildRawTx() ([]byte, string, error) { + builder := txConfig.NewTxBuilder() + builder.SetGasLimit(gas) + builder.SetFeeAmount(sdk.NewCoins(standardFees)) + builder.SetMemo("foomemo") + tx, err := txConfig.TxJSONEncoder()(builder.GetTx()) + if err != nil { + return nil, "", err + } + txBytes, err := txConfig.TxEncoder()(builder.GetTx()) + if err != nil { + return nil, "", err + } + return tx, base64.StdEncoding.EncodeToString(txBytes), err +} diff --git a/tests/e2e/e2e_evidence_test.go b/tests/e2e/e2e_evidence_test.go index e026c5e5b9e..9f49fc278e4 100644 --- a/tests/e2e/e2e_evidence_test.go +++ b/tests/e2e/e2e_evidence_test.go @@ -1,54 +1,53 @@ package e2e -// -// import ( -// "context" -// "fmt" -// "time" -// -// "github.com/cosmos/cosmos-sdk/x/evidence/exported" -// evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" -//) -// -// func (s *IntegrationTestSuite) testEvidence() { -// s.Run("test evidence queries", func() { -// var ( -// valIdx = 0 -// chain = s.chainA -// chainAPI = fmt.Sprintf("http://%s", s.valResources[chain.id][valIdx].GetHostPort("1317/tcp")) -// ) -// res, err := queryAllEvidence(chainAPI) -// s.Require().NoError(err) -// s.Require().Equal(numberOfEvidences, len(res.Evidence)) -// for _, evidence := range res.Evidence { -// var exportedEvidence exported.Evidence -// err := cdc.UnpackAny(evidence, &exportedEvidence) -// s.Require().NoError(err) -// eq, ok := exportedEvidence.(*evidencetypes.Equivocation) -// s.Require().True(ok) -// s.execQueryEvidence(chain, valIdx, eq.Hash().String()) -// } -// }) -//} -// -// func (s *IntegrationTestSuite) execQueryEvidence(c *chain, valIdx int, hash string) (res evidencetypes.Equivocation) { -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() -// -// s.T().Logf("querying evidence %s on chain %s", hash, c.id) -// -// gaiaCommand := []string{ -// gaiadBinary, -// queryCommand, -// evidencetypes.ModuleName, -// hash, -// } -// -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, func(stdOut []byte, stdErr []byte) bool { -// // TODO parse evidence after fix the SDK -// // https://github.com/cosmos/cosmos-sdk/issues/13444 -// // s.Require().NoError(yaml.Unmarshal(stdOut, &res)) -// return true -// }) -// return res -//} +import ( + "context" + "fmt" + "time" + + "github.com/cosmos/cosmos-sdk/x/evidence/exported" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" +) + +func (s *IntegrationTestSuite) testEvidence() { + s.Run("test evidence queries", func() { + var ( + valIdx = 0 + chain = s.chainA + chainAPI = fmt.Sprintf("http://%s", s.valResources[chain.id][valIdx].GetHostPort("1317/tcp")) + ) + res, err := queryAllEvidence(chainAPI) + s.Require().NoError(err) + s.Require().Equal(numberOfEvidences, len(res.Evidence)) + for _, evidence := range res.Evidence { + var exportedEvidence exported.Evidence + err := cdc.UnpackAny(evidence, &exportedEvidence) + s.Require().NoError(err) + eq, ok := exportedEvidence.(*evidencetypes.Equivocation) + s.Require().True(ok) + s.execQueryEvidence(chain, valIdx, eq.Hash().String()) + } + }) +} + +func (s *IntegrationTestSuite) execQueryEvidence(c *chain, valIdx int, hash string) (res evidencetypes.Equivocation) { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("querying evidence %s on chain %s", hash, c.id) + + gaiaCommand := []string{ + gaiadBinary, + queryCommand, + evidencetypes.ModuleName, + hash, + } + + s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, func(stdOut []byte, stdErr []byte) bool { + // TODO parse evidence after fix the SDK + // https://github.com/cosmos/cosmos-sdk/issues/13444 + // s.Require().NoError(yaml.Unmarshal(stdOut, &res)) + return true + }) + return res +} diff --git a/tests/e2e/e2e_exec_test.go b/tests/e2e/e2e_exec_test.go index 4910753ef00..da499a87023 100644 --- a/tests/e2e/e2e_exec_test.go +++ b/tests/e2e/e2e_exec_test.go @@ -1,283 +1,288 @@ package e2e -// import ( -// "bytes" -// "context" -// "encoding/json" -// "fmt" -// "strconv" -// "strings" -// "time" - -// "github.com/cosmos/cosmos-sdk/client/flags" -// sdk "github.com/cosmos/cosmos-sdk/types" -// vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" -// banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" -// distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" -// "github.com/cosmos/cosmos-sdk/x/feegrant" -// govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" -// slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" -// stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" -// "github.com/ory/dockertest/v3/docker" -// ) - -// const ( -// flagFrom = "from" -// flagHome = "home" -// flagFees = "fees" -// flagGas = "gas" -// flagOutput = "output" -// flagChainID = "chain-id" -// flagSpendLimit = "spend-limit" -// flagGasAdjustment = "gas-adjustment" -// flagFeeAccount = "fee-account" -// flagBroadcastMode = "broadcast-mode" -// flagKeyringBackend = "keyring-backend" -// flagAllowedMessages = "allowed-messages" -// ) - -// type flagOption func(map[string]interface{}) - -// // withKeyValue add a new flag to command -// func withKeyValue(key string, value interface{}) flagOption { -// return func(o map[string]interface{}) { -// o[key] = value -// } -// } - -// func applyOptions(chainID string, options []flagOption) map[string]interface{} { -// opts := map[string]interface{}{ -// flagKeyringBackend: "test", -// flagOutput: "json", -// flagGas: "auto", -// flagFrom: "alice", -// flagBroadcastMode: "sync", -// flagGasAdjustment: "1.5", -// flagChainID: chainID, -// flagHome: gaiaHomePath, -// flagFees: standardFees.String(), -// } -// for _, apply := range options { -// apply(opts) -// } -// return opts -// } - -// func (s *IntegrationTestSuite) execEncode( -// c *chain, -// txPath string, -// opt ...flagOption, -// ) string { -// opts := applyOptions(c.id, opt) -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// s.T().Logf("%s - Executing gaiad encoding with %v", c.id, txPath) -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// "encode", -// txPath, -// } -// for flag, value := range opts { -// gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) -// } - -// var encoded string -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, 0, func(stdOut []byte, stdErr []byte) bool { -// if stdErr != nil { -// return false -// } -// encoded = strings.TrimSuffix(string(stdOut), "\n") -// return true -// }) -// s.T().Logf("successfully encode with %v", txPath) -// return encoded -// } - -// func (s *IntegrationTestSuite) execDecode( -// c *chain, -// txPath string, -// opt ...flagOption, -// ) string { -// opts := applyOptions(c.id, opt) -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// s.T().Logf("%s - Executing gaiad decoding with %v", c.id, txPath) -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// "decode", -// txPath, -// } -// for flag, value := range opts { -// gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) -// } - -// var decoded string -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, 0, func(stdOut []byte, stdErr []byte) bool { -// if stdErr != nil { -// return false -// } -// decoded = strings.TrimSuffix(string(stdOut), "\n") -// return true -// }) -// s.T().Logf("successfully decode %v", txPath) -// return decoded -// } - -// func (s *IntegrationTestSuite) execVestingTx( -// c *chain, -// method string, -// args []string, -// opt ...flagOption, -// ) { -// opts := applyOptions(c.id, opt) -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// s.T().Logf("%s - Executing gaiad %s with %v", c.id, method, args) -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// vestingtypes.ModuleName, -// method, -// "-y", -// } -// gaiaCommand = append(gaiaCommand, args...) - -// for flag, value := range opts { -// gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) -// } - -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, 0, s.defaultExecValidation(c, 0)) -// s.T().Logf("successfully %s with %v", method, args) -// } - -// func (s *IntegrationTestSuite) execCreatePeriodicVestingAccount( -// c *chain, -// address, -// jsonPath string, -// opt ...flagOption, -// ) { -// s.T().Logf("Executing gaiad create periodic vesting account %s", c.id) -// s.execVestingTx(c, "create-periodic-vesting-account", []string{address, jsonPath}, opt...) -// s.T().Logf("successfully created periodic vesting account %s with %s", address, jsonPath) -// } - -// func (s *IntegrationTestSuite) execUnjail( -// c *chain, -// opt ...flagOption, -// ) { -// opts := applyOptions(c.id, opt) -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// s.T().Logf("Executing gaiad slashing unjail %s with options: %v", c.id, opt) -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// slashingtypes.ModuleName, -// "unjail", -// "-y", -// } - -// for flag, value := range opts { -// gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) -// } - -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, 0, s.defaultExecValidation(c, 0)) -// s.T().Logf("successfully unjail with options %v", opt) -// } - -// func (s *IntegrationTestSuite) execFeeGrant(c *chain, valIdx int, granter, grantee, spendLimit string, opt ...flagOption) { -// opt = append(opt, withKeyValue(flagFrom, granter)) -// opt = append(opt, withKeyValue(flagSpendLimit, spendLimit)) -// opts := applyOptions(c.id, opt) - -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// s.T().Logf("granting %s fee from %s on chain %s", grantee, granter, c.id) - -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// feegrant.ModuleName, -// "grant", -// granter, -// grantee, -// "-y", -// } -// for flag, value := range opts { -// gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) -// } - -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) -// } - -// func (s *IntegrationTestSuite) execFeeGrantRevoke(c *chain, valIdx int, granter, grantee string, opt ...flagOption) { -// opt = append(opt, withKeyValue(flagFrom, granter)) -// opts := applyOptions(c.id, opt) - -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// s.T().Logf("revoking %s fee grant from %s on chain %s", grantee, granter, c.id) - -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// feegrant.ModuleName, -// "revoke", -// granter, -// grantee, -// "-y", -// } -// for flag, value := range opts { -// gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) -// } - -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) -// } - -// func (s *IntegrationTestSuite) execBankSend( -// c *chain, -// valIdx int, -// from, -// to, -// amt, -// fees string, -// expectErr bool, -// opt ...flagOption, -// ) { -// // TODO remove the hardcode opt after refactor, all methods should accept custom flags -// opt = append(opt, withKeyValue(flagFees, fees)) -// opt = append(opt, withKeyValue(flagFrom, from)) -// opts := applyOptions(c.id, opt) - -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// s.T().Logf("sending %s tokens from %s to %s on chain %s", amt, from, to, c.id) - -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// banktypes.ModuleName, -// "send", -// from, -// to, -// amt, -// "-y", -// } -// for flag, value := range opts { -// gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) -// } - -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.expectErrExecValidation(c, valIdx, expectErr)) -// } +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "strconv" + "strings" + "time" + + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" + "github.com/cosmos/cosmos-sdk/x/feegrant" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/ory/dockertest/v3/docker" +) + +const ( + flagFrom = "from" + flagHome = "home" + flagFees = "fees" + flagGas = "gas" + flagOutput = "output" + flagChainID = "chain-id" + flagSpendLimit = "spend-limit" + flagGasAdjustment = "gas-adjustment" + flagFeeGranter = "fee-granter" + flagBroadcastMode = "broadcast-mode" + flagKeyringBackend = "keyring-backend" + flagAllowedMessages = "allowed-messages" +) + +type flagOption func(map[string]interface{}) + +// withKeyValue add a new flag to command + +func withKeyValue(key string, value interface{}) flagOption { + return func(o map[string]interface{}) { + o[key] = value + } +} + +func applyOptions(chainID string, options []flagOption) map[string]interface{} { + opts := map[string]interface{}{ + flagKeyringBackend: "test", + flagOutput: "json", + flagGas: "auto", + flagFrom: "alice", + flagBroadcastMode: "sync", + flagGasAdjustment: "1.5", + flagChainID: chainID, + flagHome: gaiaHomePath, + flagFees: standardFees.String(), + } + for _, apply := range options { + apply(opts) + } + return opts +} + +func (s *IntegrationTestSuite) execEncode( + c *chain, + txPath string, + opt ...flagOption, +) string { + opts := applyOptions(c.id, opt) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("%s - Executing gaiad encoding with %v", c.id, txPath) + gaiaCommand := []string{ + gaiadBinary, + txCommand, + "encode", + txPath, + } + for flag, value := range opts { + gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) + } + + var encoded string + s.executeGaiaTxCommand(ctx, c, gaiaCommand, 0, func(stdOut []byte, stdErr []byte) bool { + if stdErr != nil { + return false + } + encoded = strings.TrimSuffix(string(stdOut), "\n") + return true + }) + s.T().Logf("successfully encode with %v", txPath) + return encoded +} + +func (s *IntegrationTestSuite) execDecode( + c *chain, + txPath string, + opt ...flagOption, +) string { + opts := applyOptions(c.id, opt) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("%s - Executing gaiad decoding with %v", c.id, txPath) + gaiaCommand := []string{ + gaiadBinary, + txCommand, + "decode", + txPath, + } + for flag, value := range opts { + gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) + } + + var decoded string + s.executeGaiaTxCommand(ctx, c, gaiaCommand, 0, func(stdOut []byte, stdErr []byte) bool { + if stdErr != nil { + return false + } + decoded = strings.TrimSuffix(string(stdOut), "\n") + return true + }) + s.T().Logf("successfully decode %v", txPath) + return decoded +} + +func (s *IntegrationTestSuite) execVestingTx( //nolint:unused + + c *chain, + method string, + args []string, + opt ...flagOption, +) { + opts := applyOptions(c.id, opt) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("%s - Executing gaiad %s with %v", c.id, method, args) + gaiaCommand := []string{ + gaiadBinary, + txCommand, + vestingtypes.ModuleName, + method, + "-y", + } + gaiaCommand = append(gaiaCommand, args...) + + for flag, value := range opts { + gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) + } + + s.executeGaiaTxCommand(ctx, c, gaiaCommand, 0, s.defaultExecValidation(c, 0)) + s.T().Logf("successfully %s with %v", method, args) +} + +func (s *IntegrationTestSuite) execCreatePeriodicVestingAccount( //nolint:unused + + c *chain, + address, + jsonPath string, + opt ...flagOption, +) { + s.T().Logf("Executing gaiad create periodic vesting account %s", c.id) + s.execVestingTx(c, "create-periodic-vesting-account", []string{address, jsonPath}, opt...) + s.T().Logf("successfully created periodic vesting account %s with %s", address, jsonPath) +} + +func (s *IntegrationTestSuite) execUnjail( + c *chain, + opt ...flagOption, +) { + opts := applyOptions(c.id, opt) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("Executing gaiad slashing unjail %s with options: %v", c.id, opt) + gaiaCommand := []string{ + gaiadBinary, + txCommand, + slashingtypes.ModuleName, + "unjail", + "-y", + } + + for flag, value := range opts { + gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) + } + + s.executeGaiaTxCommand(ctx, c, gaiaCommand, 0, s.defaultExecValidation(c, 0)) + s.T().Logf("successfully unjail with options %v", opt) +} + +func (s *IntegrationTestSuite) execFeeGrant(c *chain, valIdx int, granter, grantee, spendLimit string, opt ...flagOption) { + opt = append(opt, withKeyValue(flagFrom, granter)) + opt = append(opt, withKeyValue(flagSpendLimit, spendLimit)) + opts := applyOptions(c.id, opt) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("granting %s fee from %s on chain %s", grantee, granter, c.id) + + gaiaCommand := []string{ + gaiadBinary, + txCommand, + feegrant.ModuleName, + "grant", + granter, + grantee, + "-y", + } + for flag, value := range opts { + gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) + } + + s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) +} + +func (s *IntegrationTestSuite) execFeeGrantRevoke(c *chain, valIdx int, granter, grantee string, opt ...flagOption) { + opt = append(opt, withKeyValue(flagFrom, granter)) + opts := applyOptions(c.id, opt) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("revoking %s fee grant from %s on chain %s", grantee, granter, c.id) + + gaiaCommand := []string{ + gaiadBinary, + txCommand, + feegrant.ModuleName, + "revoke", + granter, + grantee, + "-y", + } + for flag, value := range opts { + gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) + } + + s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) +} + +func (s *IntegrationTestSuite) execBankSend( + c *chain, + valIdx int, + from, + to, + amt, + fees string, + expectErr bool, + opt ...flagOption, +) { + // TODO remove the hardcode opt after refactor, all methods should accept custom flags + opt = append(opt, withKeyValue(flagFees, fees)) + opt = append(opt, withKeyValue(flagFrom, from)) + opts := applyOptions(c.id, opt) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("sending %s tokens from %s to %s on chain %s", amt, from, to, c.id) + + gaiaCommand := []string{ + gaiadBinary, + txCommand, + banktypes.ModuleName, + "send", + from, + to, + amt, + "-y", + } + for flag, value := range opts { + gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) + } + + s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.expectErrExecValidation(c, valIdx, expectErr)) +} // type txBankSend struct { // from string @@ -289,97 +294,98 @@ package e2e // } // func (s *IntegrationTestSuite) execBankSendBatch( -// c *chain, -// valIdx int, //nolint:unparam -// txs ...txBankSend, -// ) int { -// sucessBankSendCount := 0 - -// for i := range txs { -// s.T().Logf(txs[i].log) - -// s.execBankSend(c, valIdx, txs[i].from, txs[i].to, txs[i].amt, txs[i].fees, txs[i].expectErr) -// if !txs[i].expectErr { -// if !txs[i].expectErr { -// sucessBankSendCount++ -// } -// } -// } - -// return sucessBankSendCount -// } - -// func (s *IntegrationTestSuite) execWithdrawAllRewards(c *chain, valIdx int, payee, fees string, expectErr bool) { -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// distributiontypes.ModuleName, -// "withdraw-all-rewards", -// fmt.Sprintf("--%s=%s", flags.FlagFrom, payee), -// fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), -// fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), -// "--keyring-backend=test", -// "--output=json", -// "-y", -// } - -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.expectErrExecValidation(c, valIdx, expectErr)) -// } - -// func (s *IntegrationTestSuite) execDistributionFundCommunityPool(c *chain, valIdx int, from, amt, fees string) { -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// s.T().Logf("Executing gaiad tx distribution fund-community-pool on chain %s", c.id) - -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// distributiontypes.ModuleName, -// "fund-community-pool", -// amt, -// fmt.Sprintf("--%s=%s", flags.FlagFrom, from), -// fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), -// fmt.Sprintf("--%s=%s", flags.FlagFees, fees), -// "--keyring-backend=test", -// "--output=json", -// "-y", -// } - -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) -// s.T().Logf("Successfully funded community pool") -// } - -// func (s *IntegrationTestSuite) runGovExec(c *chain, valIdx int, submitterAddr, govCommand string, proposalFlags []string, fees string) { -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// govtypes.ModuleName, -// govCommand, -// } - -// generalFlags := []string{ -// fmt.Sprintf("--%s=%s", flags.FlagFrom, submitterAddr), -// fmt.Sprintf("--%s=%s", flags.FlagGas, "300000"), // default 200000 isn't enough -// fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), -// fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), -// "--keyring-backend=test", -// "--output=json", -// "-y", -// } - -// gaiaCommand = concatFlags(gaiaCommand, proposalFlags, generalFlags) - -// s.T().Logf("Executing gaiad tx gov %s on chain %s", govCommand, c.id) -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) -// s.T().Logf("Successfully executed %s", govCommand) -// } +// +// c *chain, +// valIdx int, //nolint:unparam +// txs ...txBankSend, +// +// ) int { +// sucessBankSendCount := 0 +// +// for i := range txs { +// s.T().Logf(txs[i].log) +// +// s.execBankSend(c, valIdx, txs[i].from, txs[i].to, txs[i].amt, txs[i].fees, txs[i].expectErr) +// if !txs[i].expectErr { +// if !txs[i].expectErr { +// sucessBankSendCount++ +// } +// } +// } +// +// return sucessBankSendCount +// } +// +// func (s *IntegrationTestSuite) execWithdrawAllRewards(c *chain, valIdx int, payee, fees string, expectErr bool) { +// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) +// defer cancel() +// +// gaiaCommand := []string{ +// gaiadBinary, +// txCommand, +// distributiontypes.ModuleName, +// "withdraw-all-rewards", +// fmt.Sprintf("--%s=%s", flags.FlagFrom, payee), +// fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), +// fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), +// "--keyring-backend=test", +// "--output=json", +// "-y", +// } +// +// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.expectErrExecValidation(c, valIdx, expectErr)) +// } +func (s *IntegrationTestSuite) execDistributionFundCommunityPool(c *chain, valIdx int, from, amt, fees string) { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("Executing gaiad tx distribution fund-community-pool on chain %s", c.id) + + gaiaCommand := []string{ + gaiadBinary, + txCommand, + distributiontypes.ModuleName, + "fund-community-pool", + amt, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), + fmt.Sprintf("--%s=%s", flags.FlagFees, fees), + "--keyring-backend=test", + "--output=json", + "-y", + } + + s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) + s.T().Logf("Successfully funded community pool") +} + +func (s *IntegrationTestSuite) runGovExec(c *chain, valIdx int, submitterAddr, govCommand string, proposalFlags []string, fees string) { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + gaiaCommand := []string{ + gaiadBinary, + txCommand, + govtypes.ModuleName, + govCommand, + } + + generalFlags := []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, submitterAddr), + fmt.Sprintf("--%s=%s", flags.FlagGas, "300000"), // default 200000 isn't enough + fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), + fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), + "--keyring-backend=test", + "--output=json", + "-y", + } + + gaiaCommand = concatFlags(gaiaCommand, proposalFlags, generalFlags) + + s.T().Logf("Executing gaiad tx gov %s on chain %s", govCommand, c.id) + s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) + s.T().Logf("Successfully executed %s", govCommand) +} // func (s *IntegrationTestSuite) executeGKeysAddCommand(c *chain, valIdx int, name string, home string) string { // ctx, cancel := context.WithTimeout(context.Background(), time.Minute) @@ -424,86 +430,88 @@ package e2e // }) // } -// func (s *IntegrationTestSuite) executeDelegate(c *chain, valIdx int, amount, valOperAddress, delegatorAddr, home, delegateFees string) { //nolint:unparam -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// s.T().Logf("Executing gaiad tx staking delegate %s", c.id) - -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// stakingtypes.ModuleName, -// "delegate", -// valOperAddress, -// amount, -// fmt.Sprintf("--%s=%s", flags.FlagFrom, delegatorAddr), -// fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), -// fmt.Sprintf("--%s=%s", flags.FlagGasPrices, delegateFees), -// "--keyring-backend=test", -// fmt.Sprintf("--%s=%s", flags.FlagHome, home), -// "--output=json", -// "-y", -// } - -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) -// s.T().Logf("%s successfully delegated %s to %s", delegatorAddr, amount, valOperAddress) -// } - -// func (s *IntegrationTestSuite) executeRedelegate(c *chain, valIdx int, amount, originalValOperAddress, -// newValOperAddress, delegatorAddr, home, delegateFees string, -// ) { -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// s.T().Logf("Executing gaiad tx staking redelegate %s", c.id) - -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// stakingtypes.ModuleName, -// "redelegate", -// originalValOperAddress, -// newValOperAddress, -// amount, -// fmt.Sprintf("--%s=%s", flags.FlagFrom, delegatorAddr), -// fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), -// fmt.Sprintf("--%s=%s", flags.FlagGas, "300000"), // default 200000 isn't enough -// fmt.Sprintf("--%s=%s", flags.FlagGasPrices, delegateFees), -// "--keyring-backend=test", -// fmt.Sprintf("--%s=%s", flags.FlagHome, home), -// "--output=json", -// "-y", -// } - -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) -// s.T().Logf("%s successfully redelegated %s from %s to %s", delegatorAddr, amount, originalValOperAddress, newValOperAddress) -// } - -// func (s *IntegrationTestSuite) getLatestBlockHeight(c *chain, valIdx int) int { -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// type syncInfo struct { -// SyncInfo struct { -// LatestHeight string `json:"latest_block_height"` -// } `json:"SyncInfo"` -// } - -// var currentHeight int -// gaiaCommand := []string{gaiadBinary, "status"} -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, func(stdOut []byte, stdErr []byte) bool { -// var ( -// err error -// block syncInfo -// ) -// s.Require().NoError(json.Unmarshal(stdErr, &block)) -// currentHeight, err = strconv.Atoi(block.SyncInfo.LatestHeight) -// s.Require().NoError(err) -// return currentHeight > 0 -// }) -// return currentHeight -// } +func (s *IntegrationTestSuite) executeDelegate(c *chain, valIdx int, amount, valOperAddress, delegatorAddr, home, delegateFees string) { //nolint:unparam + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("Executing gaiad tx staking delegate %s", c.id) + + gaiaCommand := []string{ + gaiadBinary, + txCommand, + stakingtypes.ModuleName, + "delegate", + valOperAddress, + amount, + fmt.Sprintf("--%s=%s", flags.FlagFrom, delegatorAddr), + fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), + fmt.Sprintf("--%s=%s", flags.FlagGasPrices, delegateFees), + "--keyring-backend=test", + fmt.Sprintf("--%s=%s", flags.FlagHome, home), + "--output=json", + "-y", + } + + s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) + s.T().Logf("%s successfully delegated %s to %s", delegatorAddr, amount, valOperAddress) +} + +func (s *IntegrationTestSuite) executeRedelegate(c *chain, valIdx int, amount, originalValOperAddress, + + newValOperAddress, delegatorAddr, home, delegateFees string, +) { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("Executing gaiad tx staking redelegate %s", c.id) + + gaiaCommand := []string{ + gaiadBinary, + txCommand, + stakingtypes.ModuleName, + "redelegate", + originalValOperAddress, + newValOperAddress, + amount, + fmt.Sprintf("--%s=%s", flags.FlagFrom, delegatorAddr), + fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), + fmt.Sprintf("--%s=%s", flags.FlagGas, "300000"), // default 200000 isn't enough + fmt.Sprintf("--%s=%s", flags.FlagGasPrices, delegateFees), + "--keyring-backend=test", + fmt.Sprintf("--%s=%s", flags.FlagHome, home), + "--output=json", + "-y", + } + + s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) + s.T().Logf("%s successfully redelegated %s from %s to %s", delegatorAddr, amount, originalValOperAddress, newValOperAddress) +} + +func (s *IntegrationTestSuite) getLatestBlockHeight(c *chain, valIdx int) int { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + type syncInfo struct { + SyncInfo struct { + LatestHeight string `json:"latest_block_height"` + } `json:"SyncInfo"` + } + + var currentHeight int + gaiaCommand := []string{gaiadBinary, "status"} + s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, func(stdOut []byte, stdErr []byte) bool { + var ( + err error + block syncInfo + ) + s.Require().NoError(json.Unmarshal(stdOut, &block)) + currentHeight, err = strconv.Atoi(block.SyncInfo.LatestHeight) + s.Require().NoError(err) + return currentHeight > 0 + }) + return currentHeight +} // func (s *IntegrationTestSuite) verifyBalanceChange(endpoint string, expectedAmount sdk.Coin, recipientAddress string) { // s.Require().Eventually( @@ -518,176 +526,147 @@ package e2e // ) // } -// func (s *IntegrationTestSuite) execSetWithdrawAddress( -// c *chain, -// valIdx int, -// fees, -// delegatorAddress, -// newWithdrawalAddress, -// homePath string, -// ) { -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// s.T().Logf("Setting distribution withdrawal address on chain %s for %s to %s", c.id, delegatorAddress, newWithdrawalAddress) -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// distributiontypes.ModuleName, -// "set-withdraw-addr", -// newWithdrawalAddress, -// fmt.Sprintf("--%s=%s", flags.FlagFrom, delegatorAddress), -// fmt.Sprintf("--%s=%s", flags.FlagFees, fees), -// fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), -// fmt.Sprintf("--%s=%s", flags.FlagHome, homePath), -// "--keyring-backend=test", -// "--output=json", -// "-y", -// } - -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) -// s.T().Logf("Successfully set new distribution withdrawal address for %s to %s", delegatorAddress, newWithdrawalAddress) -// } - -// func (s *IntegrationTestSuite) execWithdrawReward( -// c *chain, -// valIdx int, -// delegatorAddress, -// validatorAddress, -// homePath string, -// ) { -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// s.T().Logf("Withdrawing distribution rewards on chain %s for delegator %s from %s validator", c.id, delegatorAddress, validatorAddress) -// gaiaCommand := []string{ -// gaiadBinary, -// txCommand, -// distributiontypes.ModuleName, -// "withdraw-rewards", -// validatorAddress, -// fmt.Sprintf("--%s=%s", flags.FlagFrom, delegatorAddress), -// fmt.Sprintf("--%s=%s", flags.FlagGasPrices, "300uatom"), -// fmt.Sprintf("--%s=%s", flags.FlagGas, "auto"), -// fmt.Sprintf("--%s=%s", flags.FlagGasAdjustment, "1.5"), -// fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), -// fmt.Sprintf("--%s=%s", flags.FlagHome, homePath), -// "--keyring-backend=test", -// "--output=json", -// "-y", -// } - -// s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) -// s.T().Logf("Successfully withdrew distribution rewards for delegator %s from validator %s", delegatorAddress, validatorAddress) -// } - -// func (s *IntegrationTestSuite) executeGaiaTxCommand(ctx context.Context, c *chain, gaiaCommand []string, valIdx int, validation func([]byte, []byte) bool) { -// if validation == nil { -// validation = s.defaultExecValidation(s.chainA, 0) -// } -// var ( -// outBuf bytes.Buffer -// errBuf bytes.Buffer -// ) -// exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ -// Context: ctx, -// AttachStdout: true, -// AttachStderr: true, -// Container: s.valResources[c.id][valIdx].Container.ID, -// User: "nonroot", -// Cmd: gaiaCommand, -// }) -// s.Require().NoError(err) - -// err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ -// Context: ctx, -// Detach: false, -// OutputStream: &outBuf, -// ErrorStream: &errBuf, -// }) -// s.Require().NoError(err) - -// stdOut := outBuf.Bytes() -// stdErr := errBuf.Bytes() - -// if !validation(stdOut, stdErr) { -// s.Require().FailNowf("Exec validation failed", "stdout: %s, stderr: %s", -// string(stdOut), string(stdErr)) -// } -// } - -// func (s *IntegrationTestSuite) executeHermesCommand(ctx context.Context, hermesCmd []string) ([]byte, []byte) { -// var ( -// outBuf bytes.Buffer -// errBuf bytes.Buffer -// ) -// exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ -// Context: ctx, -// AttachStdout: true, -// AttachStderr: true, -// Container: s.hermesResource1.Container.ID, -// User: "root", -// Cmd: hermesCmd, -// }) -// s.Require().NoError(err) - -// err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ -// Context: ctx, -// Detach: false, -// OutputStream: &outBuf, -// ErrorStream: &errBuf, -// }) -// s.Require().NoError(err) - -// stdOut := outBuf.Bytes() -// stdErr := errBuf.Bytes() - -// return stdOut, stdErr -// } - -// func (s *IntegrationTestSuite) expectErrExecValidation(chain *chain, valIdx int, expectErr bool) func([]byte, []byte) bool { -// return func(stdOut []byte, stdErr []byte) bool { -// var txResp sdk.TxResponse -// gotErr := cdc.UnmarshalJSON(stdOut, &txResp) != nil -// if gotErr { -// s.Require().True(expectErr) -// } - -// endpoint := fmt.Sprintf("http://%s", s.valResources[chain.id][valIdx].GetHostPort("1317/tcp")) -// // wait for the tx to be committed on chain -// s.Require().Eventuallyf( -// func() bool { -// gotErr := queryGaiaTx(endpoint, txResp.TxHash) != nil -// return gotErr == expectErr -// }, -// time.Minute, -// 5*time.Second, -// "stdOut: %s, stdErr: %s", -// string(stdOut), string(stdErr), -// ) -// return true -// } -// } - -// func (s *IntegrationTestSuite) defaultExecValidation(chain *chain, valIdx int) func([]byte, []byte) bool { -// return func(stdOut []byte, stdErr []byte) bool { -// var txResp sdk.TxResponse -// if err := cdc.UnmarshalJSON(stdOut, &txResp); err != nil { -// return false -// } -// if strings.Contains(txResp.String(), "code: 0") || txResp.Code == 0 { -// endpoint := fmt.Sprintf("http://%s", s.valResources[chain.id][valIdx].GetHostPort("1317/tcp")) -// s.Require().Eventually( -// func() bool { -// return queryGaiaTx(endpoint, txResp.TxHash) == nil -// }, -// time.Minute, -// 5*time.Second, -// "stdOut: %s, stdErr: %s", -// string(stdOut), string(stdErr), -// ) -// return true -// } -// return false -// } -// } +func (s *IntegrationTestSuite) execSetWithdrawAddress( + c *chain, + valIdx int, + fees, + delegatorAddress, + newWithdrawalAddress, + homePath string, +) { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("Setting distribution withdrawal address on chain %s for %s to %s", c.id, delegatorAddress, newWithdrawalAddress) + gaiaCommand := []string{ + gaiadBinary, + txCommand, + distributiontypes.ModuleName, + "set-withdraw-addr", + newWithdrawalAddress, + fmt.Sprintf("--%s=%s", flags.FlagFrom, delegatorAddress), + fmt.Sprintf("--%s=%s", flags.FlagFees, fees), + fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), + fmt.Sprintf("--%s=%s", flags.FlagHome, homePath), + "--keyring-backend=test", + "--output=json", + "-y", + } + + s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) + s.T().Logf("Successfully set new distribution withdrawal address for %s to %s", delegatorAddress, newWithdrawalAddress) +} + +func (s *IntegrationTestSuite) execWithdrawReward( + c *chain, + valIdx int, + delegatorAddress, + validatorAddress, + homePath string, +) { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.T().Logf("Withdrawing distribution rewards on chain %s for delegator %s from %s validator", c.id, delegatorAddress, validatorAddress) + gaiaCommand := []string{ + gaiadBinary, + txCommand, + distributiontypes.ModuleName, + "withdraw-rewards", + validatorAddress, + fmt.Sprintf("--%s=%s", flags.FlagFrom, delegatorAddress), + fmt.Sprintf("--%s=%s", flags.FlagGasPrices, "300uatom"), + fmt.Sprintf("--%s=%s", flags.FlagGas, "auto"), + fmt.Sprintf("--%s=%s", flags.FlagGasAdjustment, "1.5"), + fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), + fmt.Sprintf("--%s=%s", flags.FlagHome, homePath), + "--keyring-backend=test", + "--output=json", + "-y", + } + + s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx)) + s.T().Logf("Successfully withdrew distribution rewards for delegator %s from validator %s", delegatorAddress, validatorAddress) +} + +func (s *IntegrationTestSuite) executeGaiaTxCommand(ctx context.Context, c *chain, gaiaCommand []string, valIdx int, validation func([]byte, []byte) bool) { + if validation == nil { + validation = s.defaultExecValidation(s.chainA, 0) + } + var ( + outBuf bytes.Buffer + errBuf bytes.Buffer + ) + exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ + Context: ctx, + AttachStdout: true, + AttachStderr: true, + Container: s.valResources[c.id][valIdx].Container.ID, + User: "nonroot", + Cmd: gaiaCommand, + }) + s.Require().NoError(err) + + err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ + Context: ctx, + Detach: false, + OutputStream: &outBuf, + ErrorStream: &errBuf, + }) + s.Require().NoError(err) + + stdOut := outBuf.Bytes() + stdErr := errBuf.Bytes() + + if !validation(stdOut, stdErr) { + s.Require().FailNowf("Exec validation failed", "stdout: %s, stderr: %s", + string(stdOut), string(stdErr)) + } +} + +func (s *IntegrationTestSuite) expectErrExecValidation(chain *chain, valIdx int, expectErr bool) func([]byte, []byte) bool { + return func(stdOut []byte, stdErr []byte) bool { + var txResp sdk.TxResponse + gotErr := cdc.UnmarshalJSON(stdOut, &txResp) != nil + if gotErr { + s.Require().True(expectErr) + } + + endpoint := fmt.Sprintf("http://%s", s.valResources[chain.id][valIdx].GetHostPort("1317/tcp")) + // wait for the tx to be committed on chain + s.Require().Eventuallyf( + func() bool { + gotErr := queryGaiaTx(endpoint, txResp.TxHash) != nil + return gotErr == expectErr + }, + time.Minute, + 5*time.Second, + "stdOut: %s, stdErr: %s", + string(stdOut), string(stdErr), + ) + return true + } +} + +func (s *IntegrationTestSuite) defaultExecValidation(chain *chain, valIdx int) func([]byte, []byte) bool { + return func(stdOut []byte, stdErr []byte) bool { + var txResp sdk.TxResponse + if err := cdc.UnmarshalJSON(stdOut, &txResp); err != nil { + return false + } + if strings.Contains(txResp.String(), "code: 0") || txResp.Code == 0 { + endpoint := fmt.Sprintf("http://%s", s.valResources[chain.id][valIdx].GetHostPort("1317/tcp")) + s.Require().Eventually( + func() bool { + return queryGaiaTx(endpoint, txResp.TxHash) == nil + }, + time.Minute, + 5*time.Second, + "stdOut: %s, stdErr: %s", + string(stdOut), string(stdErr), + ) + return true + } + return false + } +} diff --git a/tests/e2e/e2e_feegrant_test.go b/tests/e2e/e2e_feegrant_test.go index 36750715b2f..316cc4e5624 100644 --- a/tests/e2e/e2e_feegrant_test.go +++ b/tests/e2e/e2e_feegrant_test.go @@ -1,14 +1,13 @@ package e2e -// -// import ( -// "fmt" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -// banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" -//) -// -///* +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +// /* // TestFeeGrant creates a test to ensure that Alice can grant the fees for bob. // Test Benchmarks: // 1. Execute fee grant CLI command for Alice to pay bob fees @@ -16,90 +15,91 @@ package e2e // 3. Check the bob balances if the fee was not deducted // 4. Try to send a transaction from bob with Alice as a fee granter again. Should fail // because all amount granted was expended -// */ -// func (s *IntegrationTestSuite) testFeeGrant() { -// s.Run("test fee grant module", func() { -// var ( -// valIdx = 0 -// c = s.chainA -// api = fmt.Sprintf("http://%s", s.valResources[c.id][valIdx].GetHostPort("1317/tcp")) -// ) -// -// alice := c.genesisAccounts[1].keyInfo.GetAddress() -// bob := c.genesisAccounts[2].keyInfo.GetAddress() -// charlie := c.genesisAccounts[3].keyInfo.GetAddress() -// -// // add fee grant from alice to bob -// s.execFeeGrant( -// c, -// valIdx, -// alice.String(), -// bob.String(), -// standardFees.String(), -// withKeyValue(flagAllowedMessages, sdk.MsgTypeURL(&banktypes.MsgSend{})), -// ) -// -// bobBalance, err := getSpecificBalance(api, bob.String(), uatomDenom) -// s.Require().NoError(err) -// -// // withdrawal all balance + fee + fee granter flag should succeed -// s.execBankSend( -// c, -// valIdx, -// bob.String(), -// Address(), -// tokenAmount.String(), -// standardFees.String(), -// false, -// withKeyValue(flagFeeAccount, alice.String()), -// ) -// -// // check if the bob balance was subtracted without the fees -// expectedBobBalance := bobBalance.Sub(tokenAmount) -// bobBalance, err = getSpecificBalance(api, bob.String(), uatomDenom) -// s.Require().NoError(err) -// s.Require().Equal(expectedBobBalance, bobBalance) -// -// // tx should fail after spend limit reach -// s.execBankSend( -// c, -// valIdx, -// bob.String(), -// Address(), -// tokenAmount.String(), -// standardFees.String(), -// true, -// withKeyValue(flagFeeAccount, alice.String()), -// ) // -// // add fee grant from alice to charlie -// s.execFeeGrant( -// c, -// valIdx, -// alice.String(), -// charlie.String(), -// standardFees.String(), // spend limit -// withKeyValue(flagAllowedMessages, sdk.MsgTypeURL(&banktypes.MsgSend{})), -// ) -// -// // revoke fee grant from alice to charlie -// s.execFeeGrantRevoke( -// c, -// valIdx, -// alice.String(), -// charlie.String(), -// ) -// -// // tx should fail because the grant was revoked -// s.execBankSend( -// c, -// valIdx, -// charlie.String(), -// Address(), -// tokenAmount.String(), -// standardFees.String(), -// true, -// withKeyValue(flagFeeAccount, alice.String()), -// ) -// }) -//} +// */ +func (s *IntegrationTestSuite) testFeeGrant() { + s.Run("test fee grant module", func() { + var ( + valIdx = 0 + c = s.chainA + api = fmt.Sprintf("http://%s", s.valResources[c.id][valIdx].GetHostPort("1317/tcp")) + ) + + alice, _ := c.genesisAccounts[1].keyInfo.GetAddress() + bob, _ := c.genesisAccounts[2].keyInfo.GetAddress() + charlie, _ := c.genesisAccounts[3].keyInfo.GetAddress() + + // add fee grant from alice to bob + s.execFeeGrant( + c, + valIdx, + alice.String(), + bob.String(), + standardFees.String(), + withKeyValue(flagAllowedMessages, sdk.MsgTypeURL(&banktypes.MsgSend{})), + ) + + bobBalance, err := getSpecificBalance(api, bob.String(), uatomDenom) + s.Require().NoError(err) + + // withdrawal all balance + fee + fee granter flag should succeed + s.execBankSend( + c, + valIdx, + bob.String(), + Address(), + tokenAmount.String(), + standardFees.String(), + false, + withKeyValue(flagFeeGranter, alice.String()), + ) + + // check if the bob balance was subtracted without the fees + expectedBobBalance := bobBalance.Sub(tokenAmount) + bobBalance, err = getSpecificBalance(api, bob.String(), uatomDenom) + s.Require().NoError(err) + s.Require().Equal(expectedBobBalance, bobBalance) + + // tx should fail after spend limit reach + s.execBankSend( + c, + valIdx, + bob.String(), + Address(), + tokenAmount.String(), + standardFees.String(), + true, + withKeyValue(flagFeeGranter, alice.String()), + ) + + // add fee grant from alice to charlie + s.execFeeGrant( + c, + valIdx, + alice.String(), + charlie.String(), + standardFees.String(), // spend limit + withKeyValue(flagAllowedMessages, sdk.MsgTypeURL(&banktypes.MsgSend{})), + ) + + // revoke fee grant from alice to charlie + s.execFeeGrantRevoke( + c, + valIdx, + alice.String(), + charlie.String(), + ) + + // tx should fail because the grant was revoked + s.execBankSend( + c, + valIdx, + charlie.String(), + Address(), + tokenAmount.String(), + standardFees.String(), + true, + withKeyValue(flagFeeGranter, alice.String()), + ) + }) +} diff --git a/tests/e2e/e2e_gov_test.go b/tests/e2e/e2e_gov_test.go index ffbfab5014a..2e7a6684814 100644 --- a/tests/e2e/e2e_gov_test.go +++ b/tests/e2e/e2e_gov_test.go @@ -1,144 +1,164 @@ package e2e -// import ( -// "fmt" -// "strconv" -// "strings" -// "time" - -// ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" - -// sdk "github.com/cosmos/cosmos-sdk/types" - -// distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" -// govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" -// upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" -// ) - -// /* -// GovSoftwareUpgrade tests passing a gov proposal to upgrade the chain at a given height. -// Test Benchmarks: -// 1. Submission, deposit and vote of message based proposal to upgrade the chain at a height (current height + buffer) -// 2. Validation that chain halted at upgrade height -// 3. Teardown & restart chains -// 4. Reset proposalCounter so subsequent tests have the correct last effective proposal id for chainA -// TODO: Perform upgrade in place of chain restart -// */ -// func (s *IntegrationTestSuite) GovSoftwareUpgrade() { -// chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) -// senderAddress := s.chainA.validators[0].keyInfo.GetAddress() -// sender := senderAddress.String() -// height := s.getLatestBlockHeight(s.chainA, 0) -// proposalHeight := height + govProposalBlockBuffer -// // Gov tests may be run in arbitrary order, each test must increment proposalCounter to have the correct proposal id to submit and query -// proposalCounter++ -// submitGovFlags := []string{"software-upgrade", "Upgrade-0", "--title='Upgrade V1'", "--description='Software Upgrade'", fmt.Sprintf("--upgrade-height=%d", proposalHeight)} -// depositGovFlags := []string{strconv.Itoa(proposalCounter), depositAmount.String()} -// voteGovFlags := []string{strconv.Itoa(proposalCounter), "yes=0.8,no=0.1,abstain=0.05,no_with_veto=0.05"} -// s.runGovProcess(chainAAPIEndpoint, sender, proposalCounter, upgradetypes.ProposalTypeSoftwareUpgrade, submitGovFlags, depositGovFlags, voteGovFlags, "weighted-vote", true) - -// s.verifyChainHaltedAtUpgradeHeight(s.chainA, 0, proposalHeight) -// s.T().Logf("Successfully halted chain at height %d", proposalHeight) - -// s.TearDownSuite() - -// s.T().Logf("Restarting containers") -// s.SetupSuite() - -// s.Require().Eventually( -// func() bool { -// h := s.getLatestBlockHeight(s.chainA, 0) -// return h > 0 -// }, -// 30*time.Second, -// 5*time.Second, -// ) - -// proposalCounter = 0 -// } - -// /* -// GovCancelSoftwareUpgrade tests passing a gov proposal that cancels a pending upgrade. -// Test Benchmarks: -// 1. Submission, deposit and vote of message based proposal to upgrade the chain at a height (current height + buffer) -// 2. Submission, deposit and vote of message based proposal to cancel the pending upgrade -// 3. Validation that the chain produced blocks past the intended upgrade height -// */ -// func (s *IntegrationTestSuite) GovCancelSoftwareUpgrade() { -// chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) -// senderAddress := s.chainA.validators[0].keyInfo.GetAddress() - -// sender := senderAddress.String() -// height := s.getLatestBlockHeight(s.chainA, 0) -// proposalHeight := height + 50 -// // Gov tests may be run in arbitrary order, each test must increment proposalCounter to have the correct proposal id to submit and query -// proposalCounter++ -// submitGovFlags := []string{"software-upgrade", "Upgrade-1", "--title='Upgrade V1'", "--description='Software Upgrade'", fmt.Sprintf("--upgrade-height=%d", proposalHeight)} -// depositGovFlags := []string{strconv.Itoa(proposalCounter), depositAmount.String()} -// voteGovFlags := []string{strconv.Itoa(proposalCounter), "yes"} -// s.runGovProcess(chainAAPIEndpoint, sender, proposalCounter, upgradetypes.ProposalTypeSoftwareUpgrade, submitGovFlags, depositGovFlags, voteGovFlags, "vote", true) - -// proposalCounter++ -// submitGovFlags = []string{"cancel-software-upgrade", "--title='Upgrade V1'", "--description='Software Upgrade'"} -// depositGovFlags = []string{strconv.Itoa(proposalCounter), depositAmount.String()} -// voteGovFlags = []string{strconv.Itoa(proposalCounter), "yes"} -// s.runGovProcess(chainAAPIEndpoint, sender, proposalCounter, upgradetypes.ProposalTypeCancelSoftwareUpgrade, submitGovFlags, depositGovFlags, voteGovFlags, "vote", true) - -// s.verifyChainPassesUpgradeHeight(s.chainA, 0, proposalHeight) -// s.T().Logf("Successfully canceled upgrade at height %d", proposalHeight) -// } - -// /* -// GovCommunityPoolSpend tests passing a community spend proposal. -// Test Benchmarks: -// 1. Fund Community Pool -// 2. Submission, deposit and vote of proposal to spend from the community pool to send atoms to a recipient -// 3. Validation that the recipient balance has increased by proposal amount -// */ -// func (s *IntegrationTestSuite) GovCommunityPoolSpend() { -// s.fundCommunityPool() -// chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) -// senderAddress := s.chainA.validators[0].keyInfo.GetAddress() -// sender := senderAddress.String() -// recipientAddress := s.chainA.validators[1].keyInfo.GetAddress() -// recipient := recipientAddress.String() -// sendAmount := sdk.NewCoin(uatomDenom, sdk.NewInt(10000000)) // 10uatom -// s.writeGovCommunitySpendProposal(s.chainA, sendAmount.String(), recipient) - -// beforeRecipientBalance, err := getSpecificBalance(chainAAPIEndpoint, recipient, uatomDenom) -// s.Require().NoError(err) - -// // Gov tests may be run in arbitrary order, each test must increment proposalCounter to have the correct proposal id to submit and query -// proposalCounter++ -// submitGovFlags := []string{"community-pool-spend", configFile(proposalCommunitySpendFilename)} -// depositGovFlags := []string{strconv.Itoa(proposalCounter), depositAmount.String()} -// voteGovFlags := []string{strconv.Itoa(proposalCounter), "yes"} -// s.runGovProcess(chainAAPIEndpoint, sender, proposalCounter, distrtypes.ProposalTypeCommunityPoolSpend, submitGovFlags, depositGovFlags, voteGovFlags, "vote", false) - -// s.Require().Eventually( -// func() bool { -// afterRecipientBalance, err := getSpecificBalance(chainAAPIEndpoint, recipient, uatomDenom) -// s.Require().NoError(err) - -// return afterRecipientBalance.Sub(sendAmount).IsEqual(beforeRecipientBalance) -// }, -// 10*time.Second, -// 5*time.Second, -// ) -// } - -// /* -// AddRemoveConsumerChain tests adding and subsequently removing a new consumer chain to Gaia. -// Test Benchmarks: -// 1. Submit and pass proposal to add consumer chain -// 2. Validation that consumer chain was added -// 3. Submit and pass proposal to remove consumer chain -// 4. Validation that consumer chain was removed -// */ +import ( + "fmt" + "strconv" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + + govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" +) + +/* +GovSoftwareUpgrade tests passing a gov proposal to upgrade the chain at a given height. +Test Benchmarks: +1. Submission, deposit and vote of message based proposal to upgrade the chain at a height (current height + buffer) +2. Validation that chain halted at upgrade height +3. Teardown & restart chains +4. Reset proposalCounter so subsequent tests have the correct last effective proposal id for chainA +TODO: Perform upgrade in place of chain restart +*/ +func (s *IntegrationTestSuite) GovSoftwareUpgrade() { + chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + senderAddress, _ := s.chainA.validators[0].keyInfo.GetAddress() + sender := senderAddress.String() + height := s.getLatestBlockHeight(s.chainA, 0) + proposalHeight := height + govProposalBlockBuffer + // Gov tests may be run in arbitrary order, each test must increment proposalCounter to have the correct proposal id to submit and query + proposalCounter++ + + s.writeGovLegProposal(s.chainA, int64(height), "upgrade-v0") + + submitGovFlags := []string{ + "software-upgrade", + "Upgrade-0", + "--title='Upgrade V0'", + "--description='Software Upgrade'", + "--no-validate", + fmt.Sprintf("--upgrade-height=%d", proposalHeight), + fmt.Sprintf("--upgrade-info=%s", configFile(proposalCommunitySpendFilename)), + } + + depositGovFlags := []string{strconv.Itoa(proposalCounter), depositAmount.String()} + voteGovFlags := []string{strconv.Itoa(proposalCounter), "yes=0.8,no=0.1,abstain=0.05,no_with_veto=0.05"} + s.runGovProcess(chainAAPIEndpoint, sender, proposalCounter, upgradetypes.ProposalTypeSoftwareUpgrade, submitGovFlags, depositGovFlags, voteGovFlags, "weighted-vote", true) + + s.verifyChainHaltedAtUpgradeHeight(s.chainA, 0, proposalHeight) + s.T().Logf("Successfully halted chain at height %d", proposalHeight) + + s.TearDownSuite() + + s.T().Logf("Restarting containers") + s.SetupSuite() + + s.Require().Eventually( + func() bool { + h := s.getLatestBlockHeight(s.chainA, 0) + return h > 0 + }, + 30*time.Second, + 5*time.Second, + ) + + proposalCounter = 0 +} + +/* +GovCancelSoftwareUpgrade tests passing a gov proposal that cancels a pending upgrade. +Test Benchmarks: +1. Submission, deposit and vote of message based proposal to upgrade the chain at a height (current height + buffer) +2. Submission, deposit and vote of message based proposal to cancel the pending upgrade +3. Validation that the chain produced blocks past the intended upgrade height +*/ +func (s *IntegrationTestSuite) GovCancelSoftwareUpgrade() { + chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + senderAddress, _ := s.chainA.validators[0].keyInfo.GetAddress() + + sender := senderAddress.String() + height := s.getLatestBlockHeight(s.chainA, 0) + proposalHeight := height + 50 + s.writeGovLegProposal(s.chainA, int64(height), "upgrade-v1") + + // Gov tests may be run in arbitrary order, each test must increment proposalCounter to have the correct proposal id to submit and query + proposalCounter++ + submitGovFlags := []string{ + "software-upgrade", + "Upgrade-1", + "--title='Upgrade V1'", + "--description='Software Upgrade'", + "--no-validate", + fmt.Sprintf("--upgrade-height=%d", proposalHeight), + fmt.Sprintf("--upgrade-info=%s", configFile(proposalCommunitySpendFilename)), + } + + depositGovFlags := []string{strconv.Itoa(proposalCounter), depositAmount.String()} + voteGovFlags := []string{strconv.Itoa(proposalCounter), "yes"} + s.runGovProcess(chainAAPIEndpoint, sender, proposalCounter, upgradetypes.ProposalTypeSoftwareUpgrade, submitGovFlags, depositGovFlags, voteGovFlags, "vote", true) + + proposalCounter++ + submitGovFlags = []string{"cancel-software-upgrade", "--title='Upgrade V1'", "--description='Software Upgrade'"} + depositGovFlags = []string{strconv.Itoa(proposalCounter), depositAmount.String()} + voteGovFlags = []string{strconv.Itoa(proposalCounter), "yes"} + s.runGovProcess(chainAAPIEndpoint, sender, proposalCounter, upgradetypes.ProposalTypeCancelSoftwareUpgrade, submitGovFlags, depositGovFlags, voteGovFlags, "vote", true) + + s.verifyChainPassesUpgradeHeight(s.chainA, 0, proposalHeight) + s.T().Logf("Successfully canceled upgrade at height %d", proposalHeight) +} + +/* +GovCommunityPoolSpend tests passing a community spend proposal. +Test Benchmarks: +1. Fund Community Pool +2. Submission, deposit and vote of proposal to spend from the community pool to send atoms to a recipient +3. Validation that the recipient balance has increased by proposal amount +*/ +func (s *IntegrationTestSuite) GovCommunityPoolSpend() { + s.fundCommunityPool() + chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + senderAddress, _ := s.chainA.validators[0].keyInfo.GetAddress() + sender := senderAddress.String() + recipientAddress, _ := s.chainA.validators[1].keyInfo.GetAddress() + recipient := recipientAddress.String() + sendAmount := sdk.NewCoin(uatomDenom, sdk.NewInt(10000000)) // 10uatom + s.writeGovCommunitySpendProposal(s.chainA, sendAmount, recipient) + + beforeRecipientBalance, err := getSpecificBalance(chainAAPIEndpoint, recipient, uatomDenom) + s.Require().NoError(err) + + // Gov tests may be run in arbitrary order, each test must increment proposalCounter to have the correct proposal id to submit and query + proposalCounter++ + submitGovFlags := []string{configFile(proposalCommunitySpendFilename)} + depositGovFlags := []string{strconv.Itoa(proposalCounter), depositAmount.String()} + voteGovFlags := []string{strconv.Itoa(proposalCounter), "yes"} + // TODO: replace proposal type by distrtypes.ProposalTypeCommunityPoolSpend equivalent in SDK v0.47 + s.runGovProcessV1(chainAAPIEndpoint, sender, proposalCounter, "CommunityPoolSpend", submitGovFlags, depositGovFlags, voteGovFlags, "vote", false) + + s.Require().Eventually( + func() bool { + afterRecipientBalance, err := getSpecificBalance(chainAAPIEndpoint, recipient, uatomDenom) + s.Require().NoError(err) + + return afterRecipientBalance.Sub(sendAmount).IsEqual(beforeRecipientBalance) + }, + 10*time.Second, + 5*time.Second, + ) +} + +/* +AddRemoveConsumerChain tests adding and subsequently removing a new consumer chain to Gaia. +Test Benchmarks: +1. Submit and pass proposal to add consumer chain +2. Validation that consumer chain was added +3. Submit and pass proposal to remove consumer chain +4. Validation that consumer chain was removed +*/ // func (s *IntegrationTestSuite) AddRemoveConsumerChain() { // s.fundCommunityPool() // chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) -// proposerAddress := s.chainA.validators[0].keyInfo.GetAddress() +// proposerAddress, _ := s.chainA.validators[0].keyInfo.GetAddress() // sender := proposerAddress.String() // consumerChainID := "consumer" // s.writeAddRemoveConsumerProposals(s.chainA, consumerChainID) @@ -185,74 +205,88 @@ package e2e // return true // } -// func (s *IntegrationTestSuite) runGovProcess(chainAAPIEndpoint, sender string, proposalID int, proposalType string, submitFlags []string, depositFlags []string, voteFlags []string, voteCommand string, withDeposit bool) { -// s.T().Logf("Submitting Gov Proposal: %s", proposalType) -// // min deposit of 1000uatom is required in e2e tests, otherwise the gov antehandler causes the proposal to be dropped -// sflags := submitFlags -// if withDeposit { -// sflags = append(sflags, "--deposit=1000uatom") -// } -// s.submitGovCommand(chainAAPIEndpoint, sender, proposalID, "submit-proposal", sflags, govtypes.StatusDepositPeriod) -// s.T().Logf("Depositing Gov Proposal: %s", proposalType) -// s.submitGovCommand(chainAAPIEndpoint, sender, proposalID, "deposit", depositFlags, govtypes.StatusVotingPeriod) -// s.T().Logf("Voting Gov Proposal: %s", proposalType) -// s.submitGovCommand(chainAAPIEndpoint, sender, proposalID, voteCommand, voteFlags, govtypes.StatusPassed) -// } - -// func (s *IntegrationTestSuite) verifyChainHaltedAtUpgradeHeight(c *chain, valIdx, upgradeHeight int) { -// s.Require().Eventually( -// func() bool { -// currentHeight := s.getLatestBlockHeight(c, valIdx) - -// return currentHeight == upgradeHeight -// }, -// 30*time.Second, -// 5*time.Second, -// ) - -// counter := 0 -// s.Require().Eventually( -// func() bool { -// currentHeight := s.getLatestBlockHeight(c, valIdx) - -// if currentHeight > upgradeHeight { -// return false -// } -// if currentHeight == upgradeHeight { -// counter++ -// } -// return counter >= 2 -// }, -// 8*time.Second, -// 2*time.Second, -// ) -// } - -// func (s *IntegrationTestSuite) verifyChainPassesUpgradeHeight(c *chain, valIdx, upgradeHeight int) { -// s.Require().Eventually( -// func() bool { -// currentHeight := s.getLatestBlockHeight(c, valIdx) - -// return currentHeight > upgradeHeight -// }, -// 30*time.Second, -// 5*time.Second, -// ) -// } - -// func (s *IntegrationTestSuite) submitGovCommand(chainAAPIEndpoint, sender string, proposalID int, govCommand string, proposalFlags []string, expectedSuccessStatus govtypes.ProposalStatus) { -// s.Run(fmt.Sprintf("Running tx gov %s", govCommand), func() { -// s.runGovExec(s.chainA, 0, sender, govCommand, proposalFlags, standardFees.String()) - -// s.Require().Eventually( -// func() bool { -// proposal, err := queryGovProposal(chainAAPIEndpoint, proposalID) -// s.Require().NoError(err) - -// return proposal.GetProposal().Status == expectedSuccessStatus -// }, -// 15*time.Second, -// 5*time.Second, -// ) -// }) -// } +func (s *IntegrationTestSuite) runGovProcess(chainAAPIEndpoint, sender string, proposalID int, proposalType string, submitFlags []string, depositFlags []string, voteFlags []string, voteCommand string, withDeposit bool) { + s.T().Logf("Submitting Gov Proposal: %s", proposalType) + // min deposit of 1000uatom is required in e2e tests, otherwise the gov antehandler causes the proposal to be dropped + sflags := submitFlags + if withDeposit { + sflags = append(sflags, "--deposit=1000uatom") + } + s.submitGovCommand(chainAAPIEndpoint, sender, proposalID, "submit-legacy-proposal", sflags, govtypesv1beta1.StatusDepositPeriod) + s.T().Logf("Depositing Gov Proposal: %s", proposalType) + s.submitGovCommand(chainAAPIEndpoint, sender, proposalID, "deposit", depositFlags, govtypesv1beta1.StatusVotingPeriod) + s.T().Logf("Voting Gov Proposal: %s", proposalType) + s.submitGovCommand(chainAAPIEndpoint, sender, proposalID, voteCommand, voteFlags, govtypesv1beta1.StatusPassed) +} + +func (s *IntegrationTestSuite) runGovProcessV1(chainAAPIEndpoint, sender string, proposalID int, proposalType string, submitFlags []string, depositFlags []string, voteFlags []string, voteCommand string, withDeposit bool) { + s.T().Logf("Submitting Gov Proposal: %s", proposalType) + // min deposit of 1000uatom is required in e2e tests, otherwise the gov antehandler causes the proposal to be dropped + sflags := submitFlags + if withDeposit { + sflags = append(sflags, "--deposit=1000uatom") + } + s.submitGovCommand(chainAAPIEndpoint, sender, proposalID, "submit-proposal", sflags, govtypesv1beta1.StatusDepositPeriod) + s.T().Logf("Depositing Gov Proposal: %s", proposalType) + s.submitGovCommand(chainAAPIEndpoint, sender, proposalID, "deposit", depositFlags, govtypesv1beta1.StatusVotingPeriod) + s.T().Logf("Voting Gov Proposal: %s", proposalType) + s.submitGovCommand(chainAAPIEndpoint, sender, proposalID, voteCommand, voteFlags, govtypesv1beta1.StatusPassed) +} + +func (s *IntegrationTestSuite) verifyChainHaltedAtUpgradeHeight(c *chain, valIdx, upgradeHeight int) { + s.Require().Eventually( + func() bool { + currentHeight := s.getLatestBlockHeight(c, valIdx) + + return currentHeight == upgradeHeight + }, + 30*time.Second, + 5*time.Second, + ) + + counter := 0 + s.Require().Eventually( + func() bool { + currentHeight := s.getLatestBlockHeight(c, valIdx) + + if currentHeight > upgradeHeight { + return false + } + if currentHeight == upgradeHeight { + counter++ + } + return counter >= 2 + }, + 8*time.Second, + 2*time.Second, + ) +} + +func (s *IntegrationTestSuite) verifyChainPassesUpgradeHeight(c *chain, valIdx, upgradeHeight int) { + s.Require().Eventually( + func() bool { + currentHeight := s.getLatestBlockHeight(c, valIdx) + + return currentHeight > upgradeHeight + }, + 30*time.Second, + 5*time.Second, + ) +} + +func (s *IntegrationTestSuite) submitGovCommand(chainAAPIEndpoint, sender string, proposalID int, govCommand string, proposalFlags []string, expectedSuccessStatus govtypesv1beta1.ProposalStatus) { + s.Run(fmt.Sprintf("Running tx gov %s", govCommand), func() { + s.runGovExec(s.chainA, 0, sender, govCommand, proposalFlags, standardFees.String()) + + s.Require().Eventually( + func() bool { + proposal, err := queryGovProposal(chainAAPIEndpoint, proposalID) + s.Require().NoError(err) + + return proposal.GetProposal().Status == expectedSuccessStatus + }, + 15*time.Second, + 5*time.Second, + ) + }) +} diff --git a/tests/e2e/e2e_ibc_test.go b/tests/e2e/e2e_ibc_test.go index a8b8d57cbb8..2f2ce19ddb0 100644 --- a/tests/e2e/e2e_ibc_test.go +++ b/tests/e2e/e2e_ibc_test.go @@ -1,482 +1,481 @@ package e2e -// import ( -// "bytes" -// "context" -// "encoding/json" -// "fmt" -// "strconv" -// "strings" -// "time" - -// "github.com/cosmos/cosmos-sdk/client/flags" -// sdk "github.com/cosmos/cosmos-sdk/types" -// "github.com/ory/dockertest/v3/docker" -// ) - -// 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"` -// } - -// type PacketMetadata struct { -// Forward *ForwardMetadata `json:"forward"` -// } - -// func (s *IntegrationTestSuite) sendIBC(c *chain, valIdx int, sender, recipient, token, fees, note string) { -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// ibcCmd := []string{ -// gaiadBinary, -// txCommand, -// "ibc-transfer", -// "transfer", -// "transfer", -// "channel-0", -// recipient, -// token, -// fmt.Sprintf("--from=%s", sender), -// fmt.Sprintf("--%s=%s", flags.FlagFees, fees), -// fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), -// // fmt.Sprintf("--%s=%s", flags.FlagNote, note), -// fmt.Sprintf("--memo=%s", note), -// "--keyring-backend=test", -// "--broadcast-mode=sync", -// "--output=json", -// "-y", -// } -// s.T().Logf("sending %s from %s (%s) to %s (%s) with memo %s", token, s.chainA.id, sender, s.chainB.id, recipient, note) -// s.executeGaiaTxCommand(ctx, c, ibcCmd, valIdx, s.defaultExecValidation(c, valIdx)) -// s.T().Log("successfully sent IBC tokens") -// } - -// func (s *IntegrationTestSuite) hermesTransfer(configPath, srcChainID, dstChainID, srcChannelID, denom string, sendAmt, timeOutOffset, numMsg int) (success bool) { -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// hermesCmd := []string{ -// hermesBinary, -// fmt.Sprintf("--config=%s", configPath), -// "tx", -// "ft-transfer", -// fmt.Sprintf("--dst-chain=%s", dstChainID), -// fmt.Sprintf("--src-chain=%s", srcChainID), -// fmt.Sprintf("--src-channel=%s", srcChannelID), -// fmt.Sprintf("--src-port=%s", "transfer"), -// fmt.Sprintf("--amount=%v", sendAmt), -// fmt.Sprintf("--denom=%s", denom), -// fmt.Sprintf("--timeout-height-offset=%v", timeOutOffset), -// fmt.Sprintf("--number-msgs=%v", numMsg), -// } - -// stdout, stderr := s.executeHermesCommand(ctx, hermesCmd) -// if strings.Contains(string(stdout), "ERROR") || strings.Contains(string(stderr), "ERROR") { -// return false -// } - -// return true -// } - -// func (s *IntegrationTestSuite) hermesClearPacket(configPath, chainID, channelID string) (success bool) { //nolint:unparam -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// hermesCmd := []string{ -// hermesBinary, -// fmt.Sprintf("--config=%s", configPath), -// "clear", -// "packets", -// fmt.Sprintf("--chain=%s", chainID), -// fmt.Sprintf("--channel=%s", channelID), -// fmt.Sprintf("--port=%s", "transfer"), -// } - -// stdout, stderr := s.executeHermesCommand(ctx, hermesCmd) -// if strings.Contains(string(stdout), "ERROR") || strings.Contains(string(stderr), "ERROR") { -// return false -// } - -// return true -// } - -// type RelayerPacketsOutput struct { -// Result struct { -// Dst struct { -// UnreceivedPackets []interface{} `json:"unreceived_packets"` -// } `json:"dst"` -// Src struct { -// UnreceivedPackets []interface{} `json:"unreceived_packets"` -// } `json:"src"` -// } `json:"result"` -// Status string `json:"status"` -// } - -// func (s *IntegrationTestSuite) hermesPendingPackets(configPath, chainID, channelID string) (pendingPackets bool) { -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() -// hermesCmd := []string{ -// hermesBinary, -// "--json", -// fmt.Sprintf("--config=%s", configPath), -// "query", -// "packet", -// "pending", -// fmt.Sprintf("--chain=%s", chainID), -// fmt.Sprintf("--channel=%s", channelID), -// fmt.Sprintf("--port=%s", "transfer"), -// } - -// stdout, _ := s.executeHermesCommand(ctx, hermesCmd) - -// var relayerPacketsOutput RelayerPacketsOutput -// err := json.Unmarshal(stdout, &relayerPacketsOutput) -// s.Require().NoError(err) - -// // Check if "unreceived_packets" exists in "src" -// return len(relayerPacketsOutput.Result.Src.UnreceivedPackets) != 0 -// } - -// func (s *IntegrationTestSuite) queryRelayerWalletsBalances() (sdk.Coin, sdk.Coin) { -// chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) -// scrRelayerBalance, err := getSpecificBalance( -// chainAAPIEndpoint, -// s.chainA.genesisAccounts[relayerAccountIndexHermes1].keyInfo.GetAddress().String(), -// uatomDenom) -// s.Require().NoError(err) - -// chainBAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainB.id][0].GetHostPort("1317/tcp")) -// dstRelayerBalance, err := getSpecificBalance( -// chainBAPIEndpoint, -// s.chainB.genesisAccounts[relayerAccountIndexHermes1].keyInfo.GetAddress().String(), -// uatomDenom) -// s.Require().NoError(err) - -// return scrRelayerBalance, dstRelayerBalance -// } - -// func (s *IntegrationTestSuite) createConnection() { -// s.T().Logf("connecting %s and %s chains via IBC", s.chainA.id, s.chainB.id) - -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ -// Context: ctx, -// AttachStdout: true, -// AttachStderr: true, -// Container: s.hermesResource0.Container.ID, -// User: "root", -// Cmd: []string{ -// "hermes", -// "create", -// "connection", -// "--a-chain", -// s.chainA.id, -// "--b-chain", -// s.chainB.id, -// }, -// }) -// s.Require().NoError(err) - -// var ( -// outBuf bytes.Buffer -// errBuf bytes.Buffer -// ) - -// err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ -// Context: ctx, -// Detach: false, -// OutputStream: &outBuf, -// ErrorStream: &errBuf, -// }) -// s.Require().NoErrorf( -// err, -// "failed connect chains; stdout: %s, stderr: %s", outBuf.String(), errBuf.String(), -// ) - -// s.T().Logf("connected %s and %s chains via IBC", s.chainA.id, s.chainB.id) -// } - -// func (s *IntegrationTestSuite) createChannel() { -// s.T().Logf("connecting %s and %s chains via IBC", s.chainA.id, s.chainB.id) - -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() - -// exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ -// Context: ctx, -// AttachStdout: true, -// AttachStderr: true, -// Container: s.hermesResource0.Container.ID, -// User: "root", -// Cmd: []string{ -// "hermes", -// txCommand, -// "chan-open-init", -// "--dst-chain", -// s.chainA.id, -// "--src-chain", -// s.chainB.id, -// "--dst-connection", -// "connection-0", -// "--src-port=transfer", -// "--dst-port=transfer", -// }, -// }) -// s.Require().NoError(err) - -// var ( -// outBuf bytes.Buffer -// errBuf bytes.Buffer -// ) - -// err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ -// Context: ctx, -// Detach: false, -// OutputStream: &outBuf, -// ErrorStream: &errBuf, -// }) -// s.Require().NoErrorf( -// err, -// "failed connect chains; stdout: %s, stderr: %s", outBuf.String(), errBuf.String(), -// ) - -// s.T().Logf("connected %s and %s chains via IBC", s.chainA.id, s.chainB.id) -// } - -// func (s *IntegrationTestSuite) testIBCTokenTransfer() { -// s.Run("send_uatom_to_chainB", func() { -// // require the recipient account receives the IBC tokens (IBC packets ACKd) -// var ( -// balances sdk.Coins -// err error -// beforeBalance int64 -// ibcStakeDenom string -// ) - -// address := s.chainA.validators[0].keyInfo.GetAddress() -// sender := address.String() - -// address = s.chainB.validators[0].keyInfo.GetAddress() -// recipient := address.String() - -// chainBAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainB.id][0].GetHostPort("1317/tcp")) - -// s.Require().Eventually( -// func() bool { -// balances, err = queryGaiaAllBalances(chainBAPIEndpoint, recipient) -// s.Require().NoError(err) -// return balances.Len() != 0 -// }, -// time.Minute, -// 5*time.Second, -// ) -// for _, c := range balances { -// if strings.Contains(c.Denom, "ibc/") { -// beforeBalance = c.Amount.Int64() -// break -// } -// } - -// tokenAmt := 3300000000 -// s.sendIBC(s.chainA, 0, sender, recipient, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), "") - -// s.Require().Eventually( -// func() bool { -// balances, err = queryGaiaAllBalances(chainBAPIEndpoint, recipient) -// s.Require().NoError(err) -// return balances.Len() != 0 -// }, -// time.Minute, -// 5*time.Second, -// ) -// for _, c := range balances { -// if strings.Contains(c.Denom, "ibc/") { -// ibcStakeDenom = c.Denom -// s.Require().Equal((int64(tokenAmt) + beforeBalance), c.Amount.Int64()) -// break -// } -// } - -// s.Require().NotEmpty(ibcStakeDenom) -// }) -// } - -// /* -// TestMultihopIBCTokenTransfer tests that sending an IBC transfer using the IBC Packet Forward Middleware accepts a port, channel and account address - -// Steps: -// 1. Check balance of Account 1 on Chain 1 -// 2. Check balance of Account 2 on Chain 1 -// 3. Account 1 on Chain 1 sends x tokens to Account 2 on Chain 1 via Account 1 on Chain 2 -// 4. Check Balance of Account 1 on Chain 1, confirm it is original minus x tokens -// 5. Check Balance of Account 2 on Chain 1, confirm it is original plus x tokens - -// */ -// // TODO: Add back only if packet forward middleware has a working version compatible with IBC v3.0.x -// func (s *IntegrationTestSuite) testMultihopIBCTokenTransfer() { -// time.Sleep(30 * time.Second) - -// s.Run("send_successful_multihop_uatom_to_chainA_from_chainA", func() { -// // require the recipient account receives the IBC tokens (IBC packets ACKd) -// var ( -// err error -// ) - -// address := s.chainA.validators[0].keyInfo.GetAddress() -// sender := address.String() - -// address = s.chainB.validators[0].keyInfo.GetAddress() -// middlehop := address.String() - -// address = s.chainA.validators[1].keyInfo.GetAddress() -// recipient := address.String() - -// forwardPort := "transfer" -// forwardChannel := "channel-0" - -// tokenAmt := 3300000000 - -// chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) - -// var ( -// beforeSenderUAtomBalance sdk.Coin -// beforeRecipientUAtomBalance sdk.Coin -// ) - -// s.Require().Eventually( -// func() bool { -// beforeSenderUAtomBalance, err = getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) -// s.Require().NoError(err) -// fmt.Println("beforeSenderUAtomBalance", beforeSenderUAtomBalance) - -// beforeRecipientUAtomBalance, err = getSpecificBalance(chainAAPIEndpoint, recipient, uatomDenom) -// s.Require().NoError(err) -// fmt.Print("beforeRecipientUAtomBalance", beforeRecipientUAtomBalance) - -// return beforeSenderUAtomBalance.IsValid() && beforeRecipientUAtomBalance.IsValid() -// }, -// 1*time.Minute, -// 5*time.Second, -// ) - -// firstHopMetadata := &PacketMetadata{ -// Forward: &ForwardMetadata{ -// Receiver: recipient, -// Channel: forwardChannel, -// Port: forwardPort, -// }, -// } - -// memo, err := json.Marshal(firstHopMetadata) -// s.Require().NoError(err) - -// s.sendIBC(s.chainA, 0, sender, middlehop, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), string(memo)) - -// s.Require().Eventually( -// func() bool { -// afterSenderUAtomBalance, err := getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) -// s.Require().NoError(err) - -// afterRecipientUAtomBalance, err := getSpecificBalance(chainAAPIEndpoint, recipient, uatomDenom) -// s.Require().NoError(err) - -// decremented := beforeSenderUAtomBalance.Sub(tokenAmount).Sub(standardFees).IsEqual(afterSenderUAtomBalance) -// incremented := beforeRecipientUAtomBalance.Add(tokenAmount).IsEqual(afterRecipientUAtomBalance) - -// return decremented && incremented -// }, -// 1*time.Minute, -// 5*time.Second, -// ) -// }) -// } - -// /* -// TestFailedMultihopIBCTokenTransfer tests that sending a failing IBC transfer using the IBC Packet Forward -// Middleware will send the tokens back to the original account after failing. -// */ -// func (s *IntegrationTestSuite) testFailedMultihopIBCTokenTransfer() { -// time.Sleep(30 * time.Second) - -// s.Run("send_failed_multihop_uatom_to_chainA_from_chainA", func() { -// address := s.chainA.validators[0].keyInfo.GetAddress() -// sender := address.String() - -// address = s.chainB.validators[0].keyInfo.GetAddress() -// middlehop := address.String() - -// address = s.chainA.validators[1].keyInfo.GetAddress() -// recipient := strings.Replace(address.String(), "cosmos", "foobar", 1) // this should be an invalid recipient to force the tx to fail - -// forwardPort := "transfer" -// forwardChannel := "channel-0" - -// tokenAmt := 3300000000 - -// chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) - -// var ( -// beforeSenderUAtomBalance sdk.Coin -// err error -// ) - -// s.Require().Eventually( -// func() bool { -// beforeSenderUAtomBalance, err = getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) -// s.Require().NoError(err) - -// return beforeSenderUAtomBalance.IsValid() -// }, -// 1*time.Minute, -// 5*time.Second, -// ) - -// firstHopMetadata := &PacketMetadata{ -// Forward: &ForwardMetadata{ -// Receiver: recipient, -// Channel: forwardChannel, -// Port: forwardPort, -// }, -// } - -// memo, err := json.Marshal(firstHopMetadata) -// s.Require().NoError(err) - -// s.sendIBC(s.chainA, 0, sender, middlehop, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), string(memo)) - -// // Sender account should be initially decremented the full amount -// s.Require().Eventually( -// func() bool { -// afterSenderUAtomBalance, err := getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) -// s.Require().NoError(err) - -// returned := beforeSenderUAtomBalance.Sub(tokenAmount).Sub(standardFees).IsEqual(afterSenderUAtomBalance) - -// return returned -// }, -// 1*time.Minute, -// 1*time.Second, -// ) - -// // since the forward receiving account is invalid, it should be refunded to the original sender (minus the original fee) -// s.Require().Eventually( -// func() bool { -// afterSenderUAtomBalance, err := getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) -// s.Require().NoError(err) - -// returned := beforeSenderUAtomBalance.Sub(standardFees).IsEqual(afterSenderUAtomBalance) - -// return returned -// }, -// 5*time.Minute, -// 5*time.Second, -// ) -// }) -// } +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "os" + "path" + "path/filepath" + "strconv" + "strings" + "time" + + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ory/dockertest/v3" + "github.com/ory/dockertest/v3/docker" +) + +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"` +} + +type PacketMetadata struct { + Forward *ForwardMetadata `json:"forward"` +} + +func (s *IntegrationTestSuite) runIBCRelayer() { + s.T().Log("starting Hermes relayer container...") + + tmpDir, err := os.MkdirTemp("", "gaia-e2e-testnet-hermes-") + s.Require().NoError(err) + s.tmpDirs = append(s.tmpDirs, tmpDir) + + gaiaAVal := s.chainA.validators[0] + gaiaBVal := s.chainB.validators[0] + + gaiaARly := s.chainA.genesisAccounts[relayerAccountIndex] + gaiaBRly := s.chainB.genesisAccounts[relayerAccountIndex] + + hermesCfgPath := path.Join(tmpDir, "hermes") + + s.Require().NoError(os.MkdirAll(hermesCfgPath, 0o755)) + _, err = copyFile( + filepath.Join("./scripts/", "hermes_bootstrap.sh"), + filepath.Join(hermesCfgPath, "hermes_bootstrap.sh"), + ) + s.Require().NoError(err) + + s.hermesResource, err = s.dkrPool.RunWithOptions( + &dockertest.RunOptions{ + Name: fmt.Sprintf("%s-%s-relayer", s.chainA.id, s.chainB.id), + Repository: "ghcr.io/informalsystems/hermes", + Tag: "1.4.1", + NetworkID: s.dkrNet.Network.ID, + Mounts: []string{ + fmt.Sprintf("%s/:/root/hermes", hermesCfgPath), + }, + PortBindings: map[docker.Port][]docker.PortBinding{ + "3031/tcp": {{HostIP: "", HostPort: "3031"}}, + }, + Env: []string{ + fmt.Sprintf("GAIA_A_E2E_CHAIN_ID=%s", s.chainA.id), + fmt.Sprintf("GAIA_B_E2E_CHAIN_ID=%s", s.chainB.id), + fmt.Sprintf("GAIA_A_E2E_VAL_MNEMONIC=%s", gaiaAVal.mnemonic), + fmt.Sprintf("GAIA_B_E2E_VAL_MNEMONIC=%s", gaiaBVal.mnemonic), + fmt.Sprintf("GAIA_A_E2E_RLY_MNEMONIC=%s", gaiaARly.mnemonic), + fmt.Sprintf("GAIA_B_E2E_RLY_MNEMONIC=%s", gaiaBRly.mnemonic), + fmt.Sprintf("GAIA_A_E2E_VAL_HOST=%s", s.valResources[s.chainA.id][0].Container.Name[1:]), + fmt.Sprintf("GAIA_B_E2E_VAL_HOST=%s", s.valResources[s.chainB.id][0].Container.Name[1:]), + }, + User: "root", + Entrypoint: []string{ + "sh", + "-c", + "chmod +x /root/hermes/hermes_bootstrap.sh && /root/hermes/hermes_bootstrap.sh", + }, + }, + noRestart, + ) + s.Require().NoError(err) + + // TODO: debug relayer REST endpoint + // endpoint := fmt.Sprintf("http://%s/state", s.hermesResource.GetHostPort("3031/tcp")) + // s.Require().Eventually( + // func() bool { + // resp, err := http.Get(endpoint) //nolint:gosec // this is a test + // if err != nil { + // return false + // } + + // defer resp.Body.Close() + + // bz, err := io.ReadAll(resp.Body) + // if err != nil { + // return false + // } + + // var respBody map[string]interface{} + // if err := json.Unmarshal(bz, &respBody); err != nil { + // return false + // } + + // status := respBody["status"].(string) + // result := respBody["result"].(map[string]interface{}) + + // return status == "success" && len(result["chains"].([]interface{})) == 2 + // }, + // 5*time.Minute, + // time.Second, + // "hermes relayer not healthy", + // ) + + s.T().Logf("started Hermes relayer container: %s", s.hermesResource.Container.ID) + + // XXX: Give time to both networks to start, otherwise we might see gRPC + // transport errors. + time.Sleep(10 * time.Second) + + // create the client, connection and channel between the two Gaia chains + s.createConnection() + time.Sleep(10 * time.Second) + s.createChannel() +} + +func (s *IntegrationTestSuite) sendIBC(c *chain, valIdx int, sender, recipient, token, fees, note string) { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + ibcCmd := []string{ + gaiadBinary, + txCommand, + "ibc-transfer", + "transfer", + "transfer", + "channel-0", + recipient, + token, + fmt.Sprintf("--from=%s", sender), + fmt.Sprintf("--%s=%s", flags.FlagFees, fees), + fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), + // fmt.Sprintf("--%s=%s", flags.FlagNote, note), + fmt.Sprintf("--memo=%s", note), + "--keyring-backend=test", + "--broadcast-mode=sync", + "--output=json", + "-y", + } + s.T().Logf("sending %s from %s (%s) to %s (%s) with memo %s", token, s.chainA.id, sender, s.chainB.id, recipient, note) + s.executeGaiaTxCommand(ctx, c, ibcCmd, valIdx, s.defaultExecValidation(c, valIdx)) + s.T().Log("successfully sent IBC tokens") +} + +func (s *IntegrationTestSuite) createConnection() { + s.T().Logf("connecting %s and %s chains via IBC", s.chainA.id, s.chainB.id) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ + Context: ctx, + AttachStdout: true, + AttachStderr: true, + Container: s.hermesResource.Container.ID, + User: "root", + Cmd: []string{ + "hermes", + "create", + "connection", + "--a-chain", + s.chainA.id, + "--b-chain", + s.chainB.id, + }, + }) + s.Require().NoError(err) + + var ( + outBuf bytes.Buffer + errBuf bytes.Buffer + ) + + err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ + Context: ctx, + Detach: false, + OutputStream: &outBuf, + ErrorStream: &errBuf, + }) + s.Require().NoErrorf( + err, + "failed connect chains; stdout: %s, stderr: %s", outBuf.String(), errBuf.String(), + ) + + s.T().Logf("connected %s and %s chains via IBC", s.chainA.id, s.chainB.id) +} + +func (s *IntegrationTestSuite) createChannel() { + s.T().Logf("connecting %s and %s chains via IBC", s.chainA.id, s.chainB.id) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ + Context: ctx, + AttachStdout: true, + AttachStderr: true, + Container: s.hermesResource.Container.ID, + User: "root", + Cmd: []string{ + "hermes", + txCommand, + "chan-open-init", + "--dst-chain", + s.chainA.id, + "--src-chain", + s.chainB.id, + "--dst-connection", + "connection-0", + "--src-port=transfer", + "--dst-port=transfer", + }, + }) + + s.Require().NoError(err) + + var ( + outBuf bytes.Buffer + errBuf bytes.Buffer + ) + + err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ + Context: ctx, + Detach: false, + OutputStream: &outBuf, + ErrorStream: &errBuf, + }) + + s.Require().NoErrorf( + err, + "failed connect chains; stdout: %s, stderr: %s", outBuf.String(), errBuf.String(), + ) + + s.T().Logf("connected %s and %s chains via IBC", s.chainA.id, s.chainB.id) +} + +func (s *IntegrationTestSuite) testIBCTokenTransfer() { + time.Sleep(30 * time.Second) + s.Run("send_uatom_to_chainB", func() { + // require the recipient account receives the IBC tokens (IBC packets ACKd) + var ( + balances sdk.Coins + err error + beforeBalance int64 + ibcStakeDenom string + ) + + address, _ := s.chainA.validators[0].keyInfo.GetAddress() + sender := address.String() + + address, _ = s.chainB.validators[0].keyInfo.GetAddress() + recipient := address.String() + + chainBAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainB.id][0].GetHostPort("1317/tcp")) + + s.Require().Eventually( + func() bool { + balances, err = queryGaiaAllBalances(chainBAPIEndpoint, recipient) + s.Require().NoError(err) + return balances.Len() != 0 + }, + time.Minute, + 5*time.Second, + ) + for _, c := range balances { + if strings.Contains(c.Denom, "ibc/") { + beforeBalance = c.Amount.Int64() + break + } + } + + tokenAmt := 3300000000 + s.sendIBC(s.chainA, 0, sender, recipient, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), "") + + s.Require().Eventually( + func() bool { + balances, err = queryGaiaAllBalances(chainBAPIEndpoint, recipient) + s.Require().NoError(err) + return balances.Len() != 0 + }, + time.Minute, + 5*time.Second, + ) + for _, c := range balances { + if strings.Contains(c.Denom, "ibc/") { + ibcStakeDenom = c.Denom + s.Require().Equal((int64(tokenAmt) + beforeBalance), c.Amount.Int64()) + break + } + } + + s.Require().NotEmpty(ibcStakeDenom) + }) +} + +/* +TestMultihopIBCTokenTransfer tests that sending an IBC transfer using the IBC Packet Forward Middleware accepts a port, channel and account address + +Steps: +1. Check balance of Account 1 on Chain 1 +2. Check balance of Account 2 on Chain 1 +3. Account 1 on Chain 1 sends x tokens to Account 2 on Chain 1 via Account 1 on Chain 2 +4. Check Balance of Account 1 on Chain 1, confirm it is original minus x tokens +5. Check Balance of Account 2 on Chain 1, confirm it is original plus x tokens + +*/ +// TODO: Add back only if packet forward middleware has a working version compatible with IBC v3.0.x +func (s *IntegrationTestSuite) testMultihopIBCTokenTransfer() { + time.Sleep(30 * time.Second) + + s.Run("send_successful_multihop_uatom_to_chainA_from_chainA", func() { + // require the recipient account receives the IBC tokens (IBC packets ACKd) + var ( + err error + ) + + address, _ := s.chainA.validators[0].keyInfo.GetAddress() + sender := address.String() + + address, _ = s.chainB.validators[0].keyInfo.GetAddress() + middlehop := address.String() + + address, _ = s.chainA.validators[1].keyInfo.GetAddress() + recipient := address.String() + + forwardPort := "transfer" + forwardChannel := "channel-0" + + tokenAmt := 3300000000 + + chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + + var ( + beforeSenderUAtomBalance sdk.Coin + beforeRecipientUAtomBalance sdk.Coin + ) + + s.Require().Eventually( + func() bool { + beforeSenderUAtomBalance, err = getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) + s.Require().NoError(err) + + beforeRecipientUAtomBalance, err = getSpecificBalance(chainAAPIEndpoint, recipient, uatomDenom) + s.Require().NoError(err) + + return beforeSenderUAtomBalance.IsValid() && beforeRecipientUAtomBalance.IsValid() + }, + 1*time.Minute, + 5*time.Second, + ) + + firstHopMetadata := &PacketMetadata{ + Forward: &ForwardMetadata{ + Receiver: recipient, + Channel: forwardChannel, + Port: forwardPort, + }, + } + + memo, err := json.Marshal(firstHopMetadata) + s.Require().NoError(err) + + s.sendIBC(s.chainA, 0, sender, middlehop, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), string(memo)) + + s.Require().Eventually( + func() bool { + afterSenderUAtomBalance, err := getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) + s.Require().NoError(err) + + afterRecipientUAtomBalance, err := getSpecificBalance(chainAAPIEndpoint, recipient, uatomDenom) + s.Require().NoError(err) + + decremented := beforeSenderUAtomBalance.Sub(tokenAmount).Sub(standardFees).IsEqual(afterSenderUAtomBalance) + incremented := beforeRecipientUAtomBalance.Add(tokenAmount).IsEqual(afterRecipientUAtomBalance) + + return decremented && incremented + }, + 1*time.Minute, + 5*time.Second, + ) + }) +} + +/* +TestFailedMultihopIBCTokenTransfer tests that sending a failing IBC transfer using the IBC Packet Forward +Middleware will send the tokens back to the original account after failing. +*/ +func (s *IntegrationTestSuite) testFailedMultihopIBCTokenTransfer() { + time.Sleep(30 * time.Second) + + s.Run("send_failed_multihop_uatom_to_chainA_from_chainA", func() { + address, _ := s.chainA.validators[0].keyInfo.GetAddress() + sender := address.String() + + address, _ = s.chainB.validators[0].keyInfo.GetAddress() + middlehop := address.String() + + address, _ = s.chainA.validators[1].keyInfo.GetAddress() + recipient := strings.Replace(address.String(), "cosmos", "foobar", 1) // this should be an invalid recipient to force the tx to fail + + forwardPort := "transfer" + forwardChannel := "channel-0" + + tokenAmt := 3300000000 + + chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + + var ( + beforeSenderUAtomBalance sdk.Coin + err error + ) + + s.Require().Eventually( + func() bool { + beforeSenderUAtomBalance, err = getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) + s.Require().NoError(err) + + return beforeSenderUAtomBalance.IsValid() + }, + 1*time.Minute, + 5*time.Second, + ) + + firstHopMetadata := &PacketMetadata{ + Forward: &ForwardMetadata{ + Receiver: recipient, + Channel: forwardChannel, + Port: forwardPort, + }, + } + + memo, err := json.Marshal(firstHopMetadata) + s.Require().NoError(err) + + s.sendIBC(s.chainA, 0, sender, middlehop, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), string(memo)) + + // Sender account should be initially decremented the full amount + s.Require().Eventually( + func() bool { + afterSenderUAtomBalance, err := getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) + s.Require().NoError(err) + + returned := beforeSenderUAtomBalance.Sub(tokenAmount).Sub(standardFees).IsEqual(afterSenderUAtomBalance) + + return returned + }, + 1*time.Minute, + 1*time.Second, + ) + + // since the forward receiving account is invalid, it should be refunded to the original sender (minus the original fee) + s.Require().Eventually( + func() bool { + afterSenderUAtomBalance, err := getSpecificBalance(chainAAPIEndpoint, sender, uatomDenom) + s.Require().NoError(err) + + returned := beforeSenderUAtomBalance.Sub(standardFees).IsEqual(afterSenderUAtomBalance) + + return returned + }, + 5*time.Minute, + 5*time.Second, + ) + }) +} diff --git a/tests/e2e/e2e_rest_regression_test.go b/tests/e2e/e2e_rest_regression_test.go index aa0c2b2f185..3ded9e09778 100644 --- a/tests/e2e/e2e_rest_regression_test.go +++ b/tests/e2e/e2e_rest_regression_test.go @@ -1,12 +1,11 @@ package e2e -// -// import ( -// "fmt" -// "net/http" -//) -// -///* +import ( + "fmt" + "net/http" +) + +// /* // RestRegression tests the continuity of critical endpoints that node operators, block explorers, and ecosystem participants depend on. // Test Node REST Endpoints: // 1. http://host:1317/validatorsets/latest @@ -26,65 +25,64 @@ package e2e // 7. Slashing params // 8. Staking params // */ -// -// const ( -// valSetLatestPath = "/validatorsets/latest" -// valSetHeightPath = "/validatorsets/1" -// blocksLatestPath = "/blocks/latest" -// blocksHeightPath = "/blocks/1" -// syncingPath = "/syncing" -// nodeInfoPath = "/node_info" -// transactionsPath = "/txs" -// bankTotalModuleQueryPath = "/bank/total" -// authParamsModuleQueryPath = "/auth/params" -// distributionCommPoolModuleQueryPath = "/distribution/community_pool" -// evidenceModuleQueryPath = "/evidence" -// govPropsModuleQueryPath = "/gov/proposals" -// mintingParamsModuleQueryPath = "/minting/parameters" -// slashingParamsModuleQueryPath = "/slashing/parameters" -// stakingParamsModuleQueryPath = "/staking/parameters" -// missingPath = "/missing_endpoint" -//) -// -// func (s *IntegrationTestSuite) testRestInterfaces() { -// s.Run("test rest interfaces", func() { -// var ( -// valIdx = 0 -// c = s.chainA -// endpointURL = fmt.Sprintf("http://%s", s.valResources[c.id][valIdx].GetHostPort("1317/tcp")) -// testEndpoints = []struct { -// Path string -// ExpectedStatus int -// }{ -// // Client Endpoints -// {nodeInfoPath, 200}, -// {syncingPath, 200}, -// {valSetLatestPath, 200}, -// {valSetHeightPath, 200}, -// {blocksLatestPath, 200}, -// {blocksHeightPath, 200}, -// {transactionsPath, 200}, -// // Module Endpoints -// {bankTotalModuleQueryPath, 200}, -// {authParamsModuleQueryPath, 200}, -// {distributionCommPoolModuleQueryPath, 200}, -// {evidenceModuleQueryPath, 200}, -// {govPropsModuleQueryPath, 200}, -// {mintingParamsModuleQueryPath, 200}, -// {slashingParamsModuleQueryPath, 200}, -// {stakingParamsModuleQueryPath, 200}, -// {missingPath, 501}, -// } -// ) -// -// for _, endpoint := range testEndpoints { -// resp, err := http.Get(fmt.Sprintf("%s%s", endpointURL, endpoint.Path)) -// s.NoError(err, fmt.Sprintf("failed to get endpoint: %s%s", endpointURL, endpoint.Path)) -// -// _, err = readJSON(resp) -// s.NoError(err, fmt.Sprintf("failed to read body of endpoint: %s%s", endpointURL, endpoint.Path)) -// -// s.EqualValues(resp.StatusCode, endpoint.ExpectedStatus) -// } -// }) -//} +const ( + valSetLatestPath = "/cosmos/base/tendermint/v1beta1/validatorsets/latest" + valSetHeightPath = "/cosmos/base/tendermint/v1beta1/validatorsets/1" + blocksLatestPath = "/cosmos/base/tendermint/v1beta1/blocks/latest" + blocksHeightPath = "/cosmos/base/tendermint/v1beta1/blocks/1" + syncingPath = "/cosmos/base/tendermint/v1beta1/syncing" + nodeInfoPath = "/cosmos/base/tendermint/v1beta1/node_info" + transactionsPath = "/cosmos/tx/v1beta1/txs?events=tx.height=9999999999" + bankTotalModuleQueryPath = "/cosmos/bank/v1beta1/supply" + authParamsModuleQueryPath = "/cosmos/auth/v1beta1/params" + distributionCommPoolModuleQueryPath = "/cosmos/distribution/v1beta1/community_pool" + evidenceModuleQueryPath = "/cosmos/evidence/v1beta1/evidence" + govPropsModuleQueryPath = "/cosmos/gov/v1beta1/proposals" + mintParamsModuleQueryPath = "/cosmos/mint/v1beta1/params" + slashingParamsModuleQueryPath = "/cosmos/slashing/v1beta1/params" + stakingParamsModuleQueryPath = "/cosmos/staking/v1beta1/params" + missingPath = "/missing_endpoint" +) + +func (s *IntegrationTestSuite) testRestInterfaces() { + s.Run("test rest interfaces", func() { + var ( + valIdx = 0 + c = s.chainA + endpointURL = fmt.Sprintf("http://%s", s.valResources[c.id][valIdx].GetHostPort("1317/tcp")) + testEndpoints = []struct { + Path string + ExpectedStatus int + }{ + // Client Endpoints + {nodeInfoPath, 200}, + {syncingPath, 200}, + {valSetLatestPath, 200}, + {valSetHeightPath, 200}, + {blocksLatestPath, 200}, + {blocksHeightPath, 200}, + {transactionsPath, 200}, + // Module Endpoints + {bankTotalModuleQueryPath, 200}, + {authParamsModuleQueryPath, 200}, + {distributionCommPoolModuleQueryPath, 200}, + {evidenceModuleQueryPath, 200}, + {govPropsModuleQueryPath, 200}, + {mintParamsModuleQueryPath, 200}, + {slashingParamsModuleQueryPath, 200}, + {stakingParamsModuleQueryPath, 200}, + {missingPath, 501}, + } + ) + + for _, endpoint := range testEndpoints { + resp, err := http.Get(fmt.Sprintf("%s%s", endpointURL, endpoint.Path)) + s.NoError(err, fmt.Sprintf("failed to get endpoint: %s%s", endpointURL, endpoint.Path)) + + _, err = readJSON(resp) + s.NoError(err, fmt.Sprintf("failed to read body of endpoint: %s%s", endpointURL, endpoint.Path)) + + s.EqualValues(resp.StatusCode, endpoint.ExpectedStatus, fmt.Sprintf("invalid status from endpoint: : %s%s", endpointURL, endpoint.Path)) + } + }) +} diff --git a/tests/e2e/e2e_setup_test.go b/tests/e2e/e2e_setup_test.go index 34c1c166bad..dac245a6ae6 100644 --- a/tests/e2e/e2e_setup_test.go +++ b/tests/e2e/e2e_setup_test.go @@ -1,766 +1,603 @@ package e2e -// import ( -// "context" -// "encoding/json" -// "fmt" -// "io" -// "net/http" -// "os" -// "os/exec" -// "path" -// "path/filepath" -// "strconv" -// "strings" -// "testing" -// "time" - -// ccvprovider "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" - -// codectypes "github.com/cosmos/cosmos-sdk/codec/types" -// "github.com/cosmos/cosmos-sdk/crypto/hd" -// "github.com/cosmos/cosmos-sdk/crypto/keyring" -// "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" -// "github.com/cosmos/cosmos-sdk/server" -// srvconfig "github.com/cosmos/cosmos-sdk/server/config" -// sdk "github.com/cosmos/cosmos-sdk/types" -// authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" -// authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" -// banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" -// distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" -// evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" -// genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" -// stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" -// ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" -// "github.com/ory/dockertest/v3" -// "github.com/ory/dockertest/v3/docker" -// "github.com/spf13/viper" -// "github.com/stretchr/testify/suite" -// tmconfig "github.com/tendermint/tendermint/config" -// tmjson "github.com/tendermint/tendermint/libs/json" -// "github.com/tendermint/tendermint/libs/rand" -// rpchttp "github.com/tendermint/tendermint/rpc/client/http" -// ) - -// const ( -// gaiadBinary = "gaiad" -// txCommand = "tx" -// queryCommand = "query" -// keysCommand = "keys" -// gaiaHomePath = "/home/nonroot/.gaia" -// photonDenom = "photon" -// uatomDenom = "uatom" -// stakeDenom = "stake" -// initBalanceStr = "110000000000stake,100000000000000000photon,100000000000000000uatom" -// minGasPrice = "0.00001" -// // the test globalfee in genesis is the same as minGasPrice -// // global fee lower/higher than min_gas_price -// initialGlobalFeeAmt = "0.00001" -// lowGlobalFeesAmt = "0.000001" -// highGlobalFeeAmt = "0.0001" -// maxTotalBypassMinFeeMsgGasUsage = "1" -// gas = 200000 -// govProposalBlockBuffer = 35 -// relayerAccountIndexHermes0 = 0 -// relayerAccountIndexHermes1 = 1 -// numberOfEvidences = 10 -// slashingShares int64 = 10000 - -// proposalGlobalFeeFilename = "proposal_globalfee.json" -// proposalBypassMsgFilename = "proposal_bypass_msg.json" -// proposalMaxTotalBypassFilename = "proposal_max_total_bypass.json" -// proposalCommunitySpendFilename = "proposal_community_spend.json" -// proposalAddConsumerChainFilename = "proposal_add_consumer.json" -// proposalRemoveConsumerChainFilename = "proposal_remove_consumer.json" - -// hermesBinary = "hermes" -// hermesConfigWithGasPrices = "/root/.hermes/config.toml" -// hermesConfigNoGasPrices = "/root/.hermes/config-zero.toml" -// transferChannel = "channel-0" -// ) - -// var ( -// gaiaConfigPath = filepath.Join(gaiaHomePath, "config") -// stakingAmount = sdk.NewInt(100000000000) -// stakingAmountCoin = sdk.NewCoin(uatomDenom, stakingAmount) -// tokenAmount = sdk.NewCoin(uatomDenom, sdk.NewInt(3300000000)) // 3,300uatom -// standardFees = sdk.NewCoin(uatomDenom, sdk.NewInt(330000)) // 0.33uatom -// depositAmount = sdk.NewCoin(uatomDenom, sdk.NewInt(330000000)) // 3,300uatom -// distModuleAddress = authtypes.NewModuleAddress(distrtypes.ModuleName).String() -// proposalCounter = 0 -// HermesResource0Purged = false -// ) - -// type IntegrationTestSuite struct { -// suite.Suite - -// tmpDirs []string -// chainA *chain -// chainB *chain -// dkrPool *dockertest.Pool -// dkrNet *dockertest.Network -// hermesResource0 *dockertest.Resource -// hermesResource1 *dockertest.Resource - -// valResources map[string][]*dockertest.Resource -// } - -// type AddressResponse struct { -// Name string `json:"name"` -// Type string `json:"type"` -// Address string `json:"address"` -// Mnemonic string `json:"mnemonic"` -// } - -// func TestIntegrationTestSuite(t *testing.T) { -// suite.Run(t, new(IntegrationTestSuite)) -// } - -// func (s *IntegrationTestSuite) SetupSuite() { -// s.T().Log("setting up e2e integration test suite...") - -// var err error -// s.chainA, err = newChain() -// s.Require().NoError(err) - -// s.chainB, err = newChain() -// s.Require().NoError(err) - -// s.dkrPool, err = dockertest.NewPool("") -// s.Require().NoError(err) - -// s.dkrNet, err = s.dkrPool.CreateNetwork(fmt.Sprintf("%s-%s-testnet", s.chainA.id, s.chainB.id)) -// s.Require().NoError(err) - -// s.valResources = make(map[string][]*dockertest.Resource) - -// vestingMnemonic, err := createMnemonic() -// s.Require().NoError(err) - -// jailedValMnemonic, err := createMnemonic() -// s.Require().NoError(err) - -// // The boostrapping phase is as follows: -// // -// // 1. Initialize Gaia validator nodes. -// // 2. Create and initialize Gaia validator genesis files (both chains) -// // 3. Start both networks. -// // 4. Create and run IBC relayer (Hermes) containers. - -// s.T().Logf("starting e2e infrastructure for chain A; chain-id: %s; datadir: %s", s.chainA.id, s.chainA.dataDir) -// s.initNodes(s.chainA) -// s.initGenesis(s.chainA, vestingMnemonic, jailedValMnemonic) -// s.initValidatorConfigs(s.chainA) -// s.runValidators(s.chainA, 0) - -// s.T().Logf("starting e2e infrastructure for chain B; chain-id: %s; datadir: %s", s.chainB.id, s.chainB.dataDir) -// s.initNodes(s.chainB) -// s.initGenesis(s.chainB, vestingMnemonic, jailedValMnemonic) -// s.initValidatorConfigs(s.chainB) -// s.runValidators(s.chainB, 10) - -// time.Sleep(10 * time.Second) -// s.runIBCRelayer0() -// s.runIBCRelayer1() -// } - -// func (s *IntegrationTestSuite) TearDownSuite() { -// if str := os.Getenv("GAIA_E2E_SKIP_CLEANUP"); len(str) > 0 { -// skipCleanup, err := strconv.ParseBool(str) -// s.Require().NoError(err) - -// if skipCleanup { -// return -// } -// } - -// s.T().Log("tearing down e2e integration test suite...") - -// s.Require().NoError(s.dkrPool.Purge(s.hermesResource1)) -// // if runIBCTest, s.hermesResource0 already purged in TestIBC() -// // in GovSoftwareUpgrade test, s.TearDownSuite() then s.SetupSuite() -// // if IBCTest runs before GovSoftwareUpgrade, s.hermesResource0 is already purged. -// if !HermesResource0Purged { -// s.Require().NoError(s.dkrPool.Purge(s.hermesResource0)) -// } - -// for _, vr := range s.valResources { -// for _, r := range vr { -// s.Require().NoError(s.dkrPool.Purge(r)) -// } -// } - -// s.Require().NoError(s.dkrPool.RemoveNetwork(s.dkrNet)) - -// os.RemoveAll(s.chainA.dataDir) -// os.RemoveAll(s.chainB.dataDir) - -// for _, td := range s.tmpDirs { -// os.RemoveAll(td) -// } -// } - -// func (s *IntegrationTestSuite) initNodes(c *chain) { -// s.Require().NoError(c.createAndInitValidators(2)) -// /* Adding 4 accounts to val0 local directory -// c.genesisAccounts[0]: Relayer0 Wallet -// c.genesisAccounts[1]: ICA Owner -// c.genesisAccounts[2]: Test Account 1 -// c.genesisAccounts[3]: Test Account 2 -// c.genesisAccounts[4]: Relayer1 Wallet -// */ -// s.Require().NoError(c.addAccountFromMnemonic(5)) -// // Initialize a genesis file for the first validator -// val0ConfigDir := c.validators[0].configDir() -// var addrAll []sdk.AccAddress -// for _, val := range c.validators { -// address := val.keyInfo.GetAddress() -// addrAll = append(addrAll, address) -// } - -// for _, addr := range c.genesisAccounts { -// acctAddr := addr.keyInfo.GetAddress() -// addrAll = append(addrAll, acctAddr) -// } - -// s.Require().NoError( -// modifyGenesis(val0ConfigDir, "", initBalanceStr, addrAll, initialGlobalFeeAmt+uatomDenom, uatomDenom), -// ) -// // copy the genesis file to the remaining validators -// for _, val := range c.validators[1:] { -// _, err := copyFile( -// filepath.Join(val0ConfigDir, "config", "genesis.json"), -// filepath.Join(val.configDir(), "config", "genesis.json"), -// ) -// s.Require().NoError(err) -// } -// } - -// // TODO find a better way to manipulate accounts to add genesis accounts -// func (s *IntegrationTestSuite) addGenesisVestingAndJailedAccounts( -// c *chain, -// valConfigDir, -// vestingMnemonic, -// jailedValMnemonic string, -// appGenState map[string]json.RawMessage, -// ) map[string]json.RawMessage { -// var ( -// authGenState = authtypes.GetGenesisStateFromAppState(cdc, appGenState) -// bankGenState = banktypes.GetGenesisStateFromAppState(cdc, appGenState) -// stakingGenState = stakingtypes.GetGenesisStateFromAppState(cdc, appGenState) -// ) - -// // create genesis vesting accounts keys -// kb, err := keyring.New(keyringAppName, keyring.BackendTest, valConfigDir, nil) -// s.Require().NoError(err) - -// keyringAlgos, _ := kb.SupportedAlgorithms() -// algo, err := keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), keyringAlgos) -// s.Require().NoError(err) - -// // create jailed validator account keys -// jailedValKey, err := kb.NewAccount(jailedValidatorKey, jailedValMnemonic, "", sdk.FullFundraiserPath, algo) -// s.Require().NoError(err) - -// // create genesis vesting accounts keys -// c.genesisVestingAccounts = make(map[string]sdk.AccAddress) -// for i, key := range genesisVestingKeys { -// // Use the first wallet from the same mnemonic by HD path -// acc, err := kb.NewAccount(key, vestingMnemonic, "", HDPath(i), algo) -// s.Require().NoError(err) -// c.genesisVestingAccounts[key] = acc.GetAddress() -// s.T().Logf("created %s genesis account %s\n", key, c.genesisVestingAccounts[key].String()) -// } -// var ( -// continuousVestingAcc = c.genesisVestingAccounts[continuousVestingKey] -// delayedVestingAcc = c.genesisVestingAccounts[delayedVestingKey] -// ) - -// // add jailed validator to staking store -// pubKey := jailedValKey.GetPubKey() -// jailedValAcc := jailedValKey.GetAddress() -// jailedValAddr := sdk.ValAddress(jailedValAcc) -// val, err := stakingtypes.NewValidator( -// jailedValAddr, -// pubKey, -// stakingtypes.NewDescription("jailed", "", "", "", ""), -// ) -// s.Require().NoError(err) -// val.Jailed = true -// val.Tokens = sdk.NewInt(slashingShares) -// val.DelegatorShares = sdk.NewDec(slashingShares) -// stakingGenState.Validators = append(stakingGenState.Validators, val) - -// // add jailed validator delegations -// stakingGenState.Delegations = append(stakingGenState.Delegations, stakingtypes.Delegation{ -// DelegatorAddress: jailedValAcc.String(), -// ValidatorAddress: jailedValAddr.String(), -// Shares: sdk.NewDec(slashingShares), -// }) - -// appGenState[stakingtypes.ModuleName], err = cdc.MarshalJSON(stakingGenState) -// s.Require().NoError(err) - -// // add jailed account to the genesis -// baseJailedAccount := authtypes.NewBaseAccount(jailedValAcc, pubKey, 0, 0) -// s.Require().NoError(baseJailedAccount.Validate()) - -// // add continuous vesting account to the genesis -// baseVestingContinuousAccount := authtypes.NewBaseAccount( -// continuousVestingAcc, nil, 0, 0) -// vestingContinuousGenAccount := authvesting.NewContinuousVestingAccountRaw( -// authvesting.NewBaseVestingAccount( -// baseVestingContinuousAccount, -// sdk.NewCoins(vestingAmountVested), -// time.Now().Add(time.Duration(rand.Intn(80)+150)*time.Second).Unix(), -// ), -// time.Now().Add(time.Duration(rand.Intn(40)+90)*time.Second).Unix(), -// ) -// s.Require().NoError(vestingContinuousGenAccount.Validate()) - -// // add delayed vesting account to the genesis -// baseVestingDelayedAccount := authtypes.NewBaseAccount( -// delayedVestingAcc, nil, 0, 0) -// vestingDelayedGenAccount := authvesting.NewDelayedVestingAccountRaw( -// authvesting.NewBaseVestingAccount( -// baseVestingDelayedAccount, -// sdk.NewCoins(vestingAmountVested), -// time.Now().Add(time.Duration(rand.Intn(40)+90)*time.Second).Unix(), -// ), -// ) -// s.Require().NoError(vestingDelayedGenAccount.Validate()) - -// // unpack and append accounts -// accs, err := authtypes.UnpackAccounts(authGenState.Accounts) -// s.Require().NoError(err) -// accs = append(accs, vestingContinuousGenAccount, vestingDelayedGenAccount, baseJailedAccount) -// accs = authtypes.SanitizeGenesisAccounts(accs) -// genAccs, err := authtypes.PackAccounts(accs) -// s.Require().NoError(err) -// authGenState.Accounts = genAccs - -// // update auth module state -// appGenState[authtypes.ModuleName], err = cdc.MarshalJSON(&authGenState) -// s.Require().NoError(err) - -// // update balances -// vestingContinuousBalances := banktypes.Balance{ -// Address: continuousVestingAcc.String(), -// Coins: vestingBalance, -// } -// vestingDelayedBalances := banktypes.Balance{ -// Address: delayedVestingAcc.String(), -// Coins: vestingBalance, -// } -// jailedValidatorBalances := banktypes.Balance{ -// Address: jailedValAcc.String(), -// Coins: sdk.NewCoins(tokenAmount), -// } -// stakingModuleBalances := banktypes.Balance{ -// Address: authtypes.NewModuleAddress(stakingtypes.NotBondedPoolName).String(), -// Coins: sdk.NewCoins(sdk.NewCoin(uatomDenom, sdk.NewInt(slashingShares))), -// } -// bankGenState.Balances = append( -// bankGenState.Balances, -// vestingContinuousBalances, -// vestingDelayedBalances, -// jailedValidatorBalances, -// stakingModuleBalances, -// ) -// bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances) - -// // update the denom metadata for the bank module -// bankGenState.DenomMetadata = append(bankGenState.DenomMetadata, banktypes.Metadata{ -// Description: "An example stable token", -// Display: uatomDenom, -// Base: uatomDenom, -// Symbol: uatomDenom, -// Name: uatomDenom, -// DenomUnits: []*banktypes.DenomUnit{ -// { -// Denom: uatomDenom, -// Exponent: 0, -// }, -// }, -// }) - -// // update bank module state -// appGenState[banktypes.ModuleName], err = cdc.MarshalJSON(bankGenState) -// s.Require().NoError(err) - -// return appGenState -// } - -// func (s *IntegrationTestSuite) initGenesis(c *chain, vestingMnemonic, jailedValMnemonic string) { -// var ( -// serverCtx = server.NewDefaultContext() -// config = serverCtx.Config -// validator = c.validators[0] -// ) - -// config.SetRoot(validator.configDir()) -// config.Moniker = validator.moniker - -// genFilePath := config.GenesisFile() -// appGenState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFilePath) -// s.Require().NoError(err) - -// appGenState = s.addGenesisVestingAndJailedAccounts( -// c, -// validator.configDir(), -// vestingMnemonic, -// jailedValMnemonic, -// appGenState, -// ) - -// var evidenceGenState evidencetypes.GenesisState -// s.Require().NoError(cdc.UnmarshalJSON(appGenState[evidencetypes.ModuleName], &evidenceGenState)) - -// evidenceGenState.Evidence = make([]*codectypes.Any, numberOfEvidences) -// for i := range evidenceGenState.Evidence { -// pk := ed25519.GenPrivKey() -// evidence := &evidencetypes.Equivocation{ -// Height: 1, -// Power: 100, -// Time: time.Now().UTC(), -// ConsensusAddress: sdk.ConsAddress(pk.PubKey().Address().Bytes()).String(), -// } -// evidenceGenState.Evidence[i], err = codectypes.NewAnyWithValue(evidence) -// s.Require().NoError(err) -// } - -// appGenState[evidencetypes.ModuleName], err = cdc.MarshalJSON(&evidenceGenState) -// s.Require().NoError(err) - -// var genUtilGenState genutiltypes.GenesisState -// s.Require().NoError(cdc.UnmarshalJSON(appGenState[genutiltypes.ModuleName], &genUtilGenState)) - -// // generate genesis txs -// genTxs := make([]json.RawMessage, len(c.validators)) -// for i, val := range c.validators { -// createValmsg, err := val.buildCreateValidatorMsg(stakingAmountCoin) -// s.Require().NoError(err) -// signedTx, err := val.signMsg(createValmsg) - -// s.Require().NoError(err) - -// txRaw, err := cdc.MarshalJSON(signedTx) -// s.Require().NoError(err) - -// genTxs[i] = txRaw -// } - -// genUtilGenState.GenTxs = genTxs - -// appGenState[genutiltypes.ModuleName], err = cdc.MarshalJSON(&genUtilGenState) -// s.Require().NoError(err) - -// genDoc.AppState, err = json.MarshalIndent(appGenState, "", " ") -// s.Require().NoError(err) - -// bz, err := tmjson.MarshalIndent(genDoc, "", " ") -// s.Require().NoError(err) - -// vestingPeriod, err := generateVestingPeriod() -// s.Require().NoError(err) - -// rawTx, _, err := buildRawTx() -// s.Require().NoError(err) - -// // write the updated genesis file to each validator. -// for _, val := range c.validators { -// err = writeFile(filepath.Join(val.configDir(), "config", "genesis.json"), bz) -// s.Require().NoError(err) - -// err = writeFile(filepath.Join(val.configDir(), vestingPeriodFile), vestingPeriod) -// s.Require().NoError(err) - -// err = writeFile(filepath.Join(val.configDir(), rawTxFile), rawTx) -// s.Require().NoError(err) -// } -// } - -// // initValidatorConfigs initializes the validator configs for the given chain. -// func (s *IntegrationTestSuite) initValidatorConfigs(c *chain) { -// for i, val := range c.validators { -// tmCfgPath := filepath.Join(val.configDir(), "config", "config.toml") - -// vpr := viper.New() -// vpr.SetConfigFile(tmCfgPath) -// s.Require().NoError(vpr.ReadInConfig()) - -// valConfig := tmconfig.DefaultConfig() - -// s.Require().NoError(vpr.Unmarshal(valConfig)) - -// valConfig.P2P.ListenAddress = "tcp://0.0.0.0:26656" -// valConfig.P2P.AddrBookStrict = false -// valConfig.P2P.ExternalAddress = fmt.Sprintf("%s:%d", val.instanceName(), 26656) -// valConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657" -// valConfig.StateSync.Enable = false -// valConfig.LogLevel = "info" - -// var peers []string - -// for j := 0; j < len(c.validators); j++ { -// if i == j { -// continue -// } - -// peer := c.validators[j] -// peerID := fmt.Sprintf("%s@%s%d:26656", peer.nodeKey.ID(), peer.moniker, j) -// peers = append(peers, peerID) -// } - -// valConfig.P2P.PersistentPeers = strings.Join(peers, ",") - -// tmconfig.WriteConfigFile(tmCfgPath, valConfig) - -// // set application configuration -// appCfgPath := filepath.Join(val.configDir(), "config", "app.toml") - -// appConfig := srvconfig.DefaultConfig() -// appConfig.API.Enable = true -// appConfig.MinGasPrices = fmt.Sprintf("%s%s", minGasPrice, uatomDenom) - -// srvconfig.SetConfigTemplate(srvconfig.DefaultConfigTemplate) -// srvconfig.WriteConfigFile(appCfgPath, appConfig) -// } -// } - -// // runValidators runs the validators in the chain -// func (s *IntegrationTestSuite) runValidators(c *chain, portOffset int) { -// s.T().Logf("starting Gaia %s validator containers...", c.id) - -// s.valResources[c.id] = make([]*dockertest.Resource, len(c.validators)) -// for i, val := range c.validators { -// runOpts := &dockertest.RunOptions{ -// Name: val.instanceName(), -// NetworkID: s.dkrNet.Network.ID, -// Mounts: []string{ -// fmt.Sprintf("%s/:%s", val.configDir(), gaiaHomePath), -// }, -// Repository: "cosmos/gaiad-e2e", -// } - -// s.Require().NoError(exec.Command("chmod", "-R", "0777", val.configDir()).Run()) //nolint:gosec // this is a test - -// // expose the first validator for debugging and communication -// if val.index == 0 { -// runOpts.PortBindings = map[docker.Port][]docker.PortBinding{ -// "1317/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 1317+portOffset)}}, -// "6060/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6060+portOffset)}}, -// "6061/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6061+portOffset)}}, -// "6062/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6062+portOffset)}}, -// "6063/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6063+portOffset)}}, -// "6064/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6064+portOffset)}}, -// "6065/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6065+portOffset)}}, -// "9090/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 9090+portOffset)}}, -// "26656/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 26656+portOffset)}}, -// "26657/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 26657+portOffset)}}, -// } -// } - -// resource, err := s.dkrPool.RunWithOptions(runOpts, noRestart) -// s.Require().NoError(err) - -// s.valResources[c.id][i] = resource -// s.T().Logf("started Gaia %s validator container: %s", c.id, resource.Container.ID) -// } - -// rpcClient, err := rpchttp.New("tcp://localhost:26657", "/websocket") -// s.Require().NoError(err) - -// s.Require().Eventually( -// func() bool { -// ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) -// defer cancel() - -// status, err := rpcClient.Status(ctx) -// if err != nil { -// return false -// } - -// // let the node produce a few blocks -// if status.SyncInfo.CatchingUp || status.SyncInfo.LatestBlockHeight < 3 { -// return false -// } - -// return true -// }, -// 5*time.Minute, -// time.Second, -// "Gaia node failed to produce blocks", -// ) -// } - -// func noRestart(config *docker.HostConfig) { -// // in this case we don't want the nodes to restart on failure -// config.RestartPolicy = docker.RestartPolicy{ -// Name: "no", -// } -// } - -// // hermes0 is for ibc and packet-forward-middleware(PFM) test, hermes0 is keep running during the ibc and PFM test. -// func (s *IntegrationTestSuite) runIBCRelayer0() { -// s.T().Log("starting Hermes relayer container 0...") - -// tmpDir, err := os.MkdirTemp("", "gaia-e2e-testnet-hermes-") -// s.Require().NoError(err) -// s.tmpDirs = append(s.tmpDirs, tmpDir) - -// gaiaAVal := s.chainA.validators[0] -// gaiaBVal := s.chainB.validators[0] - -// gaiaARly := s.chainA.genesisAccounts[relayerAccountIndexHermes0] -// gaiaBRly := s.chainB.genesisAccounts[relayerAccountIndexHermes0] - -// hermesCfgPath := path.Join(tmpDir, "hermes") - -// s.Require().NoError(os.MkdirAll(hermesCfgPath, 0o755)) -// _, err = copyFile( -// filepath.Join("./scripts/", "hermes_bootstrap.sh"), -// filepath.Join(hermesCfgPath, "hermes_bootstrap.sh"), -// ) -// s.Require().NoError(err) - -// s.hermesResource0, err = s.dkrPool.RunWithOptions( -// &dockertest.RunOptions{ -// Name: fmt.Sprintf("%s-%s-relayer-0", s.chainA.id, s.chainB.id), -// Repository: "ghcr.io/cosmos/hermes-e2e", -// Tag: "1.0.0", -// NetworkID: s.dkrNet.Network.ID, -// Mounts: []string{ -// fmt.Sprintf("%s/:/root/hermes", hermesCfgPath), -// }, -// PortBindings: map[docker.Port][]docker.PortBinding{ -// "3031/tcp": {{HostIP: "", HostPort: "3031"}}, -// }, -// Env: []string{ -// fmt.Sprintf("GAIA_A_E2E_CHAIN_ID=%s", s.chainA.id), -// fmt.Sprintf("GAIA_B_E2E_CHAIN_ID=%s", s.chainB.id), -// fmt.Sprintf("GAIA_A_E2E_VAL_MNEMONIC=%s", gaiaAVal.mnemonic), -// fmt.Sprintf("GAIA_B_E2E_VAL_MNEMONIC=%s", gaiaBVal.mnemonic), -// fmt.Sprintf("GAIA_A_E2E_RLY_MNEMONIC=%s", gaiaARly.mnemonic), -// fmt.Sprintf("GAIA_B_E2E_RLY_MNEMONIC=%s", gaiaBRly.mnemonic), -// fmt.Sprintf("GAIA_A_E2E_VAL_HOST=%s", s.valResources[s.chainA.id][0].Container.Name[1:]), -// fmt.Sprintf("GAIA_B_E2E_VAL_HOST=%s", s.valResources[s.chainB.id][0].Container.Name[1:]), -// }, -// Entrypoint: []string{ -// "sh", -// "-c", -// "chmod +x /root/hermes/hermes_bootstrap.sh && /root/hermes/hermes_bootstrap.sh", -// }, -// }, -// noRestart, -// ) -// s.Require().NoError(err) - -// endpoint := fmt.Sprintf("http://%s/state", s.hermesResource0.GetHostPort("3031/tcp")) -// s.Require().Eventually( -// func() bool { -// resp, err := http.Get(endpoint) //nolint:gosec // this is a test -// if err != nil { -// return false -// } - -// defer resp.Body.Close() - -// bz, err := io.ReadAll(resp.Body) -// if err != nil { -// return false -// } - -// var respBody map[string]interface{} -// if err := json.Unmarshal(bz, &respBody); err != nil { -// return false -// } - -// status := respBody["status"].(string) -// result := respBody["result"].(map[string]interface{}) - -// return status == "success" && len(result["chains"].([]interface{})) == 2 -// }, -// 5*time.Minute, -// time.Second, -// "hermes relayer not healthy", -// ) - -// s.T().Logf("started Hermes relayer 0 container: %s", s.hermesResource0.Container.ID) - -// // XXX: Give time to both networks to start, otherwise we might see gRPC -// // transport errors. -// time.Sleep(10 * time.Second) - -// // create the client, connection and channel between the two Gaia chains -// s.createConnection() -// time.Sleep(10 * time.Second) -// s.createChannel() -// } - -// // hermes1 is for bypass-msg test. Hermes1 is to process asynchronous transactions, -// // Hermes1 has access to two Hermes configurations: one configuration allows paying fees, while the other does not. -// // With Hermes1, better control can be achieved regarding whether fees are paid when clearing transactions. -// func (s *IntegrationTestSuite) runIBCRelayer1() { -// s.T().Log("starting Hermes relayer container 1...") - -// tmpDir, err := os.MkdirTemp("", "gaia-e2e-testnet-hermes-") -// s.Require().NoError(err) -// s.tmpDirs = append(s.tmpDirs, tmpDir) - -// gaiaAVal := s.chainA.validators[0] -// gaiaBVal := s.chainB.validators[0] - -// gaiaARly := s.chainA.genesisAccounts[relayerAccountIndexHermes1] -// gaiaBRly := s.chainB.genesisAccounts[relayerAccountIndexHermes1] - -// hermesCfgPath := path.Join(tmpDir, "hermes") - -// s.Require().NoError(os.MkdirAll(hermesCfgPath, 0o755)) -// _, err = copyFile( -// filepath.Join("./scripts/", "hermes1_bootstrap.sh"), -// filepath.Join(hermesCfgPath, "hermes1_bootstrap.sh"), -// ) -// s.Require().NoError(err) - -// s.hermesResource1, err = s.dkrPool.RunWithOptions( -// &dockertest.RunOptions{ -// Name: fmt.Sprintf("%s-%s-relayer-1", s.chainA.id, s.chainB.id), -// Repository: "ghcr.io/cosmos/hermes-e2e", -// Tag: "1.0.0", -// NetworkID: s.dkrNet.Network.ID, -// Mounts: []string{ -// fmt.Sprintf("%s/:/root/hermes", hermesCfgPath), -// }, -// PortBindings: map[docker.Port][]docker.PortBinding{ -// "3032/tcp": {{HostIP: "", HostPort: "3032"}}, -// }, -// Env: []string{ -// fmt.Sprintf("GAIA_A_E2E_CHAIN_ID=%s", s.chainA.id), -// fmt.Sprintf("GAIA_B_E2E_CHAIN_ID=%s", s.chainB.id), -// fmt.Sprintf("GAIA_A_E2E_VAL_MNEMONIC=%s", gaiaAVal.mnemonic), -// fmt.Sprintf("GAIA_B_E2E_VAL_MNEMONIC=%s", gaiaBVal.mnemonic), -// fmt.Sprintf("GAIA_A_E2E_RLY_MNEMONIC=%s", gaiaARly.mnemonic), -// fmt.Sprintf("GAIA_B_E2E_RLY_MNEMONIC=%s", gaiaBRly.mnemonic), -// fmt.Sprintf("GAIA_A_E2E_VAL_HOST=%s", s.valResources[s.chainA.id][0].Container.Name[1:]), -// fmt.Sprintf("GAIA_B_E2E_VAL_HOST=%s", s.valResources[s.chainB.id][0].Container.Name[1:]), -// }, -// Entrypoint: []string{ -// "sh", -// "-c", -// "chmod +x /root/hermes/hermes1_bootstrap.sh && /root/hermes/hermes1_bootstrap.sh && tail -f /dev/null", -// }, -// }, -// noRestart, -// ) -// s.Require().NoError(err) - -// s.T().Logf("started Hermes relayer 1 container: %s", s.hermesResource1.Container.ID) - -// // XXX: Give time to both networks to start, otherwise we might see gRPC -// // transport errors. -// time.Sleep(10 * time.Second) -// } +import ( + "context" + "encoding/json" + "fmt" + "math/rand" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "testing" + "time" + + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + tmconfig "github.com/cometbft/cometbft/config" + "github.com/cometbft/cometbft/crypto/ed25519" + tmjson "github.com/cometbft/cometbft/libs/json" + rpchttp "github.com/cometbft/cometbft/rpc/client/http" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/server" + srvconfig "github.com/cosmos/cosmos-sdk/server/config" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/ory/dockertest/v3" + "github.com/stretchr/testify/suite" + + // // ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + // "github.com/cosmos/cosmos-sdk/crypto/hd" + // "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/ory/dockertest/v3/docker" + "github.com/spf13/viper" +) + +const ( + gaiadBinary = "gaiad" + txCommand = "tx" + queryCommand = "query" + keysCommand = "keys" + gaiaHomePath = "/home/nonroot/.gaia" + // photonDenom = "photon" + uatomDenom = "uatom" + stakeDenom = "stake" + initBalanceStr = "110000000000stake,100000000000000000photon,100000000000000000uatom" + minGasPrice = "0.00001" + // // the test globalfee in genesis is the same as minGasPrice + // // global fee lower/higher than min_gas_price + initialGlobalFeeAmt = "0.00001" + // lowGlobalFeesAmt = "0.000001" + // highGlobalFeeAmt = "0.0001" + // maxTotalBypassMinFeeMsgGasUsage = "1" + gas = 200000 + + govProposalBlockBuffer = 35 + relayerAccountIndex = 0 + numberOfEvidences = 10 + slashingShares int64 = 10000 + + // proposalGlobalFeeFilename = "proposal_globalfee.json" + // proposalBypassMsgFilename = "proposal_bypass_msg.json" + // proposalMaxTotalBypassFilename = "proposal_max_total_bypass.json" + proposalCommunitySpendFilename = "proposal_community_spend.json" + +// proposalAddConsumerChainFilename = "proposal_add_consumer.json" +// proposalRemoveConsumerChainFilename = "proposal_remove_consumer.json" +) + +var ( + gaiaConfigPath = filepath.Join(gaiaHomePath, "config") + stakingAmount = sdk.NewInt(100000000000) + stakingAmountCoin = sdk.NewCoin(uatomDenom, stakingAmount) + tokenAmount = sdk.NewCoin(uatomDenom, sdk.NewInt(3300000000)) // 3,300uatom + standardFees = sdk.NewCoin(uatomDenom, sdk.NewInt(330000)) // 0.33uatom + depositAmount = sdk.NewCoin(uatomDenom, sdk.NewInt(330000000)) // 3,300uatom + distModuleAddress = authtypes.NewModuleAddress(distrtypes.ModuleName).String() + govModuleAddress = authtypes.NewModuleAddress(govtypes.ModuleName).String() + proposalCounter = 0 +) + +type IntegrationTestSuite struct { + suite.Suite + tmpDirs []string + chainA *chain + chainB *chain + dkrPool *dockertest.Pool + dkrNet *dockertest.Network + hermesResource *dockertest.Resource + valResources map[string][]*dockertest.Resource +} + +type AddressResponse struct { + Name string `json:"name"` + Type string `json:"type"` + Address string `json:"address"` + Mnemonic string `json:"mnemonic"` +} + +func TestIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} + +func (s *IntegrationTestSuite) SetupSuite() { + s.T().Log("setting up e2e integration test suite...") + + var err error + s.chainA, err = newChain() + s.Require().NoError(err) + + s.chainB, err = newChain() + s.Require().NoError(err) + + s.dkrPool, err = dockertest.NewPool("") + s.Require().NoError(err) + + s.dkrNet, err = s.dkrPool.CreateNetwork(fmt.Sprintf("%s-%s-testnet", s.chainA.id, s.chainB.id)) + s.Require().NoError(err) + + s.valResources = make(map[string][]*dockertest.Resource) + + vestingMnemonic, err := createMnemonic() + s.Require().NoError(err) + + jailedValMnemonic, err := createMnemonic() + s.Require().NoError(err) + + // The boostrapping phase is as follows: + // + // 1. Initialize Gaia validator nodes. + // 2. Create and initialize Gaia validator genesis files (both chains) + // 3. Start both networks. + // 4. Create and run IBC relayer (Hermes) containers. + + s.T().Logf("starting e2e infrastructure for chain A; chain-id: %s; datadir: %s", s.chainA.id, s.chainA.dataDir) + s.initNodes(s.chainA) + s.initGenesis(s.chainA, vestingMnemonic, jailedValMnemonic) + s.initValidatorConfigs(s.chainA) + s.runValidators(s.chainA, 0) + + s.T().Logf("starting e2e infrastructure for chain B; chain-id: %s; datadir: %s", s.chainB.id, s.chainB.dataDir) + s.initNodes(s.chainB) + s.initGenesis(s.chainB, vestingMnemonic, jailedValMnemonic) + s.initValidatorConfigs(s.chainB) + s.runValidators(s.chainB, 10) + + time.Sleep(10 * time.Second) + s.runIBCRelayer() +} + +func (s *IntegrationTestSuite) TearDownSuite() { + if str := os.Getenv("GAIA_E2E_SKIP_CLEANUP"); len(str) > 0 { + skipCleanup, err := strconv.ParseBool(str) + s.Require().NoError(err) + + if skipCleanup { + return + } + } + + s.T().Log("tearing down e2e integration test suite...") + + if runIBCTest { + s.Require().NoError(s.dkrPool.Purge(s.hermesResource)) + } + + for _, vr := range s.valResources { + for _, r := range vr { + s.Require().NoError(s.dkrPool.Purge(r)) + } + } + + s.Require().NoError(s.dkrPool.RemoveNetwork(s.dkrNet)) + + os.RemoveAll(s.chainA.dataDir) + os.RemoveAll(s.chainB.dataDir) + + for _, td := range s.tmpDirs { + os.RemoveAll(td) + } +} + +func (s *IntegrationTestSuite) initNodes(c *chain) { + s.Require().NoError(c.createAndInitValidators(2)) + /* Adding 4 accounts to val0 local directory + c.genesisAccounts[0]: Relayer Wallet + c.genesisAccounts[1]: ICA Owner + c.genesisAccounts[2]: Test Account 1 + c.genesisAccounts[3]: Test Account 2 + */ + s.Require().NoError(c.addAccountFromMnemonic(4)) + // Initialize a genesis file for the first validator + val0ConfigDir := c.validators[0].configDir() + var addrAll []sdk.AccAddress + for _, val := range c.validators { + addr, err := val.keyInfo.GetAddress() + s.Require().NoError(err) + addrAll = append(addrAll, addr) + } + + for _, addr := range c.genesisAccounts { + acctAddr, err := addr.keyInfo.GetAddress() + s.Require().NoError(err) + addrAll = append(addrAll, acctAddr) + } + + s.Require().NoError( + modifyGenesis(val0ConfigDir, "", initBalanceStr, addrAll, initialGlobalFeeAmt+uatomDenom, uatomDenom), + ) + // copy the genesis file to the remaining validators + for _, val := range c.validators[1:] { + _, err := copyFile( + filepath.Join(val0ConfigDir, "config", "genesis.json"), + filepath.Join(val.configDir(), "config", "genesis.json"), + ) + s.Require().NoError(err) + } +} + +// TODO find a better way to manipulate accounts to add genesis accounts +func (s *IntegrationTestSuite) addGenesisVestingAndJailedAccounts( + c *chain, + valConfigDir, + vestingMnemonic, + jailedValMnemonic string, + appGenState map[string]json.RawMessage, +) map[string]json.RawMessage { + var ( + authGenState = authtypes.GetGenesisStateFromAppState(cdc, appGenState) + bankGenState = banktypes.GetGenesisStateFromAppState(cdc, appGenState) + stakingGenState = stakingtypes.GetGenesisStateFromAppState(cdc, appGenState) + ) + + // create genesis vesting accounts keys + kb, err := keyring.New(keyringAppName, keyring.BackendTest, valConfigDir, nil, cdc) + s.Require().NoError(err) + + keyringAlgos, _ := kb.SupportedAlgorithms() + algo, err := keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), keyringAlgos) + s.Require().NoError(err) + + // create jailed validator account keys + jailedValKey, err := kb.NewAccount(jailedValidatorKey, jailedValMnemonic, "", sdk.FullFundraiserPath, algo) + s.Require().NoError(err) + + // create genesis vesting accounts keys + c.genesisVestingAccounts = make(map[string]sdk.AccAddress) + for i, key := range genesisVestingKeys { + // Use the first wallet from the same mnemonic by HD path + acc, err := kb.NewAccount(key, vestingMnemonic, "", HDPath(i), algo) + s.Require().NoError(err) + c.genesisVestingAccounts[key], err = acc.GetAddress() + s.Require().NoError(err) + s.T().Logf("created %s genesis account %s\n", key, c.genesisVestingAccounts[key].String()) + } + var ( + continuousVestingAcc = c.genesisVestingAccounts[continuousVestingKey] + delayedVestingAcc = c.genesisVestingAccounts[delayedVestingKey] + ) + + // add jailed validator to staking store + pubKey, err := jailedValKey.GetPubKey() + s.Require().NoError(err) + + jailedValAcc, err := jailedValKey.GetAddress() + s.Require().NoError(err) + + jailedValAddr := sdk.ValAddress(jailedValAcc) + val, err := stakingtypes.NewValidator( + jailedValAddr, + pubKey, + stakingtypes.NewDescription("jailed", "", "", "", ""), + ) + s.Require().NoError(err) + val.Jailed = true + val.Tokens = sdk.NewInt(slashingShares) + val.DelegatorShares = sdk.NewDec(slashingShares) + stakingGenState.Validators = append(stakingGenState.Validators, val) + + // add jailed validator delegations + stakingGenState.Delegations = append(stakingGenState.Delegations, stakingtypes.Delegation{ + DelegatorAddress: jailedValAcc.String(), + ValidatorAddress: jailedValAddr.String(), + Shares: sdk.NewDec(slashingShares), + }) + + appGenState[stakingtypes.ModuleName], err = cdc.MarshalJSON(stakingGenState) + s.Require().NoError(err) + + // add jailed account to the genesis + baseJailedAccount := authtypes.NewBaseAccount(jailedValAcc, pubKey, 0, 0) + s.Require().NoError(baseJailedAccount.Validate()) + + // add continuous vesting account to the genesis + baseVestingContinuousAccount := authtypes.NewBaseAccount( + continuousVestingAcc, nil, 0, 0) + vestingContinuousGenAccount := authvesting.NewContinuousVestingAccountRaw( + authvesting.NewBaseVestingAccount( + baseVestingContinuousAccount, + sdk.NewCoins(vestingAmountVested), + time.Now().Add(time.Duration(rand.Intn(80)+150)*time.Second).Unix(), + ), + time.Now().Add(time.Duration(rand.Intn(40)+90)*time.Second).Unix(), + ) + s.Require().NoError(vestingContinuousGenAccount.Validate()) + + // add delayed vesting account to the genesis + baseVestingDelayedAccount := authtypes.NewBaseAccount( + delayedVestingAcc, nil, 0, 0) + vestingDelayedGenAccount := authvesting.NewDelayedVestingAccountRaw( + authvesting.NewBaseVestingAccount( + baseVestingDelayedAccount, + sdk.NewCoins(vestingAmountVested), + time.Now().Add(time.Duration(rand.Intn(40)+90)*time.Second).Unix(), + ), + ) + s.Require().NoError(vestingDelayedGenAccount.Validate()) + + // unpack and append accounts + accs, err := authtypes.UnpackAccounts(authGenState.Accounts) + s.Require().NoError(err) + accs = append(accs, vestingContinuousGenAccount, vestingDelayedGenAccount, baseJailedAccount) + accs = authtypes.SanitizeGenesisAccounts(accs) + genAccs, err := authtypes.PackAccounts(accs) + s.Require().NoError(err) + authGenState.Accounts = genAccs + + // update auth module state + appGenState[authtypes.ModuleName], err = cdc.MarshalJSON(&authGenState) + s.Require().NoError(err) + + // update balances + vestingContinuousBalances := banktypes.Balance{ + Address: continuousVestingAcc.String(), + Coins: vestingBalance, + } + vestingDelayedBalances := banktypes.Balance{ + Address: delayedVestingAcc.String(), + Coins: vestingBalance, + } + jailedValidatorBalances := banktypes.Balance{ + Address: jailedValAcc.String(), + Coins: sdk.NewCoins(tokenAmount), + } + stakingModuleBalances := banktypes.Balance{ + Address: authtypes.NewModuleAddress(stakingtypes.NotBondedPoolName).String(), + Coins: sdk.NewCoins(sdk.NewCoin(uatomDenom, sdk.NewInt(slashingShares))), + } + bankGenState.Balances = append( + bankGenState.Balances, + vestingContinuousBalances, + vestingDelayedBalances, + jailedValidatorBalances, + stakingModuleBalances, + ) + bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances) + + // update the denom metadata for the bank module + bankGenState.DenomMetadata = append(bankGenState.DenomMetadata, banktypes.Metadata{ + Description: "An example stable token", + Display: uatomDenom, + Base: uatomDenom, + Symbol: uatomDenom, + Name: uatomDenom, + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: uatomDenom, + Exponent: 0, + }, + }, + }) + + // update bank module state + appGenState[banktypes.ModuleName], err = cdc.MarshalJSON(bankGenState) + s.Require().NoError(err) + + return appGenState +} + +func (s *IntegrationTestSuite) initGenesis(c *chain, vestingMnemonic, jailedValMnemonic string) { + var ( + serverCtx = server.NewDefaultContext() + config = serverCtx.Config + validator = c.validators[0] + ) + + config.SetRoot(validator.configDir()) + config.Moniker = validator.moniker + + genFilePath := config.GenesisFile() + appGenState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFilePath) + s.Require().NoError(err) + + appGenState = s.addGenesisVestingAndJailedAccounts( + c, + validator.configDir(), + vestingMnemonic, + jailedValMnemonic, + appGenState, + ) + + var evidenceGenState evidencetypes.GenesisState + s.Require().NoError(cdc.UnmarshalJSON(appGenState[evidencetypes.ModuleName], &evidenceGenState)) + + evidenceGenState.Evidence = make([]*codectypes.Any, numberOfEvidences) + for i := range evidenceGenState.Evidence { + pk := ed25519.GenPrivKey() + evidence := &evidencetypes.Equivocation{ + Height: 1, + Power: 100, + Time: time.Now().UTC(), + ConsensusAddress: sdk.ConsAddress(pk.PubKey().Address().Bytes()).String(), + } + evidenceGenState.Evidence[i], err = codectypes.NewAnyWithValue(evidence) + s.Require().NoError(err) + } + + appGenState[evidencetypes.ModuleName], err = cdc.MarshalJSON(&evidenceGenState) + s.Require().NoError(err) + + var genUtilGenState genutiltypes.GenesisState + s.Require().NoError(cdc.UnmarshalJSON(appGenState[genutiltypes.ModuleName], &genUtilGenState)) + + // generate genesis txs + genTxs := make([]json.RawMessage, len(c.validators)) + for i, val := range c.validators { + createValmsg, err := val.buildCreateValidatorMsg(stakingAmountCoin) + s.Require().NoError(err) + signedTx, err := val.signMsg(createValmsg) + + s.Require().NoError(err) + + txRaw, err := cdc.MarshalJSON(signedTx) + s.Require().NoError(err) + + genTxs[i] = txRaw + } + + genUtilGenState.GenTxs = genTxs + + appGenState[genutiltypes.ModuleName], err = cdc.MarshalJSON(&genUtilGenState) + s.Require().NoError(err) + + genDoc.AppState, err = json.MarshalIndent(appGenState, "", " ") + s.Require().NoError(err) + + bz, err := tmjson.MarshalIndent(genDoc, "", " ") + s.Require().NoError(err) + + vestingPeriod, err := generateVestingPeriod() + s.Require().NoError(err) + + rawTx, _, err := buildRawTx() + s.Require().NoError(err) + + // write the updated genesis file to each validator. + for _, val := range c.validators { + err = writeFile(filepath.Join(val.configDir(), "config", "genesis.json"), bz) + s.Require().NoError(err) + + err = writeFile(filepath.Join(val.configDir(), vestingPeriodFile), vestingPeriod) + s.Require().NoError(err) + + err = writeFile(filepath.Join(val.configDir(), rawTxFile), rawTx) + s.Require().NoError(err) + } +} + +// initValidatorConfigs initializes the validator configs for the given chain. +func (s *IntegrationTestSuite) initValidatorConfigs(c *chain) { + for i, val := range c.validators { + tmCfgPath := filepath.Join(val.configDir(), "config", "config.toml") + + vpr := viper.New() + vpr.SetConfigFile(tmCfgPath) + s.Require().NoError(vpr.ReadInConfig()) + + valConfig := tmconfig.DefaultConfig() + + s.Require().NoError(vpr.Unmarshal(valConfig)) + + valConfig.P2P.ListenAddress = "tcp://0.0.0.0:26656" + valConfig.P2P.AddrBookStrict = false + valConfig.P2P.ExternalAddress = fmt.Sprintf("%s:%d", val.instanceName(), 26656) + valConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657" + valConfig.StateSync.Enable = false + valConfig.LogLevel = "info" + + var peers []string + + for j := 0; j < len(c.validators); j++ { + if i == j { + continue + } + + peer := c.validators[j] + peerID := fmt.Sprintf("%s@%s%d:26656", peer.nodeKey.ID(), peer.moniker, j) + peers = append(peers, peerID) + } + + valConfig.P2P.PersistentPeers = strings.Join(peers, ",") + + tmconfig.WriteConfigFile(tmCfgPath, valConfig) + + // set application configuration + appCfgPath := filepath.Join(val.configDir(), "config", "app.toml") + + appConfig := srvconfig.DefaultConfig() + appConfig.API.Enable = true + appConfig.API.Address = "tcp://0.0.0.0:1317" + appConfig.MinGasPrices = fmt.Sprintf("%s%s", minGasPrice, uatomDenom) + appConfig.GRPC.Address = "0.0.0.0:9090" + + srvconfig.SetConfigTemplate(srvconfig.DefaultConfigTemplate) + srvconfig.WriteConfigFile(appCfgPath, appConfig) + } +} + +// runValidators runs the validators in the chain +func (s *IntegrationTestSuite) runValidators(c *chain, portOffset int) { + s.T().Logf("starting Gaia %s validator containers...", c.id) + + s.valResources[c.id] = make([]*dockertest.Resource, len(c.validators)) + for i, val := range c.validators { + runOpts := &dockertest.RunOptions{ + Name: val.instanceName(), + NetworkID: s.dkrNet.Network.ID, + Mounts: []string{ + fmt.Sprintf("%s/:%s", val.configDir(), gaiaHomePath), + }, + Repository: "cosmos/gaiad-e2e", + } + + s.Require().NoError(exec.Command("chmod", "-R", "0777", val.configDir()).Run()) //nolint:gosec // this is a test + + // expose the first validator for debugging and communication + if val.index == 0 { + runOpts.PortBindings = map[docker.Port][]docker.PortBinding{ + "1317/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 1317+portOffset)}}, + "6060/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6060+portOffset)}}, + "6061/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6061+portOffset)}}, + "6062/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6062+portOffset)}}, + "6063/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6063+portOffset)}}, + "6064/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6064+portOffset)}}, + "6065/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6065+portOffset)}}, + "9090/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 9090+portOffset)}}, + "26656/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 26656+portOffset)}}, + "26657/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 26657+portOffset)}}, + } + } + + resource, err := s.dkrPool.RunWithOptions(runOpts, noRestart) + s.Require().NoError(err) + + s.valResources[c.id][i] = resource + s.T().Logf("started Gaia %s validator container: %s", c.id, resource.Container.ID) + } + + rpcClient, err := rpchttp.New("tcp://localhost:26657", "/websocket") + s.Require().NoError(err) + + s.Require().Eventually( + func() bool { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + + status, err := rpcClient.Status(ctx) + if err != nil { + return false + } + + // let the node produce a few blocks + if status.SyncInfo.CatchingUp || status.SyncInfo.LatestBlockHeight < 3 { + return false + } + + return true + }, + 5*time.Minute, + time.Second, + "Gaia node failed to produce blocks", + ) +} + +func noRestart(config *docker.HostConfig) { + // in this case we don't want the nodes to restart on failure + config.RestartPolicy = docker.RestartPolicy{ + Name: "no", + } +} // func (s *IntegrationTestSuite) writeGovParamChangeProposalGlobalFees(c *chain, coins sdk.DecCoins) { // type ParamInfo struct { @@ -852,9 +689,45 @@ package e2e // }, "", " ") // s.Require().NoError(err) -// err = writeFile(filepath.Join(c.validators[0].configDir(), "config", proposalMaxTotalBypassFilename), paramChangeProposalBody) -// s.Require().NoError(err) -// } +// err = writeFile(filepath.Join(c.validators[0].configDir(), "config", proposalMaxTotalBypassFilename), paramChangeProposalBody) +// s.Require().NoError(err) +// } +func (s *IntegrationTestSuite) writeGovCommunitySpendProposal(c *chain, amount sdk.Coin, recipient string) { + msg := &distrtypes.MsgCommunityPoolSpend{ + Authority: govModuleAddress, + Recipient: recipient, + Amount: sdk.Coins{amount}, + } + + proposalCommSpend, err := govv1.NewMsgSubmitProposal( + []sdk.Msg{msg}, + sdk.Coins{sdk.NewCoin(uatomDenom, sdk.NewInt(100))}, + "JohnGalt", + "Community Pool Spend", + "Fund Team!", + "summary", + ) + s.Require().NoError(err) + res, err := cdc.MarshalInterfaceJSON(proposalCommSpend) + s.Require().NoError(err) + + err = writeFile(filepath.Join(c.validators[0].configDir(), "config", proposalCommunitySpendFilename), res) + s.Require().NoError(err) +} + +func (s *IntegrationTestSuite) writeGovLegProposal(c *chain, height int64, name string) { + prop := &upgradetypes.Plan{ + Name: name, + Height: height, + Info: `{"binaries":{"os1/arch1":"url1","os2/arch2":"url2"}}`, + } + + commSpendBody, err := json.MarshalIndent(prop, "", " ") + s.Require().NoError(err) + + err = writeFile(filepath.Join(c.validators[0].configDir(), "config", proposalCommunitySpendFilename), commSpendBody) + s.Require().NoError(err) +} // func (s *IntegrationTestSuite) writeGovCommunitySpendProposal(c *chain, amount string, recipient string) { // proposalCommSpend := &distrtypes.CommunityPoolSpendProposalWithDeposit{ @@ -871,65 +744,64 @@ package e2e // s.Require().NoError(err) // } -// type ConsumerAdditionProposalWithDeposit struct { -// ccvprovider.ConsumerAdditionProposal -// Deposit string `json:"deposit"` -// } - -// type ConsumerRemovalProposalWithDeposit struct { -// ccvprovider.ConsumerRemovalProposal -// Deposit string `json:"deposit"` -// } - -// func (s *IntegrationTestSuite) writeAddRemoveConsumerProposals(c *chain, consumerChainID string) { -// hash, _ := json.Marshal("Z2VuX2hhc2g=") -// addProp := &ccvprovider.ConsumerAdditionProposal{ -// Title: "Create consumer chain", -// Description: "First consumer chain", -// ChainId: consumerChainID, -// InitialHeight: ibcclienttypes.Height{ -// RevisionHeight: 1, -// }, -// GenesisHash: hash, -// BinaryHash: hash, -// SpawnTime: time.Now(), -// UnbondingPeriod: time.Duration(100000000000), -// CcvTimeoutPeriod: time.Duration(100000000000), -// TransferTimeoutPeriod: time.Duration(100000000000), -// ConsumerRedistributionFraction: "0.75", -// BlocksPerDistributionTransmission: 10, -// HistoricalEntries: 10000, -// } -// addPropWithDeposit := ConsumerAdditionProposalWithDeposit{ -// ConsumerAdditionProposal: *addProp, -// Deposit: "1000uatom", -// } - -// removeProp := &ccvprovider.ConsumerRemovalProposal{ -// Title: "Remove consumer chain", -// Description: "Removing consumer chain", -// ChainId: consumerChainID, -// StopTime: time.Now(), -// } - -// removePropWithDeposit := ConsumerRemovalProposalWithDeposit{ -// ConsumerRemovalProposal: *removeProp, -// Deposit: "1000uatom", -// } - -// consumerAddBody, err := json.MarshalIndent(addPropWithDeposit, "", " ") -// s.Require().NoError(err) - -// consumerRemoveBody, err := json.MarshalIndent(removePropWithDeposit, "", " ") -// s.Require().NoError(err) - -// err = writeFile(filepath.Join(c.validators[0].configDir(), "config", proposalAddConsumerChainFilename), consumerAddBody) -// s.Require().NoError(err) -// err = writeFile(filepath.Join(c.validators[0].configDir(), "config", proposalRemoveConsumerChainFilename), consumerRemoveBody) -// s.Require().NoError(err) -// } - -// func configFile(filename string) string { -// filepath := filepath.Join(gaiaConfigPath, filename) -// return filepath -// } +// type ConsumerAdditionProposalWithDeposit struct { +// ccvprovider.ConsumerAdditionProposal +// Deposit string `json:"deposit"` +// } +// +// type ConsumerRemovalProposalWithDeposit struct { +// ccvprovider.ConsumerRemovalProposal +// Deposit string `json:"deposit"` +// } +// +// func (s *IntegrationTestSuite) writeAddRemoveConsumerProposals(c *chain, consumerChainID string) { +// hash, _ := json.Marshal("Z2VuX2hhc2g=") +// addProp := &ccvprovider.ConsumerAdditionProposal{ +// Title: "Create consumer chain", +// Description: "First consumer chain", +// ChainId: consumerChainID, +// InitialHeight: ibcclienttypes.Height{ +// RevisionHeight: 1, +// }, +// GenesisHash: hash, +// BinaryHash: hash, +// SpawnTime: time.Now(), +// UnbondingPeriod: time.Duration(100000000000), +// CcvTimeoutPeriod: time.Duration(100000000000), +// TransferTimeoutPeriod: time.Duration(100000000000), +// ConsumerRedistributionFraction: "0.75", +// BlocksPerDistributionTransmission: 10, +// HistoricalEntries: 10000, +// } +// addPropWithDeposit := ConsumerAdditionProposalWithDeposit{ +// ConsumerAdditionProposal: *addProp, +// Deposit: "1000uatom", +// } +// +// removeProp := &ccvprovider.ConsumerRemovalProposal{ +// Title: "Remove consumer chain", +// Description: "Removing consumer chain", +// ChainId: consumerChainID, +// StopTime: time.Now(), +// } +// +// removePropWithDeposit := ConsumerRemovalProposalWithDeposit{ +// ConsumerRemovalProposal: *removeProp, +// Deposit: "1000uatom", +// } +// +// consumerAddBody, err := json.MarshalIndent(addPropWithDeposit, "", " ") +// s.Require().NoError(err) +// +// consumerRemoveBody, err := json.MarshalIndent(removePropWithDeposit, "", " ") +// s.Require().NoError(err) +// +// err = writeFile(filepath.Join(c.validators[0].configDir(), "config", proposalAddConsumerChainFilename), consumerAddBody) +// s.Require().NoError(err) +// err = writeFile(filepath.Join(c.validators[0].configDir(), "config", proposalRemoveConsumerChainFilename), consumerRemoveBody) +// s.Require().NoError(err) +// } +func configFile(filename string) string { + filepath := filepath.Join(gaiaConfigPath, filename) + return filepath +} diff --git a/tests/e2e/e2e_slashing_test.go b/tests/e2e/e2e_slashing_test.go index 614e2c2768f..89744951876 100644 --- a/tests/e2e/e2e_slashing_test.go +++ b/tests/e2e/e2e_slashing_test.go @@ -1,24 +1,23 @@ package e2e -// -// const jailedValidatorKey = "jailed" -// -// func (s *IntegrationTestSuite) testSlashing(chainEndpoint string) { -// s.Run("test unjail validator", func() { -// validators, err := queryValidators(chainEndpoint) -// s.Require().NoError(err) -// -// for _, val := range validators { -// if val.Jailed { -// s.execUnjail( -// s.chainA, -// withKeyValue(flagFrom, jailedValidatorKey), -// ) -// -// valQ, err := queryValidator(chainEndpoint, val.OperatorAddress) -// s.Require().NoError(err) -// s.Require().False(valQ.Jailed) -// } -// } -// }) -//} +const jailedValidatorKey = "jailed" + +func (s *IntegrationTestSuite) testSlashing(chainEndpoint string) { + s.Run("test unjail validator", func() { + validators, err := queryValidators(chainEndpoint) + s.Require().NoError(err) + + for _, val := range validators { + if val.Jailed { + s.execUnjail( + s.chainA, + withKeyValue(flagFrom, jailedValidatorKey), + ) + + valQ, err := queryValidator(chainEndpoint, val.OperatorAddress) + s.Require().NoError(err) + s.Require().False(valQ.Jailed) + } + } + }) +} diff --git a/tests/e2e/e2e_staking_test.go b/tests/e2e/e2e_staking_test.go index 10f62fca4fb..e9ab52ab9e9 100644 --- a/tests/e2e/e2e_staking_test.go +++ b/tests/e2e/e2e_staking_test.go @@ -1,60 +1,59 @@ package e2e -// -// import ( -// "fmt" -// "time" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -//) -// -// func (s *IntegrationTestSuite) testStaking() { -// chainEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) -// -// validatorA := s.chainA.validators[0] -// validatorB := s.chainA.validators[1] -// validatorAAddr := validatorA.keyInfo.GetAddress() -// validatorBAddr := validatorB.keyInfo.GetAddress() -// -// validatorAddressA := sdk.ValAddress(validatorAAddr).String() -// validatorAddressB := sdk.ValAddress(validatorBAddr).String() -// -// delegatorAddress := s.chainA.genesisAccounts[2].keyInfo.GetAddress().String() -// -// fees := sdk.NewCoin(uatomDenom, sdk.NewInt(1)) -// -// delegationAmount := sdk.NewInt(500000000) -// delegation := sdk.NewCoin(uatomDenom, delegationAmount) // 500 atom -// -// // Alice delegate uatom to Validator A -// s.executeDelegate(s.chainA, 0, delegation.String(), validatorAddressA, delegatorAddress, gaiaHomePath, fees.String()) -// -// // Validate delegation successful -// s.Require().Eventually( -// func() bool { -// res, err := queryDelegation(chainEndpoint, validatorAddressA, delegatorAddress) -// amt := res.GetDelegationResponse().GetDelegation().GetShares() -// s.Require().NoError(err) -// -// return amt.Equal(sdk.NewDecFromInt(delegationAmount)) -// }, -// 20*time.Second, -// 5*time.Second, -// ) -// -// // Alice re-delegate uatom from Validator A to Validator B -// s.executeRedelegate(s.chainA, 0, delegation.String(), validatorAddressA, validatorAddressB, delegatorAddress, gaiaHomePath, fees.String()) -// -// // Validate re-delegation successful -// s.Require().Eventually( -// func() bool { -// res, err := queryDelegation(chainEndpoint, validatorAddressB, delegatorAddress) -// amt := res.GetDelegationResponse().GetDelegation().GetShares() -// s.Require().NoError(err) -// -// return amt.Equal(sdk.NewDecFromInt(delegationAmount)) -// }, -// 20*time.Second, -// 5*time.Second, -// ) -//} +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (s *IntegrationTestSuite) testStaking() { + chainEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + + validatorA := s.chainA.validators[0] + validatorB := s.chainA.validators[1] + validatorAAddr, _ := validatorA.keyInfo.GetAddress() + validatorBAddr, _ := validatorB.keyInfo.GetAddress() + + validatorAddressA := sdk.ValAddress(validatorAAddr).String() + validatorAddressB := sdk.ValAddress(validatorBAddr).String() + + delegatorAddress, _ := s.chainA.genesisAccounts[2].keyInfo.GetAddress() + + fees := sdk.NewCoin(uatomDenom, sdk.NewInt(1)) + + delegationAmount := sdk.NewInt(500000000) + delegation := sdk.NewCoin(uatomDenom, delegationAmount) // 500 atom + + // Alice delegate uatom to Validator A + s.executeDelegate(s.chainA, 0, delegation.String(), validatorAddressA, delegatorAddress.String(), gaiaHomePath, fees.String()) + + // Validate delegation successful + s.Require().Eventually( + func() bool { + res, err := queryDelegation(chainEndpoint, validatorAddressA, delegatorAddress.String()) + amt := res.GetDelegationResponse().GetDelegation().GetShares() + s.Require().NoError(err) + + return amt.Equal(sdk.NewDecFromInt(delegationAmount)) + }, + 20*time.Second, + 5*time.Second, + ) + + // Alice re-delegate uatom from Validator A to Validator B + s.executeRedelegate(s.chainA, 0, delegation.String(), validatorAddressA, validatorAddressB, delegatorAddress.String(), gaiaHomePath, fees.String()) + + // Validate re-delegation successful + s.Require().Eventually( + func() bool { + res, err := queryDelegation(chainEndpoint, validatorAddressB, delegatorAddress.String()) + amt := res.GetDelegationResponse().GetDelegation().GetShares() + s.Require().NoError(err) + + return amt.Equal(sdk.NewDecFromInt(delegationAmount)) + }, + 20*time.Second, + 5*time.Second, + ) +} diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 955d5a8bea4..c6727543ef3 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -1,123 +1,117 @@ package e2e -// import ( -// "fmt" -// ) +import "fmt" -// var ( -// runBankTest = true -// runBypassMinFeeTest = true -// runEncodeTest = true -// runEvidenceTest = true -// runFeeGrantTest = true -// runGlobalFeesTest = true -// runGovTest = true -// runIBCTest = true -// runSlashingTest = true -// runStakingAndDistributionTest = true -// runVestingTest = true -// runRestInterfacesTest = true -// ) +var ( + runBankTest = true + // runBypassMinFeeTest = true + runEncodeTest = true + runEvidenceTest = true + runFeeGrantTest = true + // runGlobalFeesTest = true + runGovTest = true + runIBCTest = true + runSlashingTest = true + runStakingAndDistributionTest = true + runVestingTest = true + runRestInterfacesTest = true +) -// func (s *IntegrationTestSuite) TestRestInterfaces() { -// if !runRestInterfacesTest { -// s.T().Skip() -// } -// s.testRestInterfaces() -// } +func (s *IntegrationTestSuite) TestRestInterfaces() { + if !runRestInterfacesTest { + s.T().Skip() + } + s.testRestInterfaces() +} -// func (s *IntegrationTestSuite) TestBank() { -// if !runBankTest { -// s.T().Skip() -// } -// s.testBankTokenTransfer() -// } +func (s *IntegrationTestSuite) TestBank() { + if !runBankTest { + s.T().Skip() + } + s.testBankTokenTransfer() +} -// func (s *IntegrationTestSuite) TestByPassMinFee() { -// if !runBypassMinFeeTest { -// s.T().Skip() -// } -// chainAPI := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) -// s.testBypassMinFeeWithdrawReward(chainAPI) -// } +// func (s *IntegrationTestSuite) TestByPassMinFee() { +// if !runBypassMinFeeTest { +// s.T().Skip() +// } +// chainAPI := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) +// s.testBypassMinFeeWithdrawReward(chainAPI) +// } -// func (s *IntegrationTestSuite) TestEncode() { -// if !runEncodeTest { -// s.T().Skip() -// } -// s.testEncode() -// s.testDecode() -// } +func (s *IntegrationTestSuite) TestEncode() { + if !runEncodeTest { + s.T().Skip() + } + s.testEncode() + s.testDecode() +} -// func (s *IntegrationTestSuite) TestEvidence() { -// if !runEvidenceTest { -// s.T().Skip() -// } -// s.testEvidence() -// } +func (s *IntegrationTestSuite) TestEvidence() { + if !runEvidenceTest { + s.T().Skip() + } + s.testEvidence() +} -// func (s *IntegrationTestSuite) TestFeeGrant() { -// if !runFeeGrantTest { -// s.T().Skip() -// } -// s.testFeeGrant() -// } +func (s *IntegrationTestSuite) TestFeeGrant() { + if !runFeeGrantTest { + s.T().Skip() + } + s.testFeeGrant() +} -// func (s *IntegrationTestSuite) TestGlobalFees() { -// if !runGlobalFeesTest { -// s.T().Skip() -// } -// s.testGlobalFees() -// s.testQueryGlobalFeesInGenesis() -// } +// func (s *IntegrationTestSuite) TestGlobalFees() { +// if !runGlobalFeesTest { +// s.T().Skip() +// } +// s.testGlobalFees() +// s.testQueryGlobalFeesInGenesis() +// } +// -// func (s *IntegrationTestSuite) TestGov() { -// if !runGovTest { -// s.T().Skip() -// } -// s.GovSoftwareUpgrade() -// s.GovCancelSoftwareUpgrade() -// s.GovCommunityPoolSpend() -// s.AddRemoveConsumerChain() -// } +func (s *IntegrationTestSuite) TestGov() { + if !runGovTest { + s.T().Skip() + } + s.GovSoftwareUpgrade() + s.GovCancelSoftwareUpgrade() + s.GovCommunityPoolSpend() + // s.AddRemoveConsumerChain() +} -// func (s *IntegrationTestSuite) TestIBC() { -// if !runIBCTest { -// s.T().Skip() -// } -// s.testIBCTokenTransfer() -// s.testMultihopIBCTokenTransfer() -// s.testFailedMultihopIBCTokenTransfer() +func (s *IntegrationTestSuite) TestIBC() { + if !runIBCTest { + s.T().Skip() + } + s.testIBCTokenTransfer() + s.testMultihopIBCTokenTransfer() + s.testFailedMultihopIBCTokenTransfer() +} -// // stop hermes0 to prevent hermes0 relaying transactions -// s.Require().NoError(s.dkrPool.Purge(s.hermesResource0)) -// HermesResource0Purged = true -// s.testIBCBypassMsg() -// } +func (s *IntegrationTestSuite) TestSlashing() { + if !runSlashingTest { + s.T().Skip() + } + chainAPI := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + s.testSlashing(chainAPI) +} -// func (s *IntegrationTestSuite) TestSlashing() { -// if !runSlashingTest { -// s.T().Skip() -// } -// chainAPI := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) -// s.testSlashing(chainAPI) -// } +// todo add fee test with wrong denom order +func (s *IntegrationTestSuite) TestStakingAndDistribution() { + if !runStakingAndDistributionTest { + s.T().Skip() + } + s.testStaking() + s.testDistribution() +} -// // todo add fee test with wrong denom order -// func (s *IntegrationTestSuite) TestStakingAndDistribution() { -// if !runStakingAndDistributionTest { -// s.T().Skip() -// } -// s.testStaking() -// s.testDistribution() -// } - -// func (s *IntegrationTestSuite) TestVesting() { -// if !runVestingTest { -// s.T().Skip() -// } -// chainAAPI := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) -// s.testDelayedVestingAccount(chainAAPI) -// s.testContinuousVestingAccount(chainAAPI) -// // s.testPeriodicVestingAccount(chainAAPI) TODO: add back when v0.45 adds the missing CLI command. -// } +func (s *IntegrationTestSuite) TestVesting() { + if !runVestingTest { + s.T().Skip() + } + chainAAPI := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + s.testDelayedVestingAccount(chainAAPI) + s.testContinuousVestingAccount(chainAAPI) + // s.testPeriodicVestingAccount(chainAAPI) TODO: add back when v0.45 adds the missing CLI command. +} diff --git a/tests/e2e/e2e_vesting_test.go b/tests/e2e/e2e_vesting_test.go index c68a91c54d4..0483cb8343c 100644 --- a/tests/e2e/e2e_vesting_test.go +++ b/tests/e2e/e2e_vesting_test.go @@ -1,336 +1,336 @@ package e2e -// import ( -// "encoding/json" -// "math/rand" -// "path/filepath" -// "time" - -// sdk "github.com/cosmos/cosmos-sdk/types" - -// "github.com/cosmos/gaia/v11/x/globalfee/ante" -// ) - -// const ( -// delayedVestingKey = "delayed_vesting" -// continuousVestingKey = "continuous_vesting" -// lockedVestingKey = "locker_vesting" -// periodicVestingKey = "periodic_vesting" - -// vestingPeriodFile = "test_period.json" -// vestingTxDelay = 5 -// ) - -// type ( -// vestingPeriod struct { -// StartTime int64 `json:"start_time"` -// Periods []period `json:"periods"` -// } -// period struct { -// Coins string `json:"coins"` -// Length int64 `json:"length_seconds"` -// } -// ) - -// var ( -// genesisVestingKeys = []string{continuousVestingKey, delayedVestingKey, lockedVestingKey, periodicVestingKey} -// vestingAmountVested = sdk.NewCoin(uatomDenom, sdk.NewInt(99900000000)) -// vestingAmount = sdk.NewCoin(uatomDenom, sdk.NewInt(350000)) -// vestingBalance = sdk.NewCoins(vestingAmountVested).Add(vestingAmount) -// vestingDelegationAmount = sdk.NewCoin(uatomDenom, sdk.NewInt(500000000)) -// vestingDelegationFees = sdk.NewCoin(uatomDenom, sdk.NewInt(1)) -// ) - -// func (s *IntegrationTestSuite) testDelayedVestingAccount(api string) { -// var ( -// valIdx = 0 -// chain = s.chainA -// val = chain.validators[valIdx] -// vestingDelayedAcc = chain.genesisVestingAccounts[delayedVestingKey] -// ) -// sender := val.keyInfo.GetAddress() -// valOpAddr := sdk.ValAddress(sender).String() - -// s.Run("test delayed vesting genesis account", func() { -// acc, err := queryDelayedVestingAccount(api, vestingDelayedAcc.String()) -// s.Require().NoError(err) - -// // Check address balance -// balance, err := getSpecificBalance(api, vestingDelayedAcc.String(), uatomDenom) -// s.Require().NoError(err) -// s.Require().Equal(vestingBalance.AmountOf(uatomDenom), balance.Amount) - -// // Delegate coins should succeed -// s.executeDelegate(chain, valIdx, vestingDelegationAmount.String(), valOpAddr, -// vestingDelayedAcc.String(), gaiaHomePath, vestingDelegationFees.String()) - -// // Validate delegation successful -// s.Require().Eventually( -// func() bool { -// res, err := queryDelegation(api, valOpAddr, vestingDelayedAcc.String()) -// amt := res.GetDelegationResponse().GetDelegation().GetShares() -// s.Require().NoError(err) - -// return amt.Equal(sdk.NewDecFromInt(vestingDelegationAmount.Amount)) -// }, -// 20*time.Second, -// 5*time.Second, -// ) - -// waitTime := acc.EndTime - time.Now().Unix() -// if waitTime > vestingTxDelay { -// // Transfer coins should fail -// balance, err := getSpecificBalance(api, vestingDelayedAcc.String(), uatomDenom) -// s.Require().NoError(err) -// s.execBankSend( -// chain, -// valIdx, -// vestingDelayedAcc.String(), -// Address(), -// balance.Sub(standardFees).String(), -// standardFees.String(), -// true, -// ) -// waitTime = acc.EndTime - time.Now().Unix() + vestingTxDelay -// time.Sleep(time.Duration(waitTime) * time.Second) -// } - -// // Transfer coins should succeed -// balance, err = getSpecificBalance(api, vestingDelayedAcc.String(), uatomDenom) -// s.Require().NoError(err) -// s.execBankSend( -// chain, -// valIdx, -// vestingDelayedAcc.String(), -// Address(), -// balance.Sub(standardFees).String(), -// standardFees.String(), -// false, -// ) -// }) -// } - -// func (s *IntegrationTestSuite) testContinuousVestingAccount(api string) { -// s.Run("test continuous vesting genesis account", func() { -// var ( -// valIdx = 0 -// chain = s.chainA -// val = chain.validators[valIdx] -// continuousVestingAcc = chain.genesisVestingAccounts[continuousVestingKey] -// ) -// sender := val.keyInfo.GetAddress() -// valOpAddr := sdk.ValAddress(sender).String() - -// acc, err := queryContinuousVestingAccount(api, continuousVestingAcc.String()) -// s.Require().NoError(err) - -// // Check address balance -// balance, err := getSpecificBalance(api, continuousVestingAcc.String(), uatomDenom) -// s.Require().NoError(err) -// s.Require().Equal(vestingBalance.AmountOf(uatomDenom), balance.Amount) - -// // Delegate coins should succeed -// s.executeDelegate(chain, valIdx, vestingDelegationAmount.String(), -// valOpAddr, continuousVestingAcc.String(), gaiaHomePath, vestingDelegationFees.String()) - -// // Validate delegation successful -// s.Require().Eventually( -// func() bool { -// res, err := queryDelegation(api, valOpAddr, continuousVestingAcc.String()) -// amt := res.GetDelegationResponse().GetDelegation().GetShares() -// s.Require().NoError(err) - -// return amt.Equal(sdk.NewDecFromInt(vestingDelegationAmount.Amount)) -// }, -// 20*time.Second, -// 5*time.Second, -// ) - -// waitStartTime := acc.StartTime - time.Now().Unix() -// if waitStartTime > vestingTxDelay { -// // Transfer coins should fail -// balance, err := getSpecificBalance(api, continuousVestingAcc.String(), uatomDenom) -// s.Require().NoError(err) -// s.execBankSend( -// chain, -// valIdx, -// continuousVestingAcc.String(), -// Address(), -// balance.Sub(standardFees).String(), -// standardFees.String(), -// true, -// ) -// waitStartTime = acc.StartTime - time.Now().Unix() + vestingTxDelay -// time.Sleep(time.Duration(waitStartTime) * time.Second) -// } - -// waitEndTime := acc.EndTime - time.Now().Unix() -// if waitEndTime > vestingTxDelay { -// // Transfer coins should fail -// balance, err := getSpecificBalance(api, continuousVestingAcc.String(), uatomDenom) -// s.Require().NoError(err) -// s.execBankSend( -// chain, -// valIdx, -// continuousVestingAcc.String(), -// Address(), -// balance.Sub(standardFees).String(), -// standardFees.String(), -// true, -// ) -// waitEndTime = acc.EndTime - time.Now().Unix() + vestingTxDelay -// time.Sleep(time.Duration(waitEndTime) * time.Second) -// } - -// // Transfer coins should succeed -// balance, err = getSpecificBalance(api, continuousVestingAcc.String(), uatomDenom) -// s.Require().NoError(err) -// s.execBankSend( -// chain, -// valIdx, -// continuousVestingAcc.String(), -// Address(), -// balance.Sub(standardFees).String(), -// standardFees.String(), -// false, -// ) -// }) -// } - -// func (s *IntegrationTestSuite) testPeriodicVestingAccount(api string) { //nolint:unused -// s.Run("test periodic vesting genesis account", func() { -// var ( -// valIdx = 0 -// chain = s.chainA -// val = chain.validators[valIdx] -// periodicVestingAddr = chain.genesisVestingAccounts[periodicVestingKey].String() -// ) -// sender := val.keyInfo.GetAddress() -// valOpAddr := sdk.ValAddress(sender).String() - -// s.execCreatePeriodicVestingAccount( -// chain, -// periodicVestingAddr, -// filepath.Join(gaiaHomePath, vestingPeriodFile), -// withKeyValue(flagFrom, sender.String()), -// ) - -// acc, err := queryPeriodicVestingAccount(api, periodicVestingAddr) -// s.Require().NoError(err) - -// // Check address balance -// balance, err := getSpecificBalance(api, periodicVestingAddr, uatomDenom) -// s.Require().NoError(err) - -// expectedBalance := sdk.NewCoin(uatomDenom, sdk.NewInt(0)) -// for _, period := range acc.VestingPeriods { -// _, coin := ante.Find(period.Amount, uatomDenom) -// expectedBalance = expectedBalance.Add(coin) -// } -// s.Require().Equal(expectedBalance, balance) - -// waitStartTime := acc.StartTime - time.Now().Unix() -// if waitStartTime > vestingTxDelay { -// // Transfer coins should fail -// balance, err = getSpecificBalance(api, periodicVestingAddr, uatomDenom) -// s.Require().NoError(err) -// s.execBankSend( -// chain, -// valIdx, -// periodicVestingAddr, -// Address(), -// balance.Sub(standardFees).String(), -// standardFees.String(), -// true, -// ) -// waitStartTime = acc.StartTime - time.Now().Unix() + vestingTxDelay -// time.Sleep(time.Duration(waitStartTime) * time.Second) -// } - -// firstPeriod := acc.StartTime + acc.VestingPeriods[0].Length -// waitFirstPeriod := firstPeriod - time.Now().Unix() -// if waitFirstPeriod > vestingTxDelay { -// // Transfer coins should fail -// balance, err = getSpecificBalance(api, periodicVestingAddr, uatomDenom) -// s.Require().NoError(err) -// s.execBankSend( -// chain, -// valIdx, -// periodicVestingAddr, -// Address(), -// balance.Sub(standardFees).String(), -// standardFees.String(), -// true, -// ) -// waitFirstPeriod = firstPeriod - time.Now().Unix() + vestingTxDelay -// time.Sleep(time.Duration(waitFirstPeriod) * time.Second) -// } - -// // Delegate coins should succeed -// s.executeDelegate(chain, valIdx, vestingDelegationAmount.String(), valOpAddr, -// periodicVestingAddr, gaiaHomePath, vestingDelegationFees.String()) - -// // Validate delegation successful -// s.Require().Eventually( -// func() bool { -// res, err := queryDelegation(api, valOpAddr, periodicVestingAddr) -// amt := res.GetDelegationResponse().GetDelegation().GetShares() -// s.Require().NoError(err) - -// return amt.Equal(sdk.NewDecFromInt(vestingDelegationAmount.Amount)) -// }, -// 20*time.Second, -// 5*time.Second, -// ) - -// // Transfer coins should succeed -// balance, err = getSpecificBalance(api, periodicVestingAddr, uatomDenom) -// s.Require().NoError(err) -// s.execBankSend( -// chain, -// valIdx, -// periodicVestingAddr, -// Address(), -// balance.Sub(standardFees).String(), -// standardFees.String(), -// false, -// ) - -// secondPeriod := firstPeriod + acc.VestingPeriods[1].Length -// waitSecondPeriod := secondPeriod - time.Now().Unix() -// if waitSecondPeriod > vestingTxDelay { -// time.Sleep(time.Duration(waitSecondPeriod) * time.Second) - -// // Transfer coins should succeed -// balance, err = getSpecificBalance(api, periodicVestingAddr, uatomDenom) -// s.Require().NoError(err) -// s.execBankSend( -// chain, -// valIdx, -// periodicVestingAddr, -// Address(), -// balance.Sub(standardFees).String(), -// standardFees.String(), -// false, -// ) -// } -// }) -// } - -// // generateVestingPeriod generate the vesting period file -// func generateVestingPeriod() ([]byte, error) { -// p := vestingPeriod{ -// StartTime: time.Now().Add(time.Duration(rand.Intn(20)+95) * time.Second).Unix(), -// Periods: []period{ -// { -// Coins: "850000000" + uatomDenom, -// Length: 35, -// }, -// { -// Coins: "2000000000" + uatomDenom, -// Length: 35, -// }, -// }, -// } -// return json.Marshal(p) -// } +import ( + "encoding/json" + "math/rand" + "path/filepath" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + delayedVestingKey = "delayed_vesting" + continuousVestingKey = "continuous_vesting" + lockedVestingKey = "locker_vesting" + periodicVestingKey = "periodic_vesting" + + vestingPeriodFile = "test_period.json" + vestingTxDelay = 5 +) + +type ( + vestingPeriod struct { + StartTime int64 `json:"start_time"` + Periods []period `json:"periods"` + } + period struct { + Coins string `json:"coins"` + Length int64 `json:"length_seconds"` + } +) + +var ( + genesisVestingKeys = []string{continuousVestingKey, delayedVestingKey, lockedVestingKey, periodicVestingKey} + vestingAmountVested = sdk.NewCoin(uatomDenom, sdk.NewInt(99900000000)) + vestingAmount = sdk.NewCoin(uatomDenom, sdk.NewInt(350000)) + vestingBalance = sdk.NewCoins(vestingAmountVested).Add(vestingAmount) + vestingDelegationAmount = sdk.NewCoin(uatomDenom, sdk.NewInt(500000000)) + vestingDelegationFees = sdk.NewCoin(uatomDenom, sdk.NewInt(1)) +) + +func (s *IntegrationTestSuite) testDelayedVestingAccount(api string) { + var ( + valIdx = 0 + chain = s.chainA + val = chain.validators[valIdx] + vestingDelayedAcc = chain.genesisVestingAccounts[delayedVestingKey] + ) + sender, _ := val.keyInfo.GetAddress() + valOpAddr := sdk.ValAddress(sender).String() + + s.Run("test delayed vesting genesis account", func() { + acc, err := queryDelayedVestingAccount(api, vestingDelayedAcc.String()) + s.Require().NoError(err) + + // Check address balance + balance, err := getSpecificBalance(api, vestingDelayedAcc.String(), uatomDenom) + s.Require().NoError(err) + s.Require().Equal(vestingBalance.AmountOf(uatomDenom), balance.Amount) + + // Delegate coins should succeed + s.executeDelegate(chain, valIdx, vestingDelegationAmount.String(), valOpAddr, + vestingDelayedAcc.String(), gaiaHomePath, vestingDelegationFees.String()) + + // Validate delegation successful + s.Require().Eventually( + func() bool { + res, err := queryDelegation(api, valOpAddr, vestingDelayedAcc.String()) + amt := res.GetDelegationResponse().GetDelegation().GetShares() + s.Require().NoError(err) + + return amt.Equal(sdk.NewDecFromInt(vestingDelegationAmount.Amount)) + }, + 20*time.Second, + 5*time.Second, + ) + + waitTime := acc.EndTime - time.Now().Unix() + if waitTime > vestingTxDelay { + // Transfer coins should fail + balance, err := getSpecificBalance(api, vestingDelayedAcc.String(), uatomDenom) + s.Require().NoError(err) + s.execBankSend( + chain, + valIdx, + vestingDelayedAcc.String(), + Address(), + balance.Sub(standardFees).String(), + standardFees.String(), + true, + ) + waitTime = acc.EndTime - time.Now().Unix() + vestingTxDelay + time.Sleep(time.Duration(waitTime) * time.Second) + } + + // Transfer coins should succeed + balance, err = getSpecificBalance(api, vestingDelayedAcc.String(), uatomDenom) + s.Require().NoError(err) + s.execBankSend( + chain, + valIdx, + vestingDelayedAcc.String(), + Address(), + balance.Sub(standardFees).String(), + standardFees.String(), + false, + ) + }) +} + +func (s *IntegrationTestSuite) testContinuousVestingAccount(api string) { + s.Run("test continuous vesting genesis account", func() { + var ( + valIdx = 0 + chain = s.chainA + val = chain.validators[valIdx] + continuousVestingAcc = chain.genesisVestingAccounts[continuousVestingKey] + ) + sender, _ := val.keyInfo.GetAddress() + valOpAddr := sdk.ValAddress(sender).String() + + acc, err := queryContinuousVestingAccount(api, continuousVestingAcc.String()) + s.Require().NoError(err) + + // Check address balance + balance, err := getSpecificBalance(api, continuousVestingAcc.String(), uatomDenom) + s.Require().NoError(err) + s.Require().Equal(vestingBalance.AmountOf(uatomDenom), balance.Amount) + + // Delegate coins should succeed + s.executeDelegate(chain, valIdx, vestingDelegationAmount.String(), + valOpAddr, continuousVestingAcc.String(), gaiaHomePath, vestingDelegationFees.String()) + + // Validate delegation successful + s.Require().Eventually( + func() bool { + res, err := queryDelegation(api, valOpAddr, continuousVestingAcc.String()) + amt := res.GetDelegationResponse().GetDelegation().GetShares() + s.Require().NoError(err) + + return amt.Equal(sdk.NewDecFromInt(vestingDelegationAmount.Amount)) + }, + 20*time.Second, + 5*time.Second, + ) + + waitStartTime := acc.StartTime - time.Now().Unix() + if waitStartTime > vestingTxDelay { + // Transfer coins should fail + balance, err := getSpecificBalance(api, continuousVestingAcc.String(), uatomDenom) + s.Require().NoError(err) + s.execBankSend( + chain, + valIdx, + continuousVestingAcc.String(), + Address(), + balance.Sub(standardFees).String(), + standardFees.String(), + true, + ) + waitStartTime = acc.StartTime - time.Now().Unix() + vestingTxDelay + time.Sleep(time.Duration(waitStartTime) * time.Second) + } + + waitEndTime := acc.EndTime - time.Now().Unix() + if waitEndTime > vestingTxDelay { + // Transfer coins should fail + balance, err := getSpecificBalance(api, continuousVestingAcc.String(), uatomDenom) + s.Require().NoError(err) + s.execBankSend( + chain, + valIdx, + continuousVestingAcc.String(), + Address(), + balance.Sub(standardFees).String(), + standardFees.String(), + true, + ) + waitEndTime = acc.EndTime - time.Now().Unix() + vestingTxDelay + time.Sleep(time.Duration(waitEndTime) * time.Second) + } + + // Transfer coins should succeed + balance, err = getSpecificBalance(api, continuousVestingAcc.String(), uatomDenom) + s.Require().NoError(err) + s.execBankSend( + chain, + valIdx, + continuousVestingAcc.String(), + Address(), + balance.Sub(standardFees).String(), + standardFees.String(), + false, + ) + }) +} + +func (s *IntegrationTestSuite) testPeriodicVestingAccount(api string) { //nolint:unused + + s.Run("test periodic vesting genesis account", func() { + var ( + valIdx = 0 + chain = s.chainA + val = chain.validators[valIdx] + periodicVestingAddr = chain.genesisVestingAccounts[periodicVestingKey].String() + ) + sender, _ := val.keyInfo.GetAddress() + valOpAddr := sdk.ValAddress(sender).String() + + s.execCreatePeriodicVestingAccount( + chain, + periodicVestingAddr, + filepath.Join(gaiaHomePath, vestingPeriodFile), + withKeyValue(flagFrom, sender.String()), + ) + + acc, err := queryPeriodicVestingAccount(api, periodicVestingAddr) + s.Require().NoError(err) + + // Check address balance + balance, err := getSpecificBalance(api, periodicVestingAddr, uatomDenom) + s.Require().NoError(err) + + expectedBalance := sdk.NewCoin(uatomDenom, sdk.NewInt(0)) + for _, period := range acc.VestingPeriods { + // _, coin := ante.Find(period.Amount, uatomDenom) + _, coin := period.Amount.Find(uatomDenom) + expectedBalance = expectedBalance.Add(coin) + } + s.Require().Equal(expectedBalance, balance) + + waitStartTime := acc.StartTime - time.Now().Unix() + if waitStartTime > vestingTxDelay { + // Transfer coins should fail + balance, err = getSpecificBalance(api, periodicVestingAddr, uatomDenom) + s.Require().NoError(err) + s.execBankSend( + chain, + valIdx, + periodicVestingAddr, + Address(), + balance.Sub(standardFees).String(), + standardFees.String(), + true, + ) + waitStartTime = acc.StartTime - time.Now().Unix() + vestingTxDelay + time.Sleep(time.Duration(waitStartTime) * time.Second) + } + + firstPeriod := acc.StartTime + acc.VestingPeriods[0].Length + waitFirstPeriod := firstPeriod - time.Now().Unix() + if waitFirstPeriod > vestingTxDelay { + // Transfer coins should fail + balance, err = getSpecificBalance(api, periodicVestingAddr, uatomDenom) + s.Require().NoError(err) + s.execBankSend( + chain, + valIdx, + periodicVestingAddr, + Address(), + balance.Sub(standardFees).String(), + standardFees.String(), + true, + ) + waitFirstPeriod = firstPeriod - time.Now().Unix() + vestingTxDelay + time.Sleep(time.Duration(waitFirstPeriod) * time.Second) + } + + // Delegate coins should succeed + s.executeDelegate(chain, valIdx, vestingDelegationAmount.String(), valOpAddr, + periodicVestingAddr, gaiaHomePath, vestingDelegationFees.String()) + + // Validate delegation successful + s.Require().Eventually( + func() bool { + res, err := queryDelegation(api, valOpAddr, periodicVestingAddr) + amt := res.GetDelegationResponse().GetDelegation().GetShares() + s.Require().NoError(err) + + return amt.Equal(sdk.NewDecFromInt(vestingDelegationAmount.Amount)) + }, + 20*time.Second, + 5*time.Second, + ) + + // Transfer coins should succeed + balance, err = getSpecificBalance(api, periodicVestingAddr, uatomDenom) + s.Require().NoError(err) + s.execBankSend( + chain, + valIdx, + periodicVestingAddr, + Address(), + balance.Sub(standardFees).String(), + standardFees.String(), + false, + ) + + secondPeriod := firstPeriod + acc.VestingPeriods[1].Length + waitSecondPeriod := secondPeriod - time.Now().Unix() + if waitSecondPeriod > vestingTxDelay { + time.Sleep(time.Duration(waitSecondPeriod) * time.Second) + + // Transfer coins should succeed + balance, err = getSpecificBalance(api, periodicVestingAddr, uatomDenom) + s.Require().NoError(err) + s.execBankSend( + chain, + valIdx, + periodicVestingAddr, + Address(), + balance.Sub(standardFees).String(), + standardFees.String(), + false, + ) + } + }) +} + +// generateVestingPeriod generate the vesting period file +func generateVestingPeriod() ([]byte, error) { + p := vestingPeriod{ + StartTime: time.Now().Add(time.Duration(rand.Intn(20)+95) * time.Second).Unix(), + Periods: []period{ + { + Coins: "850000000" + uatomDenom, + Length: 35, + }, + { + Coins: "2000000000" + uatomDenom, + Length: 35, + }, + }, + } + return json.Marshal(p) +} diff --git a/tests/e2e/genesis.go b/tests/e2e/genesis.go index 37f50e2e8eb..00ea348bdbe 100644 --- a/tests/e2e/genesis.go +++ b/tests/e2e/genesis.go @@ -1,202 +1,220 @@ package e2e -// import ( -// "encoding/json" -// "fmt" -// "os" -// "time" - -// "github.com/cosmos/cosmos-sdk/server" -// sdk "github.com/cosmos/cosmos-sdk/types" -// authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" -// banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" -// "github.com/cosmos/cosmos-sdk/x/genutil" -// genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" -// govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" -// stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" -// icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" -// tmtypes "github.com/tendermint/tendermint/types" - -// globfeetypes "github.com/cosmos/gaia/v11/x/globalfee/types" -// ) - -// func getGenDoc(path string) (*tmtypes.GenesisDoc, error) { -// serverCtx := server.NewDefaultContext() -// config := serverCtx.Config -// config.SetRoot(path) - -// genFile := config.GenesisFile() -// doc := &tmtypes.GenesisDoc{} - -// if _, err := os.Stat(genFile); err != nil { -// if !os.IsNotExist(err) { -// return nil, err -// } -// } else { -// var err error - -// doc, err = tmtypes.GenesisDocFromFile(genFile) -// if err != nil { -// return nil, fmt.Errorf("failed to read genesis doc from file: %w", err) -// } -// } - -// return doc, nil -// } - -// func modifyGenesis(path, moniker, amountStr string, addrAll []sdk.AccAddress, globfees string, denom string) error { -// serverCtx := server.NewDefaultContext() -// config := serverCtx.Config -// config.SetRoot(path) -// config.Moniker = moniker - -// coins, err := sdk.ParseCoinsNormalized(amountStr) -// if err != nil { -// return fmt.Errorf("failed to parse coins: %w", err) -// } - -// var balances []banktypes.Balance -// var genAccounts []*authtypes.BaseAccount -// for _, addr := range addrAll { -// balance := banktypes.Balance{Address: addr.String(), Coins: coins.Sort()} -// balances = append(balances, balance) -// genAccount := authtypes.NewBaseAccount(addr, nil, 0, 0) -// genAccounts = append(genAccounts, genAccount) -// } - -// genFile := config.GenesisFile() -// appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) -// if err != nil { -// return fmt.Errorf("failed to unmarshal genesis state: %w", err) -// } - -// authGenState := authtypes.GetGenesisStateFromAppState(cdc, appState) -// accs, err := authtypes.UnpackAccounts(authGenState.Accounts) -// if err != nil { -// return fmt.Errorf("failed to get accounts from any: %w", err) -// } - -// for _, addr := range addrAll { -// if accs.Contains(addr) { -// return fmt.Errorf("failed to add account to genesis state; account already exists: %s", addr) -// } -// } - -// // Add the new account to the set of genesis accounts and sanitize the -// // accounts afterwards. -// for _, genAcct := range genAccounts { -// accs = append(accs, genAcct) -// accs = authtypes.SanitizeGenesisAccounts(accs) -// } - -// genAccs, err := authtypes.PackAccounts(accs) -// if err != nil { -// return fmt.Errorf("failed to convert accounts into any's: %w", err) -// } - -// authGenState.Accounts = genAccs - -// authGenStateBz, err := cdc.MarshalJSON(&authGenState) -// if err != nil { -// return fmt.Errorf("failed to marshal auth genesis state: %w", err) -// } -// appState[authtypes.ModuleName] = authGenStateBz - -// bankGenState := banktypes.GetGenesisStateFromAppState(cdc, appState) -// bankGenState.Balances = append(bankGenState.Balances, balances...) -// bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances) - -// bankGenStateBz, err := cdc.MarshalJSON(bankGenState) -// if err != nil { -// return fmt.Errorf("failed to marshal bank genesis state: %w", err) -// } -// appState[banktypes.ModuleName] = bankGenStateBz - -// // add ica host allowed msg types -// var icaGenesisState icatypes.GenesisState - -// if appState[icatypes.ModuleName] != nil { -// cdc.MustUnmarshalJSON(appState[icatypes.ModuleName], &icaGenesisState) -// } - -// icaGenesisState.HostGenesisState.Params.AllowMessages = []string{ -// "/cosmos.authz.v1beta1.MsgExec", -// "/cosmos.authz.v1beta1.MsgGrant", -// "/cosmos.authz.v1beta1.MsgRevoke", -// "/cosmos.bank.v1beta1.MsgSend", -// "/cosmos.bank.v1beta1.MsgMultiSend", -// "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", -// "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission", -// "/cosmos.distribution.v1beta1.MsgFundCommunityPool", -// "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", -// "/cosmos.feegrant.v1beta1.MsgGrantAllowance", -// "/cosmos.feegrant.v1beta1.MsgRevokeAllowance", -// "/cosmos.gov.v1beta1.MsgVoteWeighted", -// "/cosmos.gov.v1beta1.MsgSubmitProposal", -// "/cosmos.gov.v1beta1.MsgDeposit", -// "/cosmos.gov.v1beta1.MsgVote", -// "/cosmos.staking.v1beta1.MsgEditValidator", -// "/cosmos.staking.v1beta1.MsgDelegate", -// "/cosmos.staking.v1beta1.MsgUndelegate", -// "/cosmos.staking.v1beta1.MsgBeginRedelegate", -// "/cosmos.staking.v1beta1.MsgCreateValidator", -// "/cosmos.vesting.v1beta1.MsgCreateVestingAccount", -// "/ibc.applications.transfer.v1.MsgTransfer", -// "/tendermint.liquidity.v1beta1.MsgCreatePool", -// "/tendermint.liquidity.v1beta1.MsgSwapWithinBatch", -// "/tendermint.liquidity.v1beta1.MsgDepositWithinBatch", -// "/tendermint.liquidity.v1beta1.MsgWithdrawWithinBatch", -// } - -// icaGenesisStateBz, err := cdc.MarshalJSON(&icaGenesisState) -// if err != nil { -// return fmt.Errorf("failed to marshal interchain accounts genesis state: %w", err) -// } -// appState[icatypes.ModuleName] = icaGenesisStateBz - -// // setup global fee in genesis -// globfeeState := globfeetypes.GetGenesisStateFromAppState(cdc, appState) -// minGases, err := sdk.ParseDecCoins(globfees) -// if err != nil { -// return fmt.Errorf("failed to parse fee coins: %w", err) -// } -// globfeeState.Params.MinimumGasPrices = minGases -// globFeeStateBz, err := cdc.MarshalJSON(globfeeState) -// if err != nil { -// return fmt.Errorf("failed to marshal global fee genesis state: %w", err) -// } -// appState[globfeetypes.ModuleName] = globFeeStateBz - -// stakingGenState := stakingtypes.GetGenesisStateFromAppState(cdc, appState) -// stakingGenState.Params.BondDenom = denom -// stakingGenStateBz, err := cdc.MarshalJSON(stakingGenState) -// if err != nil { -// return fmt.Errorf("failed to marshal staking genesis state: %s", err) -// } -// appState[stakingtypes.ModuleName] = stakingGenStateBz - -// // Refactor to separate method -// amnt := sdk.NewInt(10000) -// quorum, _ := sdk.NewDecFromStr("0.000000000000000001") -// threshold, _ := sdk.NewDecFromStr("0.000000000000000001") - -// govState := govtypes.NewGenesisState(1, -// govtypes.NewDepositParams(sdk.NewCoins(sdk.NewCoin(denom, amnt)), 10*time.Minute), -// govtypes.NewVotingParams(15*time.Second), -// govtypes.NewTallyParams(quorum, threshold, govtypes.DefaultVetoThreshold), -// ) - -// govGenStateBz, err := cdc.MarshalJSON(govState) -// if err != nil { -// return fmt.Errorf("failed to marshal gov genesis state: %w", err) -// } -// appState[govtypes.ModuleName] = govGenStateBz - -// appStateJSON, err := json.Marshal(appState) -// if err != nil { -// return fmt.Errorf("failed to marshal application genesis state: %w", err) -// } -// genDoc.AppState = appStateJSON - -// return genutil.ExportGenesisFile(genDoc, genFile) -// } +import ( + "encoding/json" + "fmt" + "os" + "time" + + tmtypes "github.com/cometbft/cometbft/types" + "github.com/cosmos/cosmos-sdk/server" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/genutil" + + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + govmigrv3 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v3" + govmigrv4 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v4" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govlegacytypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + icagen "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + // + // globfeetypes "github.com/cosmos/gaia/v11/x/globalfee/types" +) + +func getGenDoc(path string) (*tmtypes.GenesisDoc, error) { + serverCtx := server.NewDefaultContext() + config := serverCtx.Config + config.SetRoot(path) + + genFile := config.GenesisFile() + doc := &tmtypes.GenesisDoc{} + + if _, err := os.Stat(genFile); err != nil { + if !os.IsNotExist(err) { + return nil, err + } + } else { + var err error + + doc, err = tmtypes.GenesisDocFromFile(genFile) + if err != nil { + return nil, fmt.Errorf("failed to read genesis doc from file: %w", err) + } + } + + return doc, nil +} + +func modifyGenesis(path, moniker, amountStr string, addrAll []sdk.AccAddress, globfees string, denom string) error { //nolint:unparam + serverCtx := server.NewDefaultContext() + config := serverCtx.Config + config.SetRoot(path) + config.Moniker = moniker + + coins, err := sdk.ParseCoinsNormalized(amountStr) + if err != nil { + return fmt.Errorf("failed to parse coins: %w", err) + } + + var balances []banktypes.Balance + var genAccounts []*authtypes.BaseAccount + for _, addr := range addrAll { + balance := banktypes.Balance{Address: addr.String(), Coins: coins.Sort()} + balances = append(balances, balance) + genAccount := authtypes.NewBaseAccount(addr, nil, 0, 0) + genAccounts = append(genAccounts, genAccount) + } + + genFile := config.GenesisFile() + appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) + if err != nil { + return fmt.Errorf("failed to unmarshal genesis state: %w", err) + } + + authGenState := authtypes.GetGenesisStateFromAppState(cdc, appState) + accs, err := authtypes.UnpackAccounts(authGenState.Accounts) + if err != nil { + return fmt.Errorf("failed to get accounts from any: %w", err) + } + + for _, addr := range addrAll { + if accs.Contains(addr) { + return fmt.Errorf("failed to add account to genesis state; account already exists: %s", addr) + } + } + + // Add the new account to the set of genesis accounts and sanitize the + // accounts afterwards. + for _, genAcct := range genAccounts { + accs = append(accs, genAcct) + accs = authtypes.SanitizeGenesisAccounts(accs) + } + + genAccs, err := authtypes.PackAccounts(accs) + if err != nil { + return fmt.Errorf("failed to convert accounts into any's: %w", err) + } + + authGenState.Accounts = genAccs + + authGenStateBz, err := cdc.MarshalJSON(&authGenState) + if err != nil { + return fmt.Errorf("failed to marshal auth genesis state: %w", err) + } + appState[authtypes.ModuleName] = authGenStateBz + + bankGenState := banktypes.GetGenesisStateFromAppState(cdc, appState) + bankGenState.Balances = append(bankGenState.Balances, balances...) + bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances) + + bankGenStateBz, err := cdc.MarshalJSON(bankGenState) + if err != nil { + return fmt.Errorf("failed to marshal bank genesis state: %w", err) + } + appState[banktypes.ModuleName] = bankGenStateBz + + // add ica host allowed msg types + var icaGenesisState icagen.GenesisState + + if appState[icatypes.ModuleName] != nil { + cdc.MustUnmarshalJSON(appState[icatypes.ModuleName], &icaGenesisState) + } + + icaGenesisState.HostGenesisState.Params.AllowMessages = []string{ + "/cosmos.authz.v1beta1.MsgExec", + "/cosmos.authz.v1beta1.MsgGrant", + "/cosmos.authz.v1beta1.MsgRevoke", + "/cosmos.bank.v1beta1.MsgSend", + "/cosmos.bank.v1beta1.MsgMultiSend", + "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", + "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission", + "/cosmos.distribution.v1beta1.MsgFundCommunityPool", + "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + "/cosmos.feegrant.v1beta1.MsgGrantAllowance", + "/cosmos.feegrant.v1beta1.MsgRevokeAllowance", + "/cosmos.gov.v1beta1.MsgVoteWeighted", + "/cosmos.gov.v1beta1.MsgSubmitProposal", + "/cosmos.gov.v1beta1.MsgDeposit", + "/cosmos.gov.v1beta1.MsgVote", + "/cosmos.staking.v1beta1.MsgEditValidator", + "/cosmos.staking.v1beta1.MsgDelegate", + "/cosmos.staking.v1beta1.MsgUndelegate", + "/cosmos.staking.v1beta1.MsgBeginRedelegate", + "/cosmos.staking.v1beta1.MsgCreateValidator", + "/cosmos.vesting.v1beta1.MsgCreateVestingAccount", + "/ibc.applications.transfer.v1.MsgTransfer", + "/tendermint.liquidity.v1beta1.MsgCreatePool", + "/tendermint.liquidity.v1beta1.MsgSwapWithinBatch", + "/tendermint.liquidity.v1beta1.MsgDepositWithinBatch", + "/tendermint.liquidity.v1beta1.MsgWithdrawWithinBatch", + } + + icaGenesisStateBz, err := cdc.MarshalJSON(&icaGenesisState) + if err != nil { + return fmt.Errorf("failed to marshal interchain accounts genesis state: %w", err) + } + appState[icatypes.ModuleName] = icaGenesisStateBz + + // setup global fee in genesis + // globfeeState := globfeetypes.GetGenesisStateFromAppState(cdc, appState) + // minGases, err := sdk.ParseDecCoins(globfees) + // if err != nil { + // return fmt.Errorf("failed to parse fee coins: %w", err) + // } + // globfeeState.Params.MinimumGasPrices = minGases + // globFeeStateBz, err := cdc.MarshalJSON(globfeeState) + // if err != nil { + // return fmt.Errorf("failed to marshal global fee genesis state: %w", err) + // } + // appState[globfeetypes.ModuleName] = globFeeStateBz + + stakingGenState := stakingtypes.GetGenesisStateFromAppState(cdc, appState) + stakingGenState.Params.BondDenom = denom + stakingGenStateBz, err := cdc.MarshalJSON(stakingGenState) + if err != nil { + return fmt.Errorf("failed to marshal staking genesis state: %s", err) + } + appState[stakingtypes.ModuleName] = stakingGenStateBz + + // Refactor to separate method + amnt := sdk.NewInt(10000) + quorum, _ := sdk.NewDecFromStr("0.000000000000000001") + threshold, _ := sdk.NewDecFromStr("0.000000000000000001") + + maxDepositPeriod := 10 * time.Minute + votingPeriod := 15 * time.Second + + govStateLegacy := govlegacytypes.NewGenesisState(1, + govlegacytypes.NewDepositParams(sdk.NewCoins(sdk.NewCoin(denom, amnt)), maxDepositPeriod), + govlegacytypes.NewVotingParams(votingPeriod), + govlegacytypes.NewTallyParams(quorum, threshold, govlegacytypes.DefaultVetoThreshold), + ) + + govStateV3, err := govmigrv3.MigrateJSON(govStateLegacy) + if err != nil { + return fmt.Errorf("failed to migrate v1beta1 gov genesis state to v3: %w", err) + } + + govStateV4, err := govmigrv4.MigrateJSON(govStateV3) + if err != nil { + return fmt.Errorf("failed to migrate v1beta1 gov genesis state to v4: %w", err) + } + + govGenStateBz, err := cdc.MarshalJSON(govStateV4) + if err != nil { + return fmt.Errorf("failed to marshal gov genesis state: %w", err) + } + appState[govtypes.ModuleName] = govGenStateBz + + appStateJSON, err := json.Marshal(appState) + if err != nil { + return fmt.Errorf("failed to marshal application genesis state: %w", err) + } + genDoc.AppState = appStateJSON + + return genutil.ExportGenesisFile(genDoc, genFile) +} diff --git a/tests/e2e/http_util.go b/tests/e2e/http_util.go index 539eea4dc64..593759ac8b7 100644 --- a/tests/e2e/http_util.go +++ b/tests/e2e/http_util.go @@ -1,40 +1,40 @@ package e2e -// import ( -// "encoding/json" -// "fmt" -// "io" -// "net/http" -// ) - -// func httpGet(endpoint string) ([]byte, error) { -// resp, err := http.Get(endpoint) //nolint:gosec // this is only used during tests -// if err != nil { -// return nil, fmt.Errorf("failed to execute HTTP request: %w", err) -// } -// defer resp.Body.Close() - -// body, err := io.ReadAll(resp.Body) -// if err != nil { -// return nil, err -// } - -// return body, nil -// } - -// func readJSON(resp *http.Response) (map[string]interface{}, error) { -// defer resp.Body.Close() - -// body, readErr := io.ReadAll(resp.Body) -// if readErr != nil { -// return nil, fmt.Errorf("failed to read Body") -// } - -// var data map[string]interface{} -// err := json.Unmarshal(body, &data) -// if err != nil { -// return nil, fmt.Errorf("failed to unmarshal response body") -// } - -// return data, nil -// } +import ( + "encoding/json" + "fmt" + "io" + "net/http" +) + +func httpGet(endpoint string) ([]byte, error) { + resp, err := http.Get(endpoint) //nolint:gosec // this is only used during tests + if err != nil { + return nil, fmt.Errorf("failed to execute HTTP request: %w", err) + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return body, nil +} + +func readJSON(resp *http.Response) (map[string]interface{}, error) { + defer resp.Body.Close() + + body, readErr := io.ReadAll(resp.Body) + if readErr != nil { + return nil, fmt.Errorf("failed to read Body") + } + + var data map[string]interface{} + err := json.Unmarshal(body, &data) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal response body") + } + + return data, nil +} diff --git a/tests/e2e/io.go b/tests/e2e/io.go index e9b58ab3668..40b316bec48 100644 --- a/tests/e2e/io.go +++ b/tests/e2e/io.go @@ -1,44 +1,44 @@ package e2e -// import ( -// "fmt" -// "io" -// "os" -// ) - -// // copyFile copy file from src to dst -// func copyFile(src, dst string) (int64, error) { -// sourceFileStat, err := os.Stat(src) -// if err != nil { -// return 0, err -// } - -// if !sourceFileStat.Mode().IsRegular() { -// return 0, fmt.Errorf("%s is not a regular file", src) -// } - -// source, err := os.Open(src) -// if err != nil { -// return 0, err -// } -// defer source.Close() - -// destination, err := os.Create(dst) -// if err != nil { -// return 0, err -// } -// defer destination.Close() - -// nBytes, err := io.Copy(destination, source) -// return nBytes, err -// } - -// // writeFile write a byte slice into a file path -// func writeFile(path string, body []byte) error { -// _, err := os.Create(path) -// if err != nil { -// return err -// } - -// return os.WriteFile(path, body, 0o600) -// } +import ( + "fmt" + "io" + "os" +) + +// copyFile copy file from src to dst +func copyFile(src, dst string) (int64, error) { //nolint:unparam + sourceFileStat, err := os.Stat(src) + if err != nil { + return 0, err + } + + if !sourceFileStat.Mode().IsRegular() { + return 0, fmt.Errorf("%s is not a regular file", src) + } + + source, err := os.Open(src) + if err != nil { + return 0, err + } + defer source.Close() + + destination, err := os.Create(dst) + if err != nil { + return 0, err + } + defer destination.Close() + + nBytes, err := io.Copy(destination, source) + return nBytes, err +} + +// writeFile write a byte slice into a file path +func writeFile(path string, body []byte) error { + _, err := os.Create(path) + if err != nil { + return err + } + + return os.WriteFile(path, body, 0o600) +} diff --git a/tests/e2e/keys.go b/tests/e2e/keys.go index 53740d5d715..d47a7ce59d0 100644 --- a/tests/e2e/keys.go +++ b/tests/e2e/keys.go @@ -1,21 +1,20 @@ package e2e -// -// import ( -// "github.com/cosmos/go-bip39" -//) -// -//// createMnemonic creates a random string mnemonic -// func createMnemonic() (string, error) { -// entropySeed, err := bip39.NewEntropy(256) -// if err != nil { -// return "", err -// } -// -// mnemonic, err := bip39.NewMnemonic(entropySeed) -// if err != nil { -// return "", err -// } -// -// return mnemonic, nil -//} +import ( + "github.com/cosmos/go-bip39" +) + +// createMnemonic creates a random string mnemonic +func createMnemonic() (string, error) { + entropySeed, err := bip39.NewEntropy(256) + if err != nil { + return "", err + } + + mnemonic, err := bip39.NewMnemonic(entropySeed) + if err != nil { + return "", err + } + + return mnemonic, nil +} diff --git a/tests/e2e/query.go b/tests/e2e/query.go index 6aa90e921ff..433385b1ff8 100644 --- a/tests/e2e/query.go +++ b/tests/e2e/query.go @@ -1,78 +1,77 @@ package e2e -// import ( -// "encoding/json" -// "fmt" -// "io" -// "net/http" -// "strings" - -// sdk "github.com/cosmos/cosmos-sdk/types" -// authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" -// authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" -// banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" -// disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" -// evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" - -// govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" -// stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - -// "github.com/cosmos/gaia/v11/x/globalfee/types" -// ) - -// func queryGaiaTx(endpoint, txHash string) error { -// resp, err := http.Get(fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", endpoint, txHash)) -// if err != nil { -// return fmt.Errorf("failed to execute HTTP request: %w", err) -// } - -// defer resp.Body.Close() - -// if resp.StatusCode != 200 { -// return fmt.Errorf("tx query returned non-200 status: %d", resp.StatusCode) -// } - -// var result map[string]interface{} -// if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { -// return fmt.Errorf("failed to read response body: %w", err) -// } - -// txResp := result["tx_response"].(map[string]interface{}) -// if v := txResp["code"]; v.(float64) != 0 { -// return fmt.Errorf("tx %s failed with status code %v", txHash, v) -// } - -// return nil -// } - -// // if coin is zero, return empty coin. -// func getSpecificBalance(endpoint, addr, denom string) (amt sdk.Coin, err error) { -// balances, err := queryGaiaAllBalances(endpoint, addr) -// if err != nil { -// return amt, err -// } -// for _, c := range balances { -// if strings.Contains(c.Denom, denom) { -// amt = c -// break -// } -// } -// return amt, nil -// } - -// func queryGaiaAllBalances(endpoint, addr string) (sdk.Coins, error) { -// body, err := httpGet(fmt.Sprintf("%s/cosmos/bank/v1beta1/balances/%s", endpoint, addr)) -// if err != nil { -// return nil, fmt.Errorf("failed to execute HTTP request: %w", err) -// } - -// var balancesResp banktypes.QueryAllBalancesResponse -// if err := cdc.UnmarshalJSON(body, &balancesResp); err != nil { -// return nil, err -// } - -// return balancesResp.Balances, nil -// } +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +func queryGaiaTx(endpoint, txHash string) error { + resp, err := http.Get(fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", endpoint, txHash)) + if err != nil { + return fmt.Errorf("failed to execute HTTP request: %w", err) + } + + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return fmt.Errorf("tx query returned non-200 status: %d", resp.StatusCode) + } + + var result map[string]interface{} + if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { + return fmt.Errorf("failed to read response body: %w", err) + } + + txResp := result["tx_response"].(map[string]interface{}) + if v := txResp["code"]; v.(float64) != 0 { + return fmt.Errorf("tx %s failed with status code %v", txHash, v) + } + + return nil +} + +// if coin is zero, return empty coin. +func getSpecificBalance(endpoint, addr, denom string) (amt sdk.Coin, err error) { + balances, err := queryGaiaAllBalances(endpoint, addr) + if err != nil { + return amt, err + } + for _, c := range balances { + if strings.Contains(c.Denom, denom) { + amt = c + break + } + } + return amt, nil +} + +func queryGaiaAllBalances(endpoint, addr string) (sdk.Coins, error) { + body, err := httpGet(fmt.Sprintf("%s/cosmos/bank/v1beta1/balances/%s", endpoint, addr)) + if err != nil { + return nil, fmt.Errorf("failed to execute HTTP request: %w", err) + } + + var balancesResp banktypes.QueryAllBalancesResponse + if err := cdc.UnmarshalJSON(body, &balancesResp); err != nil { + return nil, err + } + + return balancesResp.Balances, nil +} // func queryGlobalFeeParams(endpoint string) (types.QueryParamsResponse, error) { // body, err := httpGet(fmt.Sprintf("%s/gaia/globalfee/v1beta1/params", endpoint)) @@ -106,108 +105,108 @@ package e2e // return p.Params.MaxTotalBypassMinFeeMsgGasUsage, err // } -// func queryDelegation(endpoint string, validatorAddr string, delegatorAddr string) (stakingtypes.QueryDelegationResponse, error) { -// var res stakingtypes.QueryDelegationResponse - -// body, err := httpGet(fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s", endpoint, validatorAddr, delegatorAddr)) -// if err != nil { -// return res, err -// } - -// if err = cdc.UnmarshalJSON(body, &res); err != nil { -// return res, err -// } -// return res, nil -// } - -// func queryDelegatorWithdrawalAddress(endpoint string, delegatorAddr string) (disttypes.QueryDelegatorWithdrawAddressResponse, error) { -// var res disttypes.QueryDelegatorWithdrawAddressResponse - -// body, err := httpGet(fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/withdraw_address", endpoint, delegatorAddr)) -// if err != nil { -// return res, err -// } - -// if err = cdc.UnmarshalJSON(body, &res); err != nil { -// return res, err -// } -// return res, nil -// } - -// func queryDelegatorTotalRewards(endpoint, delegatorAddr string) (disttypes.QueryDelegationTotalRewardsResponse, error) { -// var res disttypes.QueryDelegationTotalRewardsResponse - -// body, err := httpGet(fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/rewards", endpoint, delegatorAddr)) -// if err != nil { -// return res, err -// } - -// if err = cdc.UnmarshalJSON(body, &res); err != nil { -// return res, err -// } - -// return res, nil -// } - -// func queryGovProposal(endpoint string, proposalID int) (govtypes.QueryProposalResponse, error) { -// var govProposalResp govtypes.QueryProposalResponse - -// path := fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%d", endpoint, proposalID) - -// body, err := httpGet(path) -// if err != nil { -// return govProposalResp, fmt.Errorf("failed to execute HTTP request: %w", err) -// } -// if err := cdc.UnmarshalJSON(body, &govProposalResp); err != nil { -// return govProposalResp, err -// } - -// return govProposalResp, nil -// } - -// func queryAccount(endpoint, address string) (acc authtypes.AccountI, err error) { -// var res authtypes.QueryAccountResponse -// resp, err := http.Get(fmt.Sprintf("%s/cosmos/auth/v1beta1/accounts/%s", endpoint, address)) -// if err != nil { -// return nil, fmt.Errorf("failed to execute HTTP request: %w", err) -// } -// defer resp.Body.Close() - -// bz, err := io.ReadAll(resp.Body) -// if err != nil { -// return nil, err -// } -// if err := cdc.UnmarshalJSON(bz, &res); err != nil { -// return nil, err -// } -// return acc, cdc.UnpackAny(res.Account, &acc) -// } - -// func queryDelayedVestingAccount(endpoint, address string) (authvesting.DelayedVestingAccount, error) { -// baseAcc, err := queryAccount(endpoint, address) -// if err != nil { -// return authvesting.DelayedVestingAccount{}, err -// } -// acc, ok := baseAcc.(*authvesting.DelayedVestingAccount) -// if !ok { -// return authvesting.DelayedVestingAccount{}, -// fmt.Errorf("cannot cast %v to DelayedVestingAccount", baseAcc) -// } -// return *acc, nil -// } - -// func queryContinuousVestingAccount(endpoint, address string) (authvesting.ContinuousVestingAccount, error) { -// baseAcc, err := queryAccount(endpoint, address) -// if err != nil { -// return authvesting.ContinuousVestingAccount{}, err -// } -// acc, ok := baseAcc.(*authvesting.ContinuousVestingAccount) -// if !ok { -// return authvesting.ContinuousVestingAccount{}, -// fmt.Errorf("cannot cast %v to ContinuousVestingAccount", baseAcc) -// } -// return *acc, nil -// } +func queryDelegation(endpoint string, validatorAddr string, delegatorAddr string) (stakingtypes.QueryDelegationResponse, error) { + var res stakingtypes.QueryDelegationResponse + + body, err := httpGet(fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s/delegations/%s", endpoint, validatorAddr, delegatorAddr)) + if err != nil { + return res, err + } + + if err = cdc.UnmarshalJSON(body, &res); err != nil { + return res, err + } + return res, nil +} + +func queryDelegatorWithdrawalAddress(endpoint string, delegatorAddr string) (disttypes.QueryDelegatorWithdrawAddressResponse, error) { + var res disttypes.QueryDelegatorWithdrawAddressResponse + + body, err := httpGet(fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/withdraw_address", endpoint, delegatorAddr)) + if err != nil { + return res, err + } + + if err = cdc.UnmarshalJSON(body, &res); err != nil { + return res, err + } + return res, nil +} + +func queryDelegatorTotalRewards(endpoint, delegatorAddr string) (disttypes.QueryDelegationTotalRewardsResponse, error) { //nolint:unused + var res disttypes.QueryDelegationTotalRewardsResponse + + body, err := httpGet(fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/rewards", endpoint, delegatorAddr)) + if err != nil { + return res, err + } + + if err = cdc.UnmarshalJSON(body, &res); err != nil { + return res, err + } + + return res, nil +} + +func queryGovProposal(endpoint string, proposalID int) (govtypesv1beta1.QueryProposalResponse, error) { + var govProposalResp govtypesv1beta1.QueryProposalResponse + + path := fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%d", endpoint, proposalID) + + body, err := httpGet(path) + if err != nil { + return govProposalResp, fmt.Errorf("failed to execute HTTP request: %w", err) + } + if err := cdc.UnmarshalJSON(body, &govProposalResp); err != nil { + return govProposalResp, err + } + + return govProposalResp, nil +} + +func queryAccount(endpoint, address string) (acc authtypes.AccountI, err error) { + var res authtypes.QueryAccountResponse + resp, err := http.Get(fmt.Sprintf("%s/cosmos/auth/v1beta1/accounts/%s", endpoint, address)) + if err != nil { + return nil, fmt.Errorf("failed to execute HTTP request: %w", err) + } + defer resp.Body.Close() + + bz, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + if err := cdc.UnmarshalJSON(bz, &res); err != nil { + return nil, err + } + return acc, cdc.UnpackAny(res.Account, &acc) +} + +func queryDelayedVestingAccount(endpoint, address string) (authvesting.DelayedVestingAccount, error) { + baseAcc, err := queryAccount(endpoint, address) + if err != nil { + return authvesting.DelayedVestingAccount{}, err + } + acc, ok := baseAcc.(*authvesting.DelayedVestingAccount) + if !ok { + return authvesting.DelayedVestingAccount{}, + fmt.Errorf("cannot cast %v to DelayedVestingAccount", baseAcc) + } + return *acc, nil +} + +func queryContinuousVestingAccount(endpoint, address string) (authvesting.ContinuousVestingAccount, error) { + baseAcc, err := queryAccount(endpoint, address) + if err != nil { + return authvesting.ContinuousVestingAccount{}, err + } + acc, ok := baseAcc.(*authvesting.ContinuousVestingAccount) + if !ok { + return authvesting.ContinuousVestingAccount{}, + fmt.Errorf("cannot cast %v to ContinuousVestingAccount", baseAcc) + } + return *acc, nil +} // func queryPermanentLockedAccount(endpoint, address string) (authvesting.PermanentLockedAccount, error) { //nolint:unused // this is called during e2e tests // baseAcc, err := queryAccount(endpoint, address) @@ -222,68 +221,68 @@ package e2e // return *acc, nil // } -// func queryPeriodicVestingAccount(endpoint, address string) (authvesting.PeriodicVestingAccount, error) { //nolint:unused // this is called during e2e tests -// baseAcc, err := queryAccount(endpoint, address) -// if err != nil { -// return authvesting.PeriodicVestingAccount{}, err -// } -// acc, ok := baseAcc.(*authvesting.PeriodicVestingAccount) -// if !ok { -// return authvesting.PeriodicVestingAccount{}, -// fmt.Errorf("cannot cast %v to PeriodicVestingAccount", baseAcc) -// } -// return *acc, nil -// } - -// func queryValidator(endpoint, address string) (stakingtypes.Validator, error) { -// var res stakingtypes.QueryValidatorResponse - -// body, err := httpGet(fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s", endpoint, address)) -// if err != nil { -// return stakingtypes.Validator{}, fmt.Errorf("failed to execute HTTP request: %w", err) -// } - -// if err := cdc.UnmarshalJSON(body, &res); err != nil { -// return stakingtypes.Validator{}, err -// } -// return res.Validator, nil -// } - -// func queryValidators(endpoint string) (stakingtypes.Validators, error) { -// var res stakingtypes.QueryValidatorsResponse -// body, err := httpGet(fmt.Sprintf("%s/cosmos/staking/v1beta1/validators", endpoint)) -// if err != nil { -// return nil, fmt.Errorf("failed to execute HTTP request: %w", err) -// } - -// if err := cdc.UnmarshalJSON(body, &res); err != nil { -// return nil, err -// } -// return res.Validators, nil -// } - -// func queryEvidence(endpoint, hash string) (evidencetypes.QueryEvidenceResponse, error) { //nolint:unused // this is called during e2e tests -// var res evidencetypes.QueryEvidenceResponse -// body, err := httpGet(fmt.Sprintf("%s/cosmos/evidence/v1beta1/evidence/%s", endpoint, hash)) -// if err != nil { -// return res, err -// } - -// if err = cdc.UnmarshalJSON(body, &res); err != nil { -// return res, err -// } -// return res, nil -// } - -// func queryAllEvidence(endpoint string) (evidencetypes.QueryAllEvidenceResponse, error) { -// var res evidencetypes.QueryAllEvidenceResponse -// body, err := httpGet(fmt.Sprintf("%s/cosmos/evidence/v1beta1/evidence", endpoint)) -// if err != nil { -// return res, err -// } - -// if err = cdc.UnmarshalJSON(body, &res); err != nil { -// return res, err -// } -// return res, nil -// } +func queryPeriodicVestingAccount(endpoint, address string) (authvesting.PeriodicVestingAccount, error) { //nolint:unused // this is called during e2e tests + baseAcc, err := queryAccount(endpoint, address) + if err != nil { + return authvesting.PeriodicVestingAccount{}, err + } + acc, ok := baseAcc.(*authvesting.PeriodicVestingAccount) + if !ok { + return authvesting.PeriodicVestingAccount{}, + fmt.Errorf("cannot cast %v to PeriodicVestingAccount", baseAcc) + } + return *acc, nil +} + +func queryValidator(endpoint, address string) (stakingtypes.Validator, error) { + var res stakingtypes.QueryValidatorResponse + + body, err := httpGet(fmt.Sprintf("%s/cosmos/staking/v1beta1/validators/%s", endpoint, address)) + if err != nil { + return stakingtypes.Validator{}, fmt.Errorf("failed to execute HTTP request: %w", err) + } + + if err := cdc.UnmarshalJSON(body, &res); err != nil { + return stakingtypes.Validator{}, err + } + return res.Validator, nil +} + +func queryValidators(endpoint string) (stakingtypes.Validators, error) { + var res stakingtypes.QueryValidatorsResponse + body, err := httpGet(fmt.Sprintf("%s/cosmos/staking/v1beta1/validators", endpoint)) + if err != nil { + return nil, fmt.Errorf("failed to execute HTTP request: %w", err) + } + + if err := cdc.UnmarshalJSON(body, &res); err != nil { + return nil, err + } + return res.Validators, nil +} + +func queryEvidence(endpoint, hash string) (evidencetypes.QueryEvidenceResponse, error) { //nolint:unused // this is called during e2e tests + var res evidencetypes.QueryEvidenceResponse + body, err := httpGet(fmt.Sprintf("%s/cosmos/evidence/v1beta1/evidence/%s", endpoint, hash)) + if err != nil { + return res, err + } + + if err = cdc.UnmarshalJSON(body, &res); err != nil { + return res, err + } + return res, nil +} + +func queryAllEvidence(endpoint string) (evidencetypes.QueryAllEvidenceResponse, error) { + var res evidencetypes.QueryAllEvidenceResponse + body, err := httpGet(fmt.Sprintf("%s/cosmos/evidence/v1beta1/evidence", endpoint)) + if err != nil { + return res, err + } + + if err = cdc.UnmarshalJSON(body, &res); err != nil { + return res, err + } + return res, nil +} diff --git a/tests/e2e/scripts/hermes_bootstrap.sh b/tests/e2e/scripts/hermes_bootstrap.sh index dac73d254eb..cc360b759bf 100755 --- a/tests/e2e/scripts/hermes_bootstrap.sh +++ b/tests/e2e/scripts/hermes_bootstrap.sh @@ -83,3 +83,4 @@ hermes keys add --key-name rly01-gaia-a --chain $GAIA_A_E2E_CHAIN_ID --mnemoni sleep 5 # start Hermes relayer hermes start +# hermes listen --chain $GAIA_B_E2E_CHAIN_ID \ No newline at end of file diff --git a/tests/e2e/util.go b/tests/e2e/util.go index aae773f18e8..ae136313e3c 100644 --- a/tests/e2e/util.go +++ b/tests/e2e/util.go @@ -1,53 +1,52 @@ package e2e -// -// import ( -// "fmt" -// -// "github.com/cosmos/cosmos-sdk/codec/unknownproto" -// sdktx "github.com/cosmos/cosmos-sdk/types/tx" -//) -// -// func decodeTx(txBytes []byte) (*sdktx.Tx, error) { -// var raw sdktx.TxRaw -// -// // reject all unknown proto fields in the root TxRaw -// err := unknownproto.RejectUnknownFieldsStrict(txBytes, &raw, encodingConfig.InterfaceRegistry) -// if err != nil { -// return nil, fmt.Errorf("failed to reject unknown fields: %w", err) -// } -// -// if err := cdc.Unmarshal(txBytes, &raw); err != nil { -// return nil, err -// } -// -// var body sdktx.TxBody -// if err := cdc.Unmarshal(raw.BodyBytes, &body); err != nil { -// return nil, fmt.Errorf("failed to decode tx: %w", err) -// } -// -// var authInfo sdktx.AuthInfo -// -// // reject all unknown proto fields in AuthInfo -// err = unknownproto.RejectUnknownFieldsStrict(raw.AuthInfoBytes, &authInfo, encodingConfig.InterfaceRegistry) -// if err != nil { -// return nil, fmt.Errorf("failed to reject unknown fields: %w", err) -// } -// -// if err := cdc.Unmarshal(raw.AuthInfoBytes, &authInfo); err != nil { -// return nil, fmt.Errorf("failed to decode auth info: %w", err) -// } -// -// return &sdktx.Tx{ -// Body: &body, -// AuthInfo: &authInfo, -// Signatures: raw.Signatures, -// }, nil -//} -// -// func concatFlags(originalCollection []string, commandFlags []string, generalFlags []string) []string { -// originalCollection = append(originalCollection, commandFlags...) -// originalCollection = append(originalCollection, generalFlags...) -// -// return originalCollection -//} +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/codec/unknownproto" + sdktx "github.com/cosmos/cosmos-sdk/types/tx" +) + +func decodeTx(txBytes []byte) (*sdktx.Tx, error) { + var raw sdktx.TxRaw + + // reject all unknown proto fields in the root TxRaw + err := unknownproto.RejectUnknownFieldsStrict(txBytes, &raw, encodingConfig.InterfaceRegistry) + if err != nil { + return nil, fmt.Errorf("failed to reject unknown fields: %w", err) + } + + if err := cdc.Unmarshal(txBytes, &raw); err != nil { + return nil, err + } + + var body sdktx.TxBody + if err := cdc.Unmarshal(raw.BodyBytes, &body); err != nil { + return nil, fmt.Errorf("failed to decode tx: %w", err) + } + + var authInfo sdktx.AuthInfo + + // reject all unknown proto fields in AuthInfo + err = unknownproto.RejectUnknownFieldsStrict(raw.AuthInfoBytes, &authInfo, encodingConfig.InterfaceRegistry) + if err != nil { + return nil, fmt.Errorf("failed to reject unknown fields: %w", err) + } + + if err := cdc.Unmarshal(raw.AuthInfoBytes, &authInfo); err != nil { + return nil, fmt.Errorf("failed to decode auth info: %w", err) + } + + return &sdktx.Tx{ + Body: &body, + AuthInfo: &authInfo, + Signatures: raw.Signatures, + }, nil +} + +func concatFlags(originalCollection []string, commandFlags []string, generalFlags []string) []string { + originalCollection = append(originalCollection, commandFlags...) + originalCollection = append(originalCollection, generalFlags...) + + return originalCollection +} diff --git a/tests/e2e/validator.go b/tests/e2e/validator.go index 2e81c1251bd..c9583bf4255 100644 --- a/tests/e2e/validator.go +++ b/tests/e2e/validator.go @@ -1,319 +1,338 @@ package e2e -// import ( -// "encoding/json" -// "fmt" -// "os" -// "path" -// "path/filepath" - -// sdkcrypto "github.com/cosmos/cosmos-sdk/crypto" -// cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" -// "github.com/cosmos/cosmos-sdk/crypto/hd" -// "github.com/cosmos/cosmos-sdk/crypto/keyring" -// cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" -// "github.com/cosmos/cosmos-sdk/server" -// sdk "github.com/cosmos/cosmos-sdk/types" -// sdktx "github.com/cosmos/cosmos-sdk/types/tx" -// txsigning "github.com/cosmos/cosmos-sdk/types/tx/signing" -// authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" -// "github.com/cosmos/cosmos-sdk/x/genutil" -// stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" -// tmcfg "github.com/tendermint/tendermint/config" -// tmos "github.com/tendermint/tendermint/libs/os" -// "github.com/tendermint/tendermint/p2p" -// "github.com/tendermint/tendermint/privval" - -// gaia "github.com/cosmos/gaia/v11/app" -// ) - -// //nolint:unused -// type validator struct { -// chain *chain -// index int -// moniker string -// mnemonic string -// keyInfo keyring.Info -// privateKey cryptotypes.PrivKey -// consensusKey privval.FilePVKey -// consensusPrivKey cryptotypes.PrivKey -// nodeKey p2p.NodeKey -// } - -// type account struct { -// moniker string //nolint:unused -// mnemonic string -// keyInfo keyring.Info -// privateKey cryptotypes.PrivKey -// } - -// func (v *validator) instanceName() string { -// return fmt.Sprintf("%s%d", v.moniker, v.index) -// } - -// func (v *validator) configDir() string { -// return fmt.Sprintf("%s/%s", v.chain.configDir(), v.instanceName()) -// } - -// func (v *validator) createConfig() error { -// p := path.Join(v.configDir(), "config") -// return os.MkdirAll(p, 0o755) -// } - -// func (v *validator) init() error { -// if err := v.createConfig(); err != nil { -// return err -// } - -// serverCtx := server.NewDefaultContext() -// config := serverCtx.Config - -// config.SetRoot(v.configDir()) -// config.Moniker = v.moniker - -// genDoc, err := getGenDoc(v.configDir()) -// if err != nil { -// return err -// } - -// appState, err := json.MarshalIndent(gaia.ModuleBasics.DefaultGenesis(cdc), "", " ") -// if err != nil { -// return fmt.Errorf("failed to JSON encode app genesis state: %w", err) -// } - -// genDoc.ChainID = v.chain.id -// genDoc.Validators = nil -// genDoc.AppState = appState - -// if err = genutil.ExportGenesisFile(genDoc, config.GenesisFile()); err != nil { -// return fmt.Errorf("failed to export app genesis state: %w", err) -// } - -// tmcfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config) -// return nil -// } - -// func (v *validator) createNodeKey() error { -// serverCtx := server.NewDefaultContext() -// config := serverCtx.Config - -// config.SetRoot(v.configDir()) -// config.Moniker = v.moniker - -// nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) -// if err != nil { -// return err -// } - -// v.nodeKey = *nodeKey -// return nil -// } - -// func (v *validator) createConsensusKey() error { -// serverCtx := server.NewDefaultContext() -// config := serverCtx.Config - -// config.SetRoot(v.configDir()) -// config.Moniker = v.moniker - -// pvKeyFile := config.PrivValidatorKeyFile() -// if err := tmos.EnsureDir(filepath.Dir(pvKeyFile), 0o777); err != nil { -// return err -// } - -// pvStateFile := config.PrivValidatorStateFile() -// if err := tmos.EnsureDir(filepath.Dir(pvStateFile), 0o777); err != nil { -// return err -// } - -// filePV := privval.LoadOrGenFilePV(pvKeyFile, pvStateFile) -// v.consensusKey = filePV.Key - -// return nil -// } - -// func (v *validator) createKeyFromMnemonic(name, mnemonic string) error { -// dir := v.configDir() -// kb, err := keyring.New(keyringAppName, keyring.BackendTest, dir, nil) -// if err != nil { -// return err -// } - -// keyringAlgos, _ := kb.SupportedAlgorithms() -// algo, err := keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), keyringAlgos) -// if err != nil { -// return err -// } - -// info, err := kb.NewAccount(name, mnemonic, "", sdk.FullFundraiserPath, algo) -// if err != nil { -// return err -// } - -// privKeyArmor, err := kb.ExportPrivKeyArmor(name, keyringPassphrase) -// if err != nil { -// return err -// } - -// privKey, _, err := sdkcrypto.UnarmorDecryptPrivKey(privKeyArmor, keyringPassphrase) -// if err != nil { -// return err -// } - -// v.keyInfo = info -// v.mnemonic = mnemonic -// v.privateKey = privKey - -// return nil -// } - -// func (c *chain) addAccountFromMnemonic(counts int) error { -// val0ConfigDir := c.validators[0].configDir() -// kb, err := keyring.New(keyringAppName, keyring.BackendTest, val0ConfigDir, nil) -// if err != nil { -// return err -// } - -// keyringAlgos, _ := kb.SupportedAlgorithms() -// algo, err := keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), keyringAlgos) -// if err != nil { -// return err -// } - -// for i := 0; i < counts; i++ { -// name := fmt.Sprintf("acct-%d", i) -// mnemonic, err := createMnemonic() -// if err != nil { -// return err -// } -// info, err := kb.NewAccount(name, mnemonic, "", sdk.FullFundraiserPath, algo) -// if err != nil { -// return err -// } - -// privKeyArmor, err := kb.ExportPrivKeyArmor(name, keyringPassphrase) -// if err != nil { -// return err -// } - -// privKey, _, err := sdkcrypto.UnarmorDecryptPrivKey(privKeyArmor, keyringPassphrase) -// if err != nil { -// return err -// } -// acct := account{} -// acct.keyInfo = info -// acct.mnemonic = mnemonic -// acct.privateKey = privKey -// c.genesisAccounts = append(c.genesisAccounts, &acct) -// } - -// return nil -// } - -// func (v *validator) createKey(name string) error { -// mnemonic, err := createMnemonic() -// if err != nil { -// return err -// } - -// return v.createKeyFromMnemonic(name, mnemonic) -// } - -// func (v *validator) buildCreateValidatorMsg(amount sdk.Coin) (sdk.Msg, error) { -// description := stakingtypes.NewDescription(v.moniker, "", "", "", "") -// commissionRates := stakingtypes.CommissionRates{ -// Rate: sdk.MustNewDecFromStr("0.1"), -// MaxRate: sdk.MustNewDecFromStr("0.2"), -// MaxChangeRate: sdk.MustNewDecFromStr("0.01"), -// } - -// // get the initial validator min self delegation -// minSelfDelegation := sdk.OneInt() - -// valPubKey, err := cryptocodec.FromTmPubKeyInterface(v.consensusKey.PubKey) -// if err != nil { -// return nil, err -// } - -// return stakingtypes.NewMsgCreateValidator( -// sdk.ValAddress(v.keyInfo.GetAddress()), -// valPubKey, -// amount, -// description, -// commissionRates, -// minSelfDelegation, -// ) -// } - -// func (v *validator) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) { -// txBuilder := encodingConfig.TxConfig.NewTxBuilder() - -// if err := txBuilder.SetMsgs(msgs...); err != nil { -// return nil, err -// } - -// txBuilder.SetMemo(fmt.Sprintf("%s@%s:26656", v.nodeKey.ID(), v.instanceName())) -// txBuilder.SetFeeAmount(sdk.NewCoins()) -// txBuilder.SetGasLimit(200000) - -// signerData := authsigning.SignerData{ -// ChainID: v.chain.id, -// AccountNumber: 0, -// Sequence: 0, -// } - -// // For SIGN_MODE_DIRECT, calling SetSignatures calls setSignerInfos on -// // TxBuilder under the hood, and SignerInfos is needed to generate the sign -// // bytes. This is the reason for setting SetSignatures here, with a nil -// // signature. -// // -// // Note: This line is not needed for SIGN_MODE_LEGACY_AMINO, but putting it -// // also doesn't affect its generated sign bytes, so for code's simplicity -// // sake, we put it here. -// sig := txsigning.SignatureV2{ -// PubKey: v.keyInfo.GetPubKey(), -// Data: &txsigning.SingleSignatureData{ -// SignMode: txsigning.SignMode_SIGN_MODE_DIRECT, -// Signature: nil, -// }, -// Sequence: 0, -// } - -// if err := txBuilder.SetSignatures(sig); err != nil { -// return nil, err -// } - -// bytesToSign, err := encodingConfig.TxConfig.SignModeHandler().GetSignBytes( -// txsigning.SignMode_SIGN_MODE_DIRECT, -// signerData, -// txBuilder.GetTx(), -// ) -// if err != nil { -// return nil, err -// } - -// sigBytes, err := v.privateKey.Sign(bytesToSign) -// if err != nil { -// return nil, err -// } - -// sig = txsigning.SignatureV2{ -// PubKey: v.keyInfo.GetPubKey(), -// Data: &txsigning.SingleSignatureData{ -// SignMode: txsigning.SignMode_SIGN_MODE_DIRECT, -// Signature: sigBytes, -// }, -// Sequence: 0, -// } -// if err := txBuilder.SetSignatures(sig); err != nil { -// return nil, err -// } - -// signedTx := txBuilder.GetTx() -// bz, err := encodingConfig.TxConfig.TxEncoder()(signedTx) -// if err != nil { -// return nil, err -// } - -// return decodeTx(bz) -// } +import ( + "encoding/json" + "fmt" + "os" + "path" + "path/filepath" + + tmcfg "github.com/cometbft/cometbft/config" + tmos "github.com/cometbft/cometbft/libs/os" + "github.com/cometbft/cometbft/p2p" + "github.com/cometbft/cometbft/privval" + + sdkcrypto "github.com/cosmos/cosmos-sdk/crypto" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/x/genutil" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdktx "github.com/cosmos/cosmos-sdk/types/tx" + txsigning "github.com/cosmos/cosmos-sdk/types/tx/signing" + + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + gaia "github.com/cosmos/gaia/v11/app" +) + +// +//nolint:unused +type validator struct { + chain *chain + index int + moniker string + mnemonic string + keyInfo keyring.Record + privateKey cryptotypes.PrivKey + consensusKey privval.FilePVKey + consensusPrivKey cryptotypes.PrivKey + nodeKey p2p.NodeKey +} + +type account struct { + moniker string //nolint:unused + mnemonic string + keyInfo keyring.Record + privateKey cryptotypes.PrivKey +} + +func (v *validator) instanceName() string { + return fmt.Sprintf("%s%d", v.moniker, v.index) +} + +func (v *validator) configDir() string { + return fmt.Sprintf("%s/%s", v.chain.configDir(), v.instanceName()) +} + +func (v *validator) createConfig() error { + p := path.Join(v.configDir(), "config") + return os.MkdirAll(p, 0o755) +} + +func (v *validator) init() error { + if err := v.createConfig(); err != nil { + return err + } + + serverCtx := server.NewDefaultContext() + config := serverCtx.Config + + config.SetRoot(v.configDir()) + config.Moniker = v.moniker + + genDoc, err := getGenDoc(v.configDir()) + if err != nil { + return err + } + + appState, err := json.MarshalIndent(gaia.ModuleBasics.DefaultGenesis(cdc), "", " ") + if err != nil { + return fmt.Errorf("failed to JSON encode app genesis state: %w", err) + } + + genDoc.ChainID = v.chain.id + genDoc.Validators = nil + genDoc.AppState = appState + + if err = genutil.ExportGenesisFile(genDoc, config.GenesisFile()); err != nil { + return fmt.Errorf("failed to export app genesis state: %w", err) + } + + tmcfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config) + return nil +} + +func (v *validator) createNodeKey() error { + serverCtx := server.NewDefaultContext() + config := serverCtx.Config + + config.SetRoot(v.configDir()) + config.Moniker = v.moniker + + nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) + if err != nil { + return err + } + + v.nodeKey = *nodeKey + return nil +} + +func (v *validator) createConsensusKey() error { + serverCtx := server.NewDefaultContext() + config := serverCtx.Config + + config.SetRoot(v.configDir()) + config.Moniker = v.moniker + + pvKeyFile := config.PrivValidatorKeyFile() + if err := tmos.EnsureDir(filepath.Dir(pvKeyFile), 0o777); err != nil { + return err + } + + pvStateFile := config.PrivValidatorStateFile() + if err := tmos.EnsureDir(filepath.Dir(pvStateFile), 0o777); err != nil { + return err + } + + filePV := privval.LoadOrGenFilePV(pvKeyFile, pvStateFile) + v.consensusKey = filePV.Key + + return nil +} + +func (v *validator) createKeyFromMnemonic(name, mnemonic string) error { + dir := v.configDir() + kb, err := keyring.New(keyringAppName, keyring.BackendTest, dir, nil, cdc) + if err != nil { + return err + } + + keyringAlgos, _ := kb.SupportedAlgorithms() + algo, err := keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), keyringAlgos) + if err != nil { + return err + } + + info, err := kb.NewAccount(name, mnemonic, "", sdk.FullFundraiserPath, algo) + if err != nil { + return err + } + + privKeyArmor, err := kb.ExportPrivKeyArmor(name, keyringPassphrase) + if err != nil { + return err + } + + privKey, _, err := sdkcrypto.UnarmorDecryptPrivKey(privKeyArmor, keyringPassphrase) + if err != nil { + return err + } + + v.keyInfo = *info + v.mnemonic = mnemonic + v.privateKey = privKey + + return nil +} + +func (c *chain) addAccountFromMnemonic(counts int) error { + val0ConfigDir := c.validators[0].configDir() + kb, err := keyring.New(keyringAppName, keyring.BackendTest, val0ConfigDir, nil, cdc) + if err != nil { + return err + } + + keyringAlgos, _ := kb.SupportedAlgorithms() + algo, err := keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), keyringAlgos) + if err != nil { + return err + } + + for i := 0; i < counts; i++ { + name := fmt.Sprintf("acct-%d", i) + mnemonic, err := createMnemonic() + if err != nil { + return err + } + info, err := kb.NewAccount(name, mnemonic, "", sdk.FullFundraiserPath, algo) + if err != nil { + return err + } + + privKeyArmor, err := kb.ExportPrivKeyArmor(name, keyringPassphrase) + if err != nil { + return err + } + + privKey, _, err := sdkcrypto.UnarmorDecryptPrivKey(privKeyArmor, keyringPassphrase) + if err != nil { + return err + } + acct := account{} + acct.keyInfo = *info + acct.mnemonic = mnemonic + acct.privateKey = privKey + c.genesisAccounts = append(c.genesisAccounts, &acct) + } + + return nil +} + +func (v *validator) createKey(name string) error { + mnemonic, err := createMnemonic() + if err != nil { + return err + } + + return v.createKeyFromMnemonic(name, mnemonic) +} + +func (v *validator) buildCreateValidatorMsg(amount sdk.Coin) (sdk.Msg, error) { + description := stakingtypes.NewDescription(v.moniker, "", "", "", "") + commissionRates := stakingtypes.CommissionRates{ + Rate: sdk.MustNewDecFromStr("0.1"), + MaxRate: sdk.MustNewDecFromStr("0.2"), + MaxChangeRate: sdk.MustNewDecFromStr("0.01"), + } + + // get the initial validator min self delegation + minSelfDelegation := sdk.OneInt() + + valPubKey, err := cryptocodec.FromTmPubKeyInterface(v.consensusKey.PubKey) + if err != nil { + return nil, err + } + + addr, err := v.keyInfo.GetAddress() + if err != nil { + return nil, err + } + + return stakingtypes.NewMsgCreateValidator( + sdk.ValAddress(addr), + valPubKey, + amount, + description, + commissionRates, + minSelfDelegation, + ) +} + +func (v *validator) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) { + txBuilder := encodingConfig.TxConfig.NewTxBuilder() + + if err := txBuilder.SetMsgs(msgs...); err != nil { + return nil, err + } + + txBuilder.SetMemo(fmt.Sprintf("%s@%s:26656", v.nodeKey.ID(), v.instanceName())) + txBuilder.SetFeeAmount(sdk.NewCoins()) + txBuilder.SetGasLimit(200000) + + signerData := authsigning.SignerData{ + ChainID: v.chain.id, + AccountNumber: 0, + Sequence: 0, + } + + // For SIGN_MODE_DIRECT, calling SetSignatures calls setSignerInfos on + // TxBuilder under the hood, and SignerInfos is needed to generate the sign + // bytes. This is the reason for setting SetSignatures here, with a nil + // signature. + // + // Note: This line is not needed for SIGN_MODE_LEGACY_AMINO, but putting it + // also doesn't affect its generated sign bytes, so for code's simplicity + // sake, we put it here. + pk, err := v.keyInfo.GetPubKey() + if err != nil { + return nil, err + } + + sig := txsigning.SignatureV2{ + PubKey: pk, + Data: &txsigning.SingleSignatureData{ + SignMode: txsigning.SignMode_SIGN_MODE_DIRECT, + Signature: nil, + }, + Sequence: 0, + } + + if err := txBuilder.SetSignatures(sig); err != nil { + return nil, err + } + + bytesToSign, err := encodingConfig.TxConfig.SignModeHandler().GetSignBytes( + txsigning.SignMode_SIGN_MODE_DIRECT, + signerData, + txBuilder.GetTx(), + ) + if err != nil { + return nil, err + } + + sigBytes, err := v.privateKey.Sign(bytesToSign) + if err != nil { + return nil, err + } + + pk, err = v.keyInfo.GetPubKey() + if err != nil { + return nil, err + } + + sig = txsigning.SignatureV2{ + PubKey: pk, + Data: &txsigning.SingleSignatureData{ + SignMode: txsigning.SignMode_SIGN_MODE_DIRECT, + Signature: sigBytes, + }, + Sequence: 0, + } + if err := txBuilder.SetSignatures(sig); err != nil { + return nil, err + } + + signedTx := txBuilder.GetTx() + bz, err := encodingConfig.TxConfig.TxEncoder()(signedTx) + if err != nil { + return nil, err + } + + return decodeTx(bz) +} diff --git a/tests/ics/interchain_security_test.go b/tests/ics/interchain_security_test.go index 5a5179b7012..cf6679f505c 100644 --- a/tests/ics/interchain_security_test.go +++ b/tests/ics/interchain_security_test.go @@ -9,7 +9,7 @@ import ( icstestingutils "github.com/cosmos/interchain-security/v3/testutil/ibc_testing" "github.com/stretchr/testify/suite" - cmdb "github.com/cometbft/cometbft-db" + tmdb "github.com/cometbft/cometbft-db" "github.com/cometbft/cometbft/libs/log" ibctesting "github.com/cosmos/interchain-security/v3/legacy_ibc_testing/testing" @@ -33,7 +33,7 @@ func GaiaAppIniter() (ibctesting.TestingApp, map[string]json.RawMessage) { encoding := gaiaApp.RegisterEncodingConfig() app := gaiaApp.NewGaiaApp( log.NewNopLogger(), - cmdb.NewMemDB(), + tmdb.NewMemDB(), nil, true, map[int64]bool{},