From c8830c164a5320cd2aca94e59611e268a6ea4cc9 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 05:01:28 +0000 Subject: [PATCH 01/56] initial setup for e2e tests --- go.mod | 35 ++++++++++++- go.sum | 76 ++++++++++++++++++++++++++-- scripts/e2e_test.sh | 27 ++++++++++ scripts/versions.sh | 1 + tests/e2e/e2e_test.go | 114 ++++++++++++++++++++++++++++++++++++++++++ tests/e2e/warp.json | 47 +++++++++++++++++ 6 files changed, 293 insertions(+), 7 deletions(-) create mode 100755 scripts/e2e_test.sh create mode 100644 tests/e2e/e2e_test.go create mode 100644 tests/e2e/warp.json diff --git a/go.mod b/go.mod index bbe4297d..e7755c17 100644 --- a/go.mod +++ b/go.mod @@ -3,42 +3,73 @@ module github.com/ava-labs/awm-relayer go 1.18 require ( + github.com/ava-labs/avalanche-network-runner v1.7.2-0.20230825150237-723bc7b31724 github.com/ava-labs/avalanchego v1.10.9 github.com/ava-labs/subnet-evm v0.5.4 github.com/ethereum/go-ethereum v1.12.0 - github.com/golang/mock v1.6.0 + github.com/onsi/ginkgo v1.16.5 + github.com/onsi/gomega v1.26.0 github.com/prometheus/client_golang v1.16.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 + go.uber.org/mock v0.2.0 go.uber.org/zap v1.25.0 ) require ( + github.com/Microsoft/go-winio v0.5.2 // indirect + github.com/ava-labs/coreth v0.12.5-rc.3 // indirect github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 // indirect github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/dlclark/regexp2 v1.7.0 // indirect + github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect + github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect + github.com/go-cmd/cmd v1.4.1 // indirect + github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v4 v4.3.0 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect + github.com/hashicorp/go-bexpr v0.1.10 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/huin/goupnp v1.0.3 // indirect + github.com/jackpal/gateway v1.0.6 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/pointerstructure v1.2.0 // indirect + github.com/nxadm/tail v1.4.8 // indirect + github.com/onsi/ginkgo/v2 v2.8.1 // indirect + github.com/otiai10/copy v1.11.0 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect - go.uber.org/mock v0.2.0 // indirect + github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect + golang.org/x/mod v0.10.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect ) require ( diff --git a/go.sum b/go.sum index cc461fb8..9b102977 100644 --- a/go.sum +++ b/go.sum @@ -45,6 +45,8 @@ github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMd github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -59,8 +61,12 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/ava-labs/avalanche-network-runner v1.7.2-0.20230825150237-723bc7b31724 h1:ptqFgQtJ5DyLb2lvuvawLJNlvo1A1qv+JXYTneNeg14= +github.com/ava-labs/avalanche-network-runner v1.7.2-0.20230825150237-723bc7b31724/go.mod h1:euKHwZ77sGvGfhVj4v9WPM4jD2b5N80ldE2XHqO7lwA= github.com/ava-labs/avalanchego v1.10.9 h1:qxhp3YoD2Wm/iIKP6Wb1isbkUPWmIrJxWgivDoL0obM= github.com/ava-labs/avalanchego v1.10.9/go.mod h1:C8R5uiltpc8MQ62ixxgODR+15mesWF0aAw3H+Qrl9Iw= +github.com/ava-labs/coreth v0.12.5-rc.3 h1:cpmC+fSZMsO4gaFWqXHzAHrJACf05u5HPAYmwh7nmkU= +github.com/ava-labs/coreth v0.12.5-rc.3/go.mod h1:HI+jTIflnDFBd0bledgkgid1Uurwr8q1h7zb3LsFsSo= github.com/ava-labs/subnet-evm v0.5.4 h1:4+UHva8rhGlvH4gDYpI0Lt6/J5ie1DqQa6kEmbebArI= github.com/ava-labs/subnet-evm v0.5.4/go.mod h1:PAyhfYnECzA17N62i7OAdKazjfSsN2l8KR5nOspg39I= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -101,8 +107,11 @@ github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -127,9 +136,9 @@ github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcju 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= -github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -145,6 +154,14 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2U github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -162,6 +179,7 @@ github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDB github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= 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= @@ -178,6 +196,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-cmd/cmd v1.4.1 h1:JUcEIE84v8DSy02XTZpUDeGKExk2oW3DA10hTjbQwmc= +github.com/go-cmd/cmd v1.4.1/go.mod h1:tbBenttXtZU4c5djS1o7PWL5pd2xAr5sIqH1kGdNiRc= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -191,9 +211,12 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= @@ -204,6 +227,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog= +github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= @@ -217,8 +242,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -257,6 +280,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -273,6 +297,8 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= @@ -288,15 +314,19 @@ github.com/gorilla/rpc v1.2.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36j github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 h1:gDLXvp5S9izjldquuoAhDzccbskOL6tDC5jMSyx3zxE= github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2/go.mod h1:7pdNwVWBBHGiCxa9lAszqCJMbfTISJ7oMftp8+UGV08= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= @@ -306,9 +336,13 @@ github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iU github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= +github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= 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/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= @@ -316,6 +350,10 @@ github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/ github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jackpal/gateway v1.0.6 h1:/MJORKvJEwNVldtGVJC2p2cwCnsSoLn3hl3zxmZT7tk= +github.com/jackpal/gateway v1.0.6/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -340,6 +378,7 @@ github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9 github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -358,12 +397,14 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= @@ -373,9 +414,11 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -403,6 +446,8 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv 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/v2 v2.8.1 h1:xFTEVwOFa1D/Ty24Ws1npBWkDYEV9BqZrsDxVrVkrrU= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= 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= @@ -410,6 +455,10 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y 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/otiai10/copy v1.11.0 h1:OKBD80J/mLBrwnzXqGtFCzprFSGioo30JcmR4APsNwc= +github.com/otiai10/copy v1.11.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= +github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= @@ -441,9 +490,9 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sanity-io/litter v1.5.1 h1:dwnrSypP6q56o3lFxTU+t2fwQ9A+U5qrXVO4Qg9KwVU= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= @@ -451,10 +500,12 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 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/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= @@ -508,6 +559,7 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -519,6 +571,7 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= @@ -528,6 +581,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -612,6 +666,9 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -656,6 +713,7 @@ golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -679,6 +737,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -699,6 +758,7 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -725,6 +785,7 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w 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-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -738,9 +799,12 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -757,6 +821,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -818,8 +883,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f 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= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -938,6 +1003,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/scripts/e2e_test.sh b/scripts/e2e_test.sh new file mode 100755 index 00000000..b015c0dc --- /dev/null +++ b/scripts/e2e_test.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -e + +AWM_RELAYER_PATH=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + cd .. && pwd +) + +source "$AWM_RELAYER_PATH"/scripts/constants.sh + +source "$AWM_RELAYER_PATH"/scripts/versions.sh + +BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh +./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo.sh +DATA_DIR=/tmp/e2e-test/data + +# Build ginkgo +# to install the ginkgo binary (required for test build and run) +go install -v github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION} + +ginkgo build ./tests/e2e + +# Run the tests +./tests/e2e/e2e.test \ + --ginkgo.vv \ + --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} \ No newline at end of file diff --git a/scripts/versions.sh b/scripts/versions.sh index 8ea7ce5f..fe29cba5 100755 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -7,3 +7,4 @@ awm_relayer_version=${AWM_RELAYER_VERSION:-'v0.0.1'} subnet_evm_version=${SUBNET_EVM_VERSION:-'v0.5.2-warp-rc.0'} # Don't export them as they're used in the context of other calls avalanche_version=${AVALANCHE_VERSION:-'v1.10.2'} +ginkgo_version=${GINKGO_VERSION:-'v2.2.0'} diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go new file mode 100644 index 00000000..8c8d8075 --- /dev/null +++ b/tests/e2e/e2e_test.go @@ -0,0 +1,114 @@ +package tests + +import ( + "context" + "fmt" + "math/big" + "os" + "os/exec" + "strings" + "testing" + + "github.com/ava-labs/avalanche-network-runner/rpcpb" + "github.com/ava-labs/subnet-evm/ethclient" + "github.com/ava-labs/subnet-evm/plugin/evm" + "github.com/ava-labs/subnet-evm/tests/utils" + "github.com/ava-labs/subnet-evm/tests/utils/runner" + "github.com/ethereum/go-ethereum/crypto" + "github.com/onsi/ginkgo" + "github.com/onsi/gomega" +) + +const fundedKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" + +var ( + config = runner.NewDefaultANRConfig() + manager = runner.NewNetworkManager(config) + warpChainConfigPath string +) + +func TestE2E(t *testing.T) { + gomega.RegisterFailHandler(ginkgo.Fail) + ginkgo.RunSpecs(t, "awm-relayer e2e test") +} + +func toWebsocketURI(uri string, blockchainID string) string { + return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) +} + +// BeforeSuite builds the awm-relayer binary, starts the default network and adds 10 new nodes as validators with BLS keys +// registered on the P-Chain. +// Adds two disjoint sets of 5 of the new validator nodes to validate two new subnets with a +// a single Subnet-EVM blockchain. +var _ = ginkgo.BeforeSuite(func() { + ctx := context.Background() + var err error + + // Build the awm-relayer binary + cmd := exec.Command("./scripts/build.sh") + out, err := cmd.CombinedOutput() + fmt.Println(string(out)) + gomega.Expect(err).Should(gomega.BeNil()) + + // Name 10 new validators (which should have BLS key registered) + subnetANodeNames := make([]string, 0) + subnetBNodeNames := []string{} + for i := 1; i <= 10; i++ { + n := fmt.Sprintf("node%d-bls", i) + if i <= 5 { + subnetANodeNames = append(subnetANodeNames, n) + } else { + subnetBNodeNames = append(subnetBNodeNames, n) + } + } + f, err := os.CreateTemp(os.TempDir(), "config.json") + gomega.Expect(err).Should(gomega.BeNil()) + _, err = f.Write([]byte(`{"warp-api-enabled": true}`)) + gomega.Expect(err).Should(gomega.BeNil()) + warpChainConfigPath = f.Name() + + // Construct the network using the avalanche-network-runner + _, err = manager.StartDefaultNetwork(ctx) + gomega.Expect(err).Should(gomega.BeNil()) + err = manager.SetupNetwork( + ctx, + config.AvalancheGoExecPath, + []*rpcpb.BlockchainSpec{ + { + VmName: evm.IDStr, + Genesis: "./tests/e2e/warp.json", + ChainConfig: warpChainConfigPath, + SubnetSpec: &rpcpb.SubnetSpec{ + SubnetConfig: "", + Participants: subnetANodeNames, + }, + }, + { + VmName: evm.IDStr, + Genesis: "./tests/e2e/warp.json", + ChainConfig: warpChainConfigPath, + SubnetSpec: &rpcpb.SubnetSpec{ + SubnetConfig: "", + Participants: subnetBNodeNames, + }, + }, + }, + ) + gomega.Expect(err).Should(gomega.BeNil()) + + // Issue transactions to activate the proposerVM fork on the receiving chain + chainID := big.NewInt(99999) + fundedKey, err := crypto.HexToECDSA(fundedKeyStr) + gomega.Expect(err).Should(gomega.BeNil()) + subnetB := manager.GetSubnets()[1] + subnetBDetails, ok := manager.GetSubnet(subnetB) + gomega.Expect(ok).Should(gomega.BeTrue()) + + chainBID := subnetBDetails.BlockchainID + uri := toWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) + client, err := ethclient.Dial(uri) + gomega.Expect(err).Should(gomega.BeNil()) + + err = utils.IssueTxsToActivateProposerVMFork(ctx, chainID, fundedKey, client) + gomega.Expect(err).Should(gomega.BeNil()) +}) diff --git a/tests/e2e/warp.json b/tests/e2e/warp.json new file mode 100644 index 00000000..2c04535e --- /dev/null +++ b/tests/e2e/warp.json @@ -0,0 +1,47 @@ +{ + "config": { + "chainId": 99999, + "homesteadBlock": 0, + "eip150Block": 0, + "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "subnetEVMTimestamp": 0, + "feeConfig": { + "gasLimit": 20000000, + "minBaseFee": 1000000000, + "targetGas": 100000000, + "baseFeeChangeDenominator": 48, + "minBlockGasCost": 0, + "maxBlockGasCost": 10000000, + "targetBlockRate": 2, + "blockGasCostStep": 500000 + }, + "warpConfig": { + "blockTimestamp": 0 + } + }, + "alloc": { + "8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0x0Fa8EA536Be85F32724D57A37758761B86416123": { + "balance": "0x52B7D2DCC80CD2E4000000" + } + }, + "nonce": "0x0", + "timestamp": "0x0", + "extraData": "0x00", + "gasLimit": "0x1312D00", + "difficulty": "0x0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" +} From 3c6985b7ebc7268e06de6715ef4be7ede1feb6db Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 18:20:43 +0000 Subject: [PATCH 02/56] adding e2e test to ci --- .github/workflows/test.yml | 84 ++++++++++++++++++++++++++------------ scripts/e2e_test.sh | 5 --- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 20a117a8..93cf1619 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,33 +4,63 @@ name: Run Relayer Unit Tests on: - push: - branches: - - '*' + push: + branches: + - "*" jobs: - build-test-relayer: - runs-on: ubuntu-20.04 - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - path: awm-relayer - - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: '1.20.7' - - - name: Build Relayer - run: | - cd awm-relayer - go mod tidy - ./scripts/build.sh - - - name: Run Relayer Unit Tests - run: | - cd awm-relayer - go test ./... + build-test-relayer: + runs-on: ubuntu-20.04 + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + path: awm-relayer + + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: "1.20.7" + + - name: Build Relayer + run: | + cd awm-relayer + go mod tidy + ./scripts/build.sh + + - name: Run Relayer Unit Tests + run: | + cd awm-relayer + go test ./... + + e2e_test: + runs-on: ubuntu-20.04 + name: Run Relayer E2E Tests + + steps: + - name: Checkout subnet-evm repository + uses: actions/checkout@v3 + with: + repository: ava-labs/subnet-evm + ref: v0.5.4 + + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: "1.20.7" + + - name: Install AvalancheGo Release + shell: bash + run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh + + - name: Build Subnet-EVM Plugin Binary + shell: bash + run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy + + - name: Checkout awm-relayer repository + uses: actions/checkout@v3 + + - name: Run E2E Tests + shell: bash + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh diff --git a/scripts/e2e_test.sh b/scripts/e2e_test.sh index b015c0dc..846d179c 100755 --- a/scripts/e2e_test.sh +++ b/scripts/e2e_test.sh @@ -10,11 +10,6 @@ source "$AWM_RELAYER_PATH"/scripts/constants.sh source "$AWM_RELAYER_PATH"/scripts/versions.sh -BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh -./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy -AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/run_ginkgo.sh -DATA_DIR=/tmp/e2e-test/data - # Build ginkgo # to install the ginkgo binary (required for test build and run) go install -v github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION} From 84e7685a3347553bbb9dac1bd3bd7f50e695be8d Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 18:31:24 +0000 Subject: [PATCH 03/56] rename workflows and fixing ginkgo version to v2 --- .github/workflows/test.yml | 7 +- go.mod | 26 ++++--- go.sum | 44 ++++++------ tests/e2e/e2e_test.go | 143 +++++++++++++++++-------------------- 4 files changed, 106 insertions(+), 114 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 93cf1619..2a1f6bc9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,7 +1,7 @@ # Copyright (C) 2023, Ava Labs, Inc. All rights reserved. # See the file LICENSE for licensing terms. -name: Run Relayer Unit Tests +name: Relayer Tests on: push: @@ -10,6 +10,7 @@ on: jobs: build-test-relayer: + name: Build + Unit tests runs-on: ubuntu-20.04 steps: @@ -34,9 +35,9 @@ jobs: cd awm-relayer go test ./... - e2e_test: + e2e_tests: runs-on: ubuntu-20.04 - name: Run Relayer E2E Tests + name: e2e_tests steps: - name: Checkout subnet-evm repository diff --git a/go.mod b/go.mod index e7755c17..41d37dc5 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,11 @@ module github.com/ava-labs/awm-relayer go 1.18 require ( - github.com/ava-labs/avalanche-network-runner v1.7.2-0.20230825150237-723bc7b31724 github.com/ava-labs/avalanchego v1.10.9 github.com/ava-labs/subnet-evm v0.5.4 github.com/ethereum/go-ethereum v1.12.0 - github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.26.0 + github.com/onsi/ginkgo/v2 v2.12.0 + github.com/onsi/gomega v1.27.10 github.com/prometheus/client_golang v1.16.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.16.0 @@ -19,6 +18,7 @@ require ( require ( github.com/Microsoft/go-winio v0.5.2 // indirect + github.com/ava-labs/avalanche-network-runner v1.7.2-0.20230825150237-723bc7b31724 // indirect github.com/ava-labs/coreth v0.12.5-rc.3 // indirect github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect @@ -31,8 +31,8 @@ require ( github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect - github.com/go-cmd/cmd v1.4.1 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.3.0 // indirect github.com/google/go-cmp v0.5.9 // indirect @@ -52,8 +52,6 @@ require ( github.com/mattn/go-isatty v0.0.16 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect - github.com/nxadm/tail v1.4.8 // indirect - github.com/onsi/ginkgo/v2 v2.8.1 // indirect github.com/otiai10/copy v1.11.0 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -67,9 +65,9 @@ require ( github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect - golang.org/x/mod v0.10.0 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/tools v0.12.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect ) require ( @@ -85,7 +83,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-stack/stack v1.8.1 // indirect @@ -128,12 +126,12 @@ require ( go.opentelemetry.io/otel/trace v1.11.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/net v0.10.0 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/net v0.14.0 // indirect golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/term v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect golang.org/x/time v0.3.0 // indirect gonum.org/v1/gonum v0.11.0 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect diff --git a/go.sum b/go.sum index 9b102977..041334c0 100644 --- a/go.sum +++ b/go.sum @@ -196,16 +196,14 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-cmd/cmd v1.4.1 h1:JUcEIE84v8DSy02XTZpUDeGKExk2oW3DA10hTjbQwmc= -github.com/go-cmd/cmd v1.4.1/go.mod h1:tbBenttXtZU4c5djS1o7PWL5pd2xAr5sIqH1kGdNiRc= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= @@ -216,7 +214,8 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= @@ -446,16 +445,16 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv 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/v2 v2.8.1 h1:xFTEVwOFa1D/Ty24Ws1npBWkDYEV9BqZrsDxVrVkrrU= -github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI= +github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ= 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/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/otiai10/copy v1.11.0 h1:OKBD80J/mLBrwnzXqGtFCzprFSGioo30JcmR4APsNwc= github.com/otiai10/copy v1.11.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= @@ -532,6 +531,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +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= @@ -627,8 +627,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -667,8 +667,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -714,8 +714,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -806,12 +806,12 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -822,8 +822,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -885,6 +885,8 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 8c8d8075..cd6b000f 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -1,21 +1,12 @@ package tests import ( - "context" "fmt" - "math/big" - "os" - "os/exec" "strings" "testing" - "github.com/ava-labs/avalanche-network-runner/rpcpb" - "github.com/ava-labs/subnet-evm/ethclient" - "github.com/ava-labs/subnet-evm/plugin/evm" - "github.com/ava-labs/subnet-evm/tests/utils" "github.com/ava-labs/subnet-evm/tests/utils/runner" - "github.com/ethereum/go-ethereum/crypto" - "github.com/onsi/ginkgo" + "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" ) @@ -40,75 +31,75 @@ func toWebsocketURI(uri string, blockchainID string) string { // registered on the P-Chain. // Adds two disjoint sets of 5 of the new validator nodes to validate two new subnets with a // a single Subnet-EVM blockchain. -var _ = ginkgo.BeforeSuite(func() { - ctx := context.Background() - var err error +// var _ = ginkgo.BeforeSuite(func() { +// ctx := context.Background() +// var err error - // Build the awm-relayer binary - cmd := exec.Command("./scripts/build.sh") - out, err := cmd.CombinedOutput() - fmt.Println(string(out)) - gomega.Expect(err).Should(gomega.BeNil()) +// // Build the awm-relayer binary +// cmd := exec.Command("./scripts/build.sh") +// out, err := cmd.CombinedOutput() +// fmt.Println(string(out)) +// gomega.Expect(err).Should(gomega.BeNil()) - // Name 10 new validators (which should have BLS key registered) - subnetANodeNames := make([]string, 0) - subnetBNodeNames := []string{} - for i := 1; i <= 10; i++ { - n := fmt.Sprintf("node%d-bls", i) - if i <= 5 { - subnetANodeNames = append(subnetANodeNames, n) - } else { - subnetBNodeNames = append(subnetBNodeNames, n) - } - } - f, err := os.CreateTemp(os.TempDir(), "config.json") - gomega.Expect(err).Should(gomega.BeNil()) - _, err = f.Write([]byte(`{"warp-api-enabled": true}`)) - gomega.Expect(err).Should(gomega.BeNil()) - warpChainConfigPath = f.Name() +// // Name 10 new validators (which should have BLS key registered) +// subnetANodeNames := make([]string, 0) +// subnetBNodeNames := []string{} +// for i := 1; i <= 10; i++ { +// n := fmt.Sprintf("node%d-bls", i) +// if i <= 5 { +// subnetANodeNames = append(subnetANodeNames, n) +// } else { +// subnetBNodeNames = append(subnetBNodeNames, n) +// } +// } +// f, err := os.CreateTemp(os.TempDir(), "config.json") +// gomega.Expect(err).Should(gomega.BeNil()) +// _, err = f.Write([]byte(`{"warp-api-enabled": true}`)) +// gomega.Expect(err).Should(gomega.BeNil()) +// warpChainConfigPath = f.Name() - // Construct the network using the avalanche-network-runner - _, err = manager.StartDefaultNetwork(ctx) - gomega.Expect(err).Should(gomega.BeNil()) - err = manager.SetupNetwork( - ctx, - config.AvalancheGoExecPath, - []*rpcpb.BlockchainSpec{ - { - VmName: evm.IDStr, - Genesis: "./tests/e2e/warp.json", - ChainConfig: warpChainConfigPath, - SubnetSpec: &rpcpb.SubnetSpec{ - SubnetConfig: "", - Participants: subnetANodeNames, - }, - }, - { - VmName: evm.IDStr, - Genesis: "./tests/e2e/warp.json", - ChainConfig: warpChainConfigPath, - SubnetSpec: &rpcpb.SubnetSpec{ - SubnetConfig: "", - Participants: subnetBNodeNames, - }, - }, - }, - ) - gomega.Expect(err).Should(gomega.BeNil()) +// // Construct the network using the avalanche-network-runner +// _, err = manager.StartDefaultNetwork(ctx) +// gomega.Expect(err).Should(gomega.BeNil()) +// err = manager.SetupNetwork( +// ctx, +// config.AvalancheGoExecPath, +// []*rpcpb.BlockchainSpec{ +// { +// VmName: evm.IDStr, +// Genesis: "./tests/e2e/warp.json", +// ChainConfig: warpChainConfigPath, +// SubnetSpec: &rpcpb.SubnetSpec{ +// SubnetConfig: "", +// Participants: subnetANodeNames, +// }, +// }, +// { +// VmName: evm.IDStr, +// Genesis: "./tests/e2e/warp.json", +// ChainConfig: warpChainConfigPath, +// SubnetSpec: &rpcpb.SubnetSpec{ +// SubnetConfig: "", +// Participants: subnetBNodeNames, +// }, +// }, +// }, +// ) +// gomega.Expect(err).Should(gomega.BeNil()) - // Issue transactions to activate the proposerVM fork on the receiving chain - chainID := big.NewInt(99999) - fundedKey, err := crypto.HexToECDSA(fundedKeyStr) - gomega.Expect(err).Should(gomega.BeNil()) - subnetB := manager.GetSubnets()[1] - subnetBDetails, ok := manager.GetSubnet(subnetB) - gomega.Expect(ok).Should(gomega.BeTrue()) +// // Issue transactions to activate the proposerVM fork on the receiving chain +// chainID := big.NewInt(99999) +// fundedKey, err := crypto.HexToECDSA(fundedKeyStr) +// gomega.Expect(err).Should(gomega.BeNil()) +// subnetB := manager.GetSubnets()[1] +// subnetBDetails, ok := manager.GetSubnet(subnetB) +// gomega.Expect(ok).Should(gomega.BeTrue()) - chainBID := subnetBDetails.BlockchainID - uri := toWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) - client, err := ethclient.Dial(uri) - gomega.Expect(err).Should(gomega.BeNil()) +// chainBID := subnetBDetails.BlockchainID +// uri := toWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) +// client, err := ethclient.Dial(uri) +// gomega.Expect(err).Should(gomega.BeNil()) - err = utils.IssueTxsToActivateProposerVMFork(ctx, chainID, fundedKey, client) - gomega.Expect(err).Should(gomega.BeNil()) -}) +// err = utils.IssueTxsToActivateProposerVMFork(ctx, chainID, fundedKey, client) +// gomega.Expect(err).Should(gomega.BeNil()) +// }) From ed613b16bf76c7787cefdb870ff2bdf1ce289454 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 18:39:13 +0000 Subject: [PATCH 04/56] fix ginkgo version and add e2e test --- go.mod | 3 +- go.sum | 3 + scripts/versions.sh | 2 +- tests/e2e/e2e_test.go | 141 ++++++++++++++++++++++-------------------- 4 files changed, 81 insertions(+), 68 deletions(-) diff --git a/go.mod b/go.mod index 41d37dc5..c5f596a3 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/ava-labs/awm-relayer go 1.18 require ( + github.com/ava-labs/avalanche-network-runner v1.7.2-0.20230825150237-723bc7b31724 github.com/ava-labs/avalanchego v1.10.9 github.com/ava-labs/subnet-evm v0.5.4 github.com/ethereum/go-ethereum v1.12.0 @@ -18,7 +19,6 @@ require ( require ( github.com/Microsoft/go-winio v0.5.2 // indirect - github.com/ava-labs/avalanche-network-runner v1.7.2-0.20230825150237-723bc7b31724 // indirect github.com/ava-labs/coreth v0.12.5-rc.3 // indirect github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect @@ -31,6 +31,7 @@ require ( github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect + github.com/go-cmd/cmd v1.4.1 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect diff --git a/go.sum b/go.sum index 041334c0..f9eb5c9f 100644 --- a/go.sum +++ b/go.sum @@ -196,6 +196,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-cmd/cmd v1.4.1 h1:JUcEIE84v8DSy02XTZpUDeGKExk2oW3DA10hTjbQwmc= +github.com/go-cmd/cmd v1.4.1/go.mod h1:tbBenttXtZU4c5djS1o7PWL5pd2xAr5sIqH1kGdNiRc= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -216,6 +218,7 @@ github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= diff --git a/scripts/versions.sh b/scripts/versions.sh index fe29cba5..10fa37e8 100755 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -7,4 +7,4 @@ awm_relayer_version=${AWM_RELAYER_VERSION:-'v0.0.1'} subnet_evm_version=${SUBNET_EVM_VERSION:-'v0.5.2-warp-rc.0'} # Don't export them as they're used in the context of other calls avalanche_version=${AVALANCHE_VERSION:-'v1.10.2'} -ginkgo_version=${GINKGO_VERSION:-'v2.2.0'} +GINKGO_VERSION=${GINKGO_VERSION:-'v2.2.0'} diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index cd6b000f..52d98367 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -1,11 +1,20 @@ package tests import ( + "context" "fmt" + "math/big" + "os" + "os/exec" "strings" "testing" + "github.com/ava-labs/avalanche-network-runner/rpcpb" + "github.com/ava-labs/subnet-evm/ethclient" + "github.com/ava-labs/subnet-evm/plugin/evm" + "github.com/ava-labs/subnet-evm/tests/utils" "github.com/ava-labs/subnet-evm/tests/utils/runner" + "github.com/ethereum/go-ethereum/crypto" "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" ) @@ -31,75 +40,75 @@ func toWebsocketURI(uri string, blockchainID string) string { // registered on the P-Chain. // Adds two disjoint sets of 5 of the new validator nodes to validate two new subnets with a // a single Subnet-EVM blockchain. -// var _ = ginkgo.BeforeSuite(func() { -// ctx := context.Background() -// var err error +var _ = ginkgo.BeforeSuite(func() { + ctx := context.Background() + var err error -// // Build the awm-relayer binary -// cmd := exec.Command("./scripts/build.sh") -// out, err := cmd.CombinedOutput() -// fmt.Println(string(out)) -// gomega.Expect(err).Should(gomega.BeNil()) + // Build the awm-relayer binary + cmd := exec.Command("./scripts/build.sh") + out, err := cmd.CombinedOutput() + fmt.Println(string(out)) + gomega.Expect(err).Should(gomega.BeNil()) -// // Name 10 new validators (which should have BLS key registered) -// subnetANodeNames := make([]string, 0) -// subnetBNodeNames := []string{} -// for i := 1; i <= 10; i++ { -// n := fmt.Sprintf("node%d-bls", i) -// if i <= 5 { -// subnetANodeNames = append(subnetANodeNames, n) -// } else { -// subnetBNodeNames = append(subnetBNodeNames, n) -// } -// } -// f, err := os.CreateTemp(os.TempDir(), "config.json") -// gomega.Expect(err).Should(gomega.BeNil()) -// _, err = f.Write([]byte(`{"warp-api-enabled": true}`)) -// gomega.Expect(err).Should(gomega.BeNil()) -// warpChainConfigPath = f.Name() + // Name 10 new validators (which should have BLS key registered) + subnetANodeNames := make([]string, 0) + subnetBNodeNames := []string{} + for i := 1; i <= 10; i++ { + n := fmt.Sprintf("node%d-bls", i) + if i <= 5 { + subnetANodeNames = append(subnetANodeNames, n) + } else { + subnetBNodeNames = append(subnetBNodeNames, n) + } + } + f, err := os.CreateTemp(os.TempDir(), "config.json") + gomega.Expect(err).Should(gomega.BeNil()) + _, err = f.Write([]byte(`{"warp-api-enabled": true}`)) + gomega.Expect(err).Should(gomega.BeNil()) + warpChainConfigPath = f.Name() -// // Construct the network using the avalanche-network-runner -// _, err = manager.StartDefaultNetwork(ctx) -// gomega.Expect(err).Should(gomega.BeNil()) -// err = manager.SetupNetwork( -// ctx, -// config.AvalancheGoExecPath, -// []*rpcpb.BlockchainSpec{ -// { -// VmName: evm.IDStr, -// Genesis: "./tests/e2e/warp.json", -// ChainConfig: warpChainConfigPath, -// SubnetSpec: &rpcpb.SubnetSpec{ -// SubnetConfig: "", -// Participants: subnetANodeNames, -// }, -// }, -// { -// VmName: evm.IDStr, -// Genesis: "./tests/e2e/warp.json", -// ChainConfig: warpChainConfigPath, -// SubnetSpec: &rpcpb.SubnetSpec{ -// SubnetConfig: "", -// Participants: subnetBNodeNames, -// }, -// }, -// }, -// ) -// gomega.Expect(err).Should(gomega.BeNil()) + // Construct the network using the avalanche-network-runner + _, err = manager.StartDefaultNetwork(ctx) + gomega.Expect(err).Should(gomega.BeNil()) + err = manager.SetupNetwork( + ctx, + config.AvalancheGoExecPath, + []*rpcpb.BlockchainSpec{ + { + VmName: evm.IDStr, + Genesis: "./tests/e2e/warp.json", + ChainConfig: warpChainConfigPath, + SubnetSpec: &rpcpb.SubnetSpec{ + SubnetConfig: "", + Participants: subnetANodeNames, + }, + }, + { + VmName: evm.IDStr, + Genesis: "./tests/e2e/warp.json", + ChainConfig: warpChainConfigPath, + SubnetSpec: &rpcpb.SubnetSpec{ + SubnetConfig: "", + Participants: subnetBNodeNames, + }, + }, + }, + ) + gomega.Expect(err).Should(gomega.BeNil()) -// // Issue transactions to activate the proposerVM fork on the receiving chain -// chainID := big.NewInt(99999) -// fundedKey, err := crypto.HexToECDSA(fundedKeyStr) -// gomega.Expect(err).Should(gomega.BeNil()) -// subnetB := manager.GetSubnets()[1] -// subnetBDetails, ok := manager.GetSubnet(subnetB) -// gomega.Expect(ok).Should(gomega.BeTrue()) + // Issue transactions to activate the proposerVM fork on the receiving chain + chainID := big.NewInt(99999) + fundedKey, err := crypto.HexToECDSA(fundedKeyStr) + gomega.Expect(err).Should(gomega.BeNil()) + subnetB := manager.GetSubnets()[1] + subnetBDetails, ok := manager.GetSubnet(subnetB) + gomega.Expect(ok).Should(gomega.BeTrue()) -// chainBID := subnetBDetails.BlockchainID -// uri := toWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) -// client, err := ethclient.Dial(uri) -// gomega.Expect(err).Should(gomega.BeNil()) + chainBID := subnetBDetails.BlockchainID + uri := toWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) + client, err := ethclient.Dial(uri) + gomega.Expect(err).Should(gomega.BeNil()) -// err = utils.IssueTxsToActivateProposerVMFork(ctx, chainID, fundedKey, client) -// gomega.Expect(err).Should(gomega.BeNil()) -// }) + err = utils.IssueTxsToActivateProposerVMFork(ctx, chainID, fundedKey, client) + gomega.Expect(err).Should(gomega.BeNil()) +}) From a05f114af6d6764de82bf30c4e1fbe7465b59aca Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 21:03:55 +0000 Subject: [PATCH 05/56] add relayer config and write to file --- tests/e2e/constants.go | 11 +++ tests/e2e/e2e_test.go | 201 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 203 insertions(+), 9 deletions(-) create mode 100644 tests/e2e/constants.go diff --git a/tests/e2e/constants.go b/tests/e2e/constants.go new file mode 100644 index 00000000..533821d1 --- /dev/null +++ b/tests/e2e/constants.go @@ -0,0 +1,11 @@ +package tests + +import ( + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/awm-relayer/config" +) + +var testConfig = config.Config{ + NetworkID: constants.UnitTestID, + EncryptConnection: false, +} diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 52d98367..9d889e74 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -2,19 +2,28 @@ package tests import ( "context" + "crypto/ecdsa" + "encoding/json" "fmt" "math/big" "os" - "os/exec" + "strconv" "strings" "testing" + "time" + anr_client "github.com/ava-labs/avalanche-network-runner/client" "github.com/ava-labs/avalanche-network-runner/rpcpb" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/awm-relayer/config" "github.com/ava-labs/subnet-evm/ethclient" "github.com/ava-labs/subnet-evm/plugin/evm" "github.com/ava-labs/subnet-evm/tests/utils" "github.com/ava-labs/subnet-evm/tests/utils/runner" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" ) @@ -22,9 +31,11 @@ import ( const fundedKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" var ( - config = runner.NewDefaultANRConfig() - manager = runner.NewNetworkManager(config) - warpChainConfigPath string + anrConfig = runner.NewDefaultANRConfig() + manager = runner.NewNetworkManager(anrConfig) + warpChainConfigPath string + relayerConfigPath string + teleporterContractAddress = common.HexToAddress("27aE10273D17Cd7e80de8580A51f476960626e5f") ) func TestE2E(t *testing.T) { @@ -45,10 +56,10 @@ var _ = ginkgo.BeforeSuite(func() { var err error // Build the awm-relayer binary - cmd := exec.Command("./scripts/build.sh") - out, err := cmd.CombinedOutput() - fmt.Println(string(out)) - gomega.Expect(err).Should(gomega.BeNil()) + // cmd := exec.Command("../../scripts/build.sh") + // out, err := cmd.CombinedOutput() + // fmt.Println(string(out)) + // gomega.Expect(err).Should(gomega.BeNil()) // Name 10 new validators (which should have BLS key registered) subnetANodeNames := make([]string, 0) @@ -72,7 +83,7 @@ var _ = ginkgo.BeforeSuite(func() { gomega.Expect(err).Should(gomega.BeNil()) err = manager.SetupNetwork( ctx, - config.AvalancheGoExecPath, + anrConfig.AvalancheGoExecPath, []*rpcpb.BlockchainSpec{ { VmName: evm.IDStr, @@ -112,3 +123,175 @@ var _ = ginkgo.BeforeSuite(func() { err = utils.IssueTxsToActivateProposerVMFork(ctx, chainID, fundedKey, client) gomega.Expect(err).Should(gomega.BeNil()) }) + +var _ = ginkgo.AfterSuite(func() { + gomega.Expect(manager).ShouldNot(gomega.BeNil()) + gomega.Expect(manager.TeardownNetwork()).Should(gomega.BeNil()) + gomega.Expect(os.Remove(warpChainConfigPath)).Should(gomega.BeNil()) +}) + +var _ = ginkgo.Describe("[Relay]", ginkgo.Ordered, func() { + var ( + subnetA, subnetB ids.ID + blockchainIDA, blockchainIDB ids.ID + chainAURIs, chainBURIs []string + fundedKey *ecdsa.PrivateKey + fundedAddress common.Address + err error + // unsignedWarpMsg *avalancheWarp.UnsignedMessage + // unsignedWarpMessageID ids.ID + // signedWarpMsg *avalancheWarp.Message + // chainAWSClient, chainBWSClient ethclient.Client + // chainID = big.NewInt(99999) + // payload = []byte{1, 2, 3} + // txSigner = types.LatestSignerForChainID(chainID) + ) + + fundedKey, err = crypto.HexToECDSA(fundedKeyStr) + if err != nil { + panic(err) + } + fundedAddress = crypto.PubkeyToAddress(fundedKey.PublicKey) + + ginkgo.It("Setup subnet URIs", ginkgo.Label("Warp", "SetupWarp"), func() { + subnetIDs := manager.GetSubnets() + gomega.Expect(len(subnetIDs)).Should(gomega.Equal(2)) + + subnetA = subnetIDs[0] + subnetADetails, ok := manager.GetSubnet(subnetA) + gomega.Expect(ok).Should(gomega.BeTrue()) + blockchainIDA = subnetADetails.BlockchainID + gomega.Expect(len(subnetADetails.ValidatorURIs)).Should(gomega.Equal(5)) + chainAURIs = append(chainAURIs, subnetADetails.ValidatorURIs...) + + subnetB = subnetIDs[1] + subnetBDetails, ok := manager.GetSubnet(subnetB) + gomega.Expect(ok).Should(gomega.BeTrue()) + blockchainIDB := subnetBDetails.BlockchainID + gomega.Expect(len(subnetBDetails.ValidatorURIs)).Should(gomega.Equal(5)) + chainBURIs = append(chainBURIs, subnetBDetails.ValidatorURIs...) + + log.Info("Created URIs for both subnets", "ChainAURIs", chainAURIs, "ChainBURIs", chainBURIs, "blockchainIDA", blockchainIDA, "blockchainIDB", blockchainIDB) + + chainAWSURI := toWebsocketURI(chainAURIs[0], blockchainIDA.String()) + log.Info("Creating ethclient for blockchainA", "wsURI", chainAWSURI) + _, err = ethclient.Dial(chainAWSURI) + gomega.Expect(err).Should(gomega.BeNil()) + + chainBWSURI := toWebsocketURI(chainBURIs[0], blockchainIDB.String()) + log.Info("Creating ethclient for blockchainB", "wsURI", chainBWSURI) + _, err = ethclient.Dial(chainBWSURI) + gomega.Expect(err).Should(gomega.BeNil()) + }) + + ginkgo.It("Set up awm-relayer", ginkgo.Label("Relayer", "SetupRelayer"), func() { + subnetADetails, ok := manager.GetSubnet(subnetA) + gomega.Expect(ok).Should(gomega.BeTrue()) + + hostA, portA, err := getURIHostAndPort(subnetADetails.ValidatorURIs[0]) + gomega.Expect(err).Should(gomega.BeNil()) + + subnetBDetails, ok := manager.GetSubnet(subnetB) + gomega.Expect(ok).Should(gomega.BeTrue()) + + hostB, portB, err := getURIHostAndPort(subnetBDetails.ValidatorURIs[0]) + gomega.Expect(err).Should(gomega.BeNil()) + + relayerConfig := config.Config{ + NetworkID: 1337, + PChainAPIURL: subnetADetails.ValidatorURIs[0], + EncryptConnection: false, + SourceSubnets: []config.SourceSubnet{ + { + SubnetID: subnetA.String(), + ChainID: blockchainIDA.String(), + VM: config.EVM.String(), + EncryptConnection: false, + APINodeHost: hostA, + APINodePort: portA, + MessageContracts: map[string]config.MessageProtocolConfig{ + teleporterContractAddress.Hex(): { + MessageFormat: "teleporter", + Settings: map[string]interface{}{ + "reward-address": fundedAddress.Hex(), + }, + }, + }, + }, + }, + DestinationSubnets: []config.DestinationSubnet{ + { + SubnetID: subnetB.String(), + ChainID: blockchainIDB.String(), + VM: config.EVM.String(), + EncryptConnection: false, + APINodeHost: hostB, + APINodePort: portB, + AccountPrivateKey: fundedKeyStr, + }, + }, + } + + // relayerConfigPath := "./tests/e2e/relayer-config.json" + data, err := json.MarshalIndent(relayerConfig, "", "\t") + gomega.Expect(err).Should(gomega.BeNil()) + + f, err := os.CreateTemp(os.TempDir(), "relayer-config.json") + gomega.Expect(err).Should(gomega.BeNil()) + + _, err = f.Write(data) + gomega.Expect(err).Should(gomega.BeNil()) + relayerConfigPath = f.Name() + + log.Info("Created awm-relayer config", "configPath", relayerConfigPath, "config", string(data)) + }) +}) + +func getANRClient() (anr_client.Client, error) { + logLevel, err := logging.ToLevel(logging.Info.String()) + if err != nil { + return nil, fmt.Errorf("failed to parse ANR log level: %w", err) + } + logFactory := logging.NewFactory(logging.Config{ + DisplayLevel: logLevel, + LogLevel: logLevel, + }) + zapLog, err := logFactory.Make("main") + if err != nil { + return nil, fmt.Errorf("failed to make client log: %w", err) + } + + anrClient, err := anr_client.New(anr_client.Config{ + Endpoint: "0.0.0.0:12352", + DialTimeout: 10 * time.Second, + }, zapLog) + if err != nil { + return nil, fmt.Errorf("failed to start ANR client: %w", err) + } + + return anrClient, nil +} + +func getURIHostAndPort(uri string) (string, uint32, error) { + // At a minimum uri should have http:// of 7 characters + gomega.Expect(len(uri)).Should(gomega.BeNumerically(">", 7)) + if uri[:7] == "http://" { + uri = uri[7:] + } else if uri[:8] == "https://" { + uri = uri[8:] + } else { + return "", 0, fmt.Errorf("invalid uri: %s", uri) + } + + // Split the uri into host and port + hostAndPort := strings.Split(uri, ":") + gomega.Expect(len(hostAndPort)).Should(gomega.Equal(2)) + + // Parse the port + port, err := strconv.ParseUint(hostAndPort[1], 10, 32) + if err != nil { + return "", 0, fmt.Errorf("failed to parse port: %w", err) + } + + return hostAndPort[0], uint32(port), nil +} From 9ae7286fb8f9dbd4370c4528be0d43dbd8d78c08 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 21:16:12 +0000 Subject: [PATCH 06/56] build command and add RUN_E2E env var --- tests/e2e/constants.go | 11 ----------- tests/e2e/e2e_test.go | 41 +++++++++-------------------------------- 2 files changed, 9 insertions(+), 43 deletions(-) delete mode 100644 tests/e2e/constants.go diff --git a/tests/e2e/constants.go b/tests/e2e/constants.go deleted file mode 100644 index 533821d1..00000000 --- a/tests/e2e/constants.go +++ /dev/null @@ -1,11 +0,0 @@ -package tests - -import ( - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/awm-relayer/config" -) - -var testConfig = config.Config{ - NetworkID: constants.UnitTestID, - EncryptConnection: false, -} diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 9d889e74..9f177d61 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -7,15 +7,13 @@ import ( "fmt" "math/big" "os" + "os/exec" "strconv" "strings" "testing" - "time" - anr_client "github.com/ava-labs/avalanche-network-runner/client" "github.com/ava-labs/avalanche-network-runner/rpcpb" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/awm-relayer/config" "github.com/ava-labs/subnet-evm/ethclient" "github.com/ava-labs/subnet-evm/plugin/evm" @@ -39,6 +37,10 @@ var ( ) func TestE2E(t *testing.T) { + if os.Getenv("RUN_E2E") == "" { + t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") + } + gomega.RegisterFailHandler(ginkgo.Fail) ginkgo.RunSpecs(t, "awm-relayer e2e test") } @@ -56,10 +58,10 @@ var _ = ginkgo.BeforeSuite(func() { var err error // Build the awm-relayer binary - // cmd := exec.Command("../../scripts/build.sh") - // out, err := cmd.CombinedOutput() - // fmt.Println(string(out)) - // gomega.Expect(err).Should(gomega.BeNil()) + cmd := exec.Command("./scripts/build.sh") + out, err := cmd.CombinedOutput() + fmt.Println(string(out)) + gomega.Expect(err).Should(gomega.BeNil()) // Name 10 new validators (which should have BLS key registered) subnetANodeNames := make([]string, 0) @@ -247,31 +249,6 @@ var _ = ginkgo.Describe("[Relay]", ginkgo.Ordered, func() { }) }) -func getANRClient() (anr_client.Client, error) { - logLevel, err := logging.ToLevel(logging.Info.String()) - if err != nil { - return nil, fmt.Errorf("failed to parse ANR log level: %w", err) - } - logFactory := logging.NewFactory(logging.Config{ - DisplayLevel: logLevel, - LogLevel: logLevel, - }) - zapLog, err := logFactory.Make("main") - if err != nil { - return nil, fmt.Errorf("failed to make client log: %w", err) - } - - anrClient, err := anr_client.New(anr_client.Config{ - Endpoint: "0.0.0.0:12352", - DialTimeout: 10 * time.Second, - }, zapLog) - if err != nil { - return nil, fmt.Errorf("failed to start ANR client: %w", err) - } - - return anrClient, nil -} - func getURIHostAndPort(uri string) (string, uint32, error) { // At a minimum uri should have http:// of 7 characters gomega.Expect(len(uri)).Should(gomega.BeNumerically(">", 7)) From e34680dece94c2a871f40e594745014a47c58653 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 21:30:14 +0000 Subject: [PATCH 07/56] test ginkgo tests logs --- scripts/e2e_test.sh | 4 +++- tests/e2e/e2e_test.go | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/scripts/e2e_test.sh b/scripts/e2e_test.sh index 846d179c..1bb7d33b 100755 --- a/scripts/e2e_test.sh +++ b/scripts/e2e_test.sh @@ -10,11 +10,13 @@ source "$AWM_RELAYER_PATH"/scripts/constants.sh source "$AWM_RELAYER_PATH"/scripts/versions.sh +RUN_E2E=true + # Build ginkgo # to install the ginkgo binary (required for test build and run) go install -v github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION} -ginkgo build ./tests/e2e +ACK_GINKGO_RC=true ginkgo build ./tests/e2e # Run the tests ./tests/e2e/e2e.test \ diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 9f177d61..28c33ffb 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -63,6 +63,12 @@ var _ = ginkgo.BeforeSuite(func() { fmt.Println(string(out)) gomega.Expect(err).Should(gomega.BeNil()) + cmd = exec.Command(fmt.Sprintf("echo %s", "hello world")) + out, err = cmd.CombinedOutput() + fmt.Println(string(out)) + gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Tested hello world") + // Name 10 new validators (which should have BLS key registered) subnetANodeNames := make([]string, 0) subnetBNodeNames := []string{} @@ -247,6 +253,10 @@ var _ = ginkgo.Describe("[Relay]", ginkgo.Ordered, func() { log.Info("Created awm-relayer config", "configPath", relayerConfigPath, "config", string(data)) }) + + ginkgo.It("Should fail", ginkgo.Label("Relayer", "Fail"), func() { + gomega.Expect(false).Should(gomega.BeTrue()) + }) }) func getURIHostAndPort(uri string) (string, uint32, error) { From 09cb5d0224f8ba90248bb92d38ee16a74be834cb Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 21:34:00 +0000 Subject: [PATCH 08/56] testing why ginkgo tests aren't running --- scripts/e2e_test.sh | 5 ++++- tests/e2e/e2e_test.go | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/e2e_test.sh b/scripts/e2e_test.sh index 1bb7d33b..a71288a1 100755 --- a/scripts/e2e_test.sh +++ b/scripts/e2e_test.sh @@ -19,6 +19,9 @@ go install -v github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION} ACK_GINKGO_RC=true ginkgo build ./tests/e2e # Run the tests +echo "Running e2e tests $RUN_E2E" ./tests/e2e/e2e.test \ --ginkgo.vv \ - --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} \ No newline at end of file + --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} + + echo "e2e tests passed" \ No newline at end of file diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 28c33ffb..b6200072 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -37,6 +37,11 @@ var ( ) func TestE2E(t *testing.T) { + cmd := exec.Command(fmt.Sprintf("echo %s", "hello world2")) + out, err := cmd.CombinedOutput() + fmt.Println(string(out)) + gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Tested hello world2") if os.Getenv("RUN_E2E") == "" { t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") } From 1bda5f1fd79a801a0723f03e1acafd87dce83bb3 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 21:49:44 +0000 Subject: [PATCH 09/56] tests should fail if ran properly --- tests/e2e/e2e_test.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index b6200072..2f768290 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -37,10 +37,6 @@ var ( ) func TestE2E(t *testing.T) { - cmd := exec.Command(fmt.Sprintf("echo %s", "hello world2")) - out, err := cmd.CombinedOutput() - fmt.Println(string(out)) - gomega.Expect(err).Should(gomega.BeNil()) log.Info("Tested hello world2") if os.Getenv("RUN_E2E") == "" { t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") @@ -68,10 +64,6 @@ var _ = ginkgo.BeforeSuite(func() { fmt.Println(string(out)) gomega.Expect(err).Should(gomega.BeNil()) - cmd = exec.Command(fmt.Sprintf("echo %s", "hello world")) - out, err = cmd.CombinedOutput() - fmt.Println(string(out)) - gomega.Expect(err).Should(gomega.BeNil()) log.Info("Tested hello world") // Name 10 new validators (which should have BLS key registered) From da419948831691c4076ce2f87167adc755040232 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 21:57:53 +0000 Subject: [PATCH 10/56] add debug logs --- scripts/e2e_test.sh | 2 +- tests/e2e/e2e_test.go | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/e2e_test.sh b/scripts/e2e_test.sh index a71288a1..00300c31 100755 --- a/scripts/e2e_test.sh +++ b/scripts/e2e_test.sh @@ -20,7 +20,7 @@ ACK_GINKGO_RC=true ginkgo build ./tests/e2e # Run the tests echo "Running e2e tests $RUN_E2E" -./tests/e2e/e2e.test \ +RUN_E2E=true ./tests/e2e/e2e.test \ --ginkgo.vv \ --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 2f768290..bebfcc3b 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -37,13 +37,15 @@ var ( ) func TestE2E(t *testing.T) { - log.Info("Tested hello world2") + log.Info("RUN_E2E value is", "value", os.Getenv("RUN_E2E")) if os.Getenv("RUN_E2E") == "" { t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") } gomega.RegisterFailHandler(ginkgo.Fail) - ginkgo.RunSpecs(t, "awm-relayer e2e test") + ginkgo.RunSpecs(t, "Relayer e2e test") + + log.Info("Ran ginkgo specs") } func toWebsocketURI(uri string, blockchainID string) string { @@ -55,6 +57,7 @@ func toWebsocketURI(uri string, blockchainID string) string { // Adds two disjoint sets of 5 of the new validator nodes to validate two new subnets with a // a single Subnet-EVM blockchain. var _ = ginkgo.BeforeSuite(func() { + log.Info("Got to ginkgo before suite") ctx := context.Background() var err error @@ -130,12 +133,14 @@ var _ = ginkgo.BeforeSuite(func() { }) var _ = ginkgo.AfterSuite(func() { + log.Info("Got to ginkgo after suite") gomega.Expect(manager).ShouldNot(gomega.BeNil()) gomega.Expect(manager.TeardownNetwork()).Should(gomega.BeNil()) gomega.Expect(os.Remove(warpChainConfigPath)).Should(gomega.BeNil()) }) -var _ = ginkgo.Describe("[Relay]", ginkgo.Ordered, func() { +var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { + log.Info("Got to ginkgo describe") var ( subnetA, subnetB ids.ID blockchainIDA, blockchainIDB ids.ID @@ -158,7 +163,7 @@ var _ = ginkgo.Describe("[Relay]", ginkgo.Ordered, func() { } fundedAddress = crypto.PubkeyToAddress(fundedKey.PublicKey) - ginkgo.It("Setup subnet URIs", ginkgo.Label("Warp", "SetupWarp"), func() { + ginkgo.It("Setup subnet URIs", ginkgo.Label("Relayer", "SetupWarp"), func() { subnetIDs := manager.GetSubnets() gomega.Expect(len(subnetIDs)).Should(gomega.Equal(2)) From 6c2a1b43a80b7655dcf9eea4779f10f1747d1685 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 22:28:24 +0000 Subject: [PATCH 11/56] build and run relayer --- tests/e2e/e2e_test.go | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index bebfcc3b..8a250d91 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -61,14 +61,6 @@ var _ = ginkgo.BeforeSuite(func() { ctx := context.Background() var err error - // Build the awm-relayer binary - cmd := exec.Command("./scripts/build.sh") - out, err := cmd.CombinedOutput() - fmt.Println(string(out)) - gomega.Expect(err).Should(gomega.BeNil()) - - log.Info("Tested hello world") - // Name 10 new validators (which should have BLS key registered) subnetANodeNames := make([]string, 0) subnetBNodeNames := []string{} @@ -137,6 +129,7 @@ var _ = ginkgo.AfterSuite(func() { gomega.Expect(manager).ShouldNot(gomega.BeNil()) gomega.Expect(manager.TeardownNetwork()).Should(gomega.BeNil()) gomega.Expect(os.Remove(warpChainConfigPath)).Should(gomega.BeNil()) + gomega.Expect(os.Remove(relayerConfigPath)).Should(gomega.BeNil()) }) var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { @@ -194,7 +187,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) }) - ginkgo.It("Set up awm-relayer", ginkgo.Label("Relayer", "SetupRelayer"), func() { + ginkgo.It("Set up relayer configr", ginkgo.Label("Relayer", "Setup Relayer"), func() { subnetADetails, ok := manager.GetSubnet(subnetA) gomega.Expect(ok).Should(gomega.BeTrue()) @@ -256,8 +249,19 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { log.Info("Created awm-relayer config", "configPath", relayerConfigPath, "config", string(data)) }) - ginkgo.It("Should fail", ginkgo.Label("Relayer", "Fail"), func() { - gomega.Expect(false).Should(gomega.BeTrue()) + ginkgo.It("Build + Run Relayer", ginkgo.Label("Relayer", "Run Relayer"), func() { + // Build the awm-relayer binary + cmd := exec.Command("./scripts/build.sh") + out, err := cmd.CombinedOutput() + fmt.Println(string(out)) + gomega.Expect(err).Should(gomega.BeNil()) + + // Run awm relayer binary with config path + cmd = exec.Command("./build/awm-relayer", "--config", relayerConfigPath) + out, err = cmd.CombinedOutput() + fmt.Println(string(out)) + gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Running relayer") }) }) From f2c2270de394d65b61a0d005772da0e29e84728e Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 22:32:53 +0000 Subject: [PATCH 12/56] fix config file option --- tests/e2e/e2e_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 8a250d91..099c4b38 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -257,7 +257,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) // Run awm relayer binary with config path - cmd = exec.Command("./build/awm-relayer", "--config", relayerConfigPath) + cmd = exec.Command("./build/awm-relayer", "--config-file", relayerConfigPath) out, err = cmd.CombinedOutput() fmt.Println(string(out)) gomega.Expect(err).Should(gomega.BeNil()) From 5f64426981cc9349d4ebb2802486edb4efefadd4 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 22:51:08 +0000 Subject: [PATCH 13/56] fix logging info default --- config/config.go | 3 +- tests/e2e/e2e_test.go | 117 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 105 insertions(+), 15 deletions(-) diff --git a/config/config.go b/config/config.go index 41a07cea..91bca8c2 100644 --- a/config/config.go +++ b/config/config.go @@ -14,6 +14,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/awm-relayer/utils" "github.com/ethereum/go-ethereum/common" @@ -67,7 +68,7 @@ type Config struct { } func SetDefaultConfigValues(v *viper.Viper) { - v.SetDefault(LogLevelKey, "info") + v.SetDefault(LogLevelKey, logging.Info.String()) v.SetDefault(NetworkIDKey, constants.MainnetID) v.SetDefault(PChainAPIURLKey, "https://api.avax.network") v.SetDefault(EncryptConnectionKey, true) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 099c4b38..0ff145d0 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -14,11 +14,17 @@ import ( "github.com/ava-labs/avalanche-network-runner/rpcpb" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/logging" + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/awm-relayer/config" + "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/ethclient" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/plugin/evm" "github.com/ava-labs/subnet-evm/tests/utils" "github.com/ava-labs/subnet-evm/tests/utils/runner" + "github.com/ava-labs/subnet-evm/x/warp" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" @@ -135,19 +141,19 @@ var _ = ginkgo.AfterSuite(func() { var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { log.Info("Got to ginkgo describe") var ( - subnetA, subnetB ids.ID - blockchainIDA, blockchainIDB ids.ID - chainAURIs, chainBURIs []string - fundedKey *ecdsa.PrivateKey - fundedAddress common.Address - err error - // unsignedWarpMsg *avalancheWarp.UnsignedMessage - // unsignedWarpMessageID ids.ID - // signedWarpMsg *avalancheWarp.Message - // chainAWSClient, chainBWSClient ethclient.Client - // chainID = big.NewInt(99999) - // payload = []byte{1, 2, 3} - // txSigner = types.LatestSignerForChainID(chainID) + subnetA, subnetB ids.ID + blockchainIDA, blockchainIDB ids.ID + chainAURIs, chainBURIs []string + fundedKey *ecdsa.PrivateKey + fundedAddress common.Address + err error + unsignedWarpMsg *avalancheWarp.UnsignedMessage + unsignedWarpMessageID ids.ID + signedWarpMsg *avalancheWarp.Message + chainAWSClient, chainBWSClient ethclient.Client + chainID = big.NewInt(99999) + payload = []byte{1, 2, 3} + txSigner = types.LatestSignerForChainID(chainID) ) fundedKey, err = crypto.HexToECDSA(fundedKeyStr) @@ -187,7 +193,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) }) - ginkgo.It("Set up relayer configr", ginkgo.Label("Relayer", "Setup Relayer"), func() { + ginkgo.It("Set up relayer config", ginkgo.Label("Relayer", "Setup Relayer"), func() { subnetADetails, ok := manager.GetSubnet(subnetA) gomega.Expect(ok).Should(gomega.BeTrue()) @@ -201,6 +207,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) relayerConfig := config.Config{ + LogLevel: logging.Info.LowerString(), NetworkID: 1337, PChainAPIURL: subnetADetails.ValidatorURIs[0], EncryptConnection: false, @@ -263,6 +270,88 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) log.Info("Running relayer") }) + + // Send a transaction to Subnet A to issue a Warp Message to Subnet B + ginkgo.It("Send Message from A to B", ginkgo.Label("Warp", "SendWarp"), func() { + ctx := context.Background() + + gomega.Expect(err).Should(gomega.BeNil()) + + log.Info("Subscribing to new heads") + newHeads := make(chan *types.Header, 10) + sub, err := chainAWSClient.SubscribeNewHead(ctx, newHeads) + gomega.Expect(err).Should(gomega.BeNil()) + defer sub.Unsubscribe() + + startingNonce, err := chainAWSClient.NonceAt(ctx, fundedAddress, nil) + gomega.Expect(err).Should(gomega.BeNil()) + + packedInput, err := warp.PackSendWarpMessage(warp.SendWarpMessageInput{ + DestinationChainID: common.Hash(blockchainIDB), + DestinationAddress: fundedAddress, + Payload: payload, + }) + gomega.Expect(err).Should(gomega.BeNil()) + tx := types.NewTx(&types.DynamicFeeTx{ + ChainID: chainID, + Nonce: startingNonce, + To: &warp.Module.Address, + Gas: 200_000, + GasFeeCap: big.NewInt(225 * params.GWei), + GasTipCap: big.NewInt(params.GWei), + Value: common.Big0, + Data: packedInput, + }) + signedTx, err := types.SignTx(tx, txSigner, fundedKey) + gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Sending sendWarpMessage transaction", "txHash", signedTx.Hash()) + err = chainAWSClient.SendTransaction(ctx, signedTx) + gomega.Expect(err).Should(gomega.BeNil()) + + log.Info("Waiting for new block confirmation") + newHead := <-newHeads + blockHash := newHead.Hash() + + log.Info("Fetching relevant warp logs from the newly produced block") + logs, err := chainAWSClient.FilterLogs(ctx, interfaces.FilterQuery{ + BlockHash: &blockHash, + Addresses: []common.Address{warp.Module.Address}, + }) + gomega.Expect(err).Should(gomega.BeNil()) + gomega.Expect(len(logs)).Should(gomega.Equal(1)) + + // Check for relevant warp log from subscription and ensure that it matches + // the log extracted from the last block. + txLog := logs[0] + log.Info("Parsing logData as unsigned warp message") + unsignedMsg, err := avalancheWarp.ParseUnsignedMessage(txLog.Data) + gomega.Expect(err).Should(gomega.BeNil()) + + // Set local variables for the duration of the test + unsignedWarpMessageID = unsignedMsg.ID() + unsignedWarpMsg = unsignedMsg + log.Info("Parsed unsignedWarpMsg", "unsignedWarpMessageID", unsignedWarpMessageID, "unsignedWarpMessage", unsignedWarpMsg) + + // Loop over each client on chain A to ensure they all have time to accept the block. + // Note: if we did not confirm this here, the next stage could be racy since it assumes every node + // has accepted the block. + for i, uri := range chainAURIs { + chainAWSURI := toWebsocketURI(uri, blockchainIDA.String()) + log.Info("Creating ethclient for blockchainA", "wsURI", chainAWSURI) + client, err := ethclient.Dial(chainAWSURI) + gomega.Expect(err).Should(gomega.BeNil()) + + // Loop until each node has advanced to >= the height of the block that emitted the warp log + for { + block, err := client.BlockByNumber(ctx, nil) + gomega.Expect(err).Should(gomega.BeNil()) + if block.NumberU64() >= newHead.Number.Uint64() { + log.Info("client accepted the block containing SendWarpMessage", "client", i, "height", block.NumberU64()) + break + } + } + } + }) }) func getURIHostAndPort(uri string) (string, uint32, error) { From a84cb32d45ff9fa65b221c553654338f67eec2b8 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 23:09:23 +0000 Subject: [PATCH 14/56] sending teleporter message from a to b --- messages/teleporter/message_test.go | 9 +--- messages/teleporter/utils.go | 8 +++ tests/e2e/e2e_test.go | 80 ++++++++++++++++++----------- 3 files changed, 58 insertions(+), 39 deletions(-) diff --git a/messages/teleporter/message_test.go b/messages/teleporter/message_test.go index 62740217..e71e6772 100644 --- a/messages/teleporter/message_test.go +++ b/messages/teleporter/message_test.go @@ -33,17 +33,10 @@ func testTeleporterMessage(messageID int64) TeleporterMessage { return m } -// Pack the SendCrossChainMessage event type. PackEvent is documented as not supporting struct types, so this should be used -// with caution. Here, we only use it for testing purposes. In a real setting, the Teleporter contract should pack the event. -func packTeleporterMessage(destinationChainID common.Hash, message TeleporterMessage) ([]byte, error) { - _, hashes, err := EVMTeleporterContractABI.PackEvent("SendCrossChainMessage", destinationChainID, message.MessageID, message) - return hashes, err -} - func TestPackUnpackTeleporterMessage(t *testing.T) { message := testTeleporterMessage(4) - b, err := packTeleporterMessage(common.HexToHash("0x03"), message) + b, err := PackTeleporterMessage(common.HexToHash("0x03"), message) if err != nil { t.Errorf("failed to pack teleporter message: %v", err) t.FailNow() diff --git a/messages/teleporter/utils.go b/messages/teleporter/utils.go index 5b66648f..bc3e5081 100644 --- a/messages/teleporter/utils.go +++ b/messages/teleporter/utils.go @@ -9,6 +9,7 @@ import ( "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/awm-relayer/utils" + "github.com/ethereum/go-ethereum/common" ) const ( @@ -47,3 +48,10 @@ func CalculateReceiveMessageGasLimit(numSigners int, executionRequiredGasLimit * return res, nil } + +// Pack the SendCrossChainMessage event type. PackEvent is documented as not supporting struct types, so this should be used +// with caution. Here, we only use it for testing purposes. In a real setting, the Teleporter contract should pack the event. +func PackTeleporterMessage(destinationChainID common.Hash, message TeleporterMessage) ([]byte, error) { + _, hashes, err := EVMTeleporterContractABI.PackEvent("SendCrossChainMessage", destinationChainID, message.MessageID, message) + return hashes, err +} diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 0ff145d0..ed58210b 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/awm-relayer/config" + "github.com/ava-labs/awm-relayer/messages/teleporter" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/ethclient" "github.com/ava-labs/subnet-evm/interfaces" @@ -40,6 +41,15 @@ var ( warpChainConfigPath string relayerConfigPath string teleporterContractAddress = common.HexToAddress("27aE10273D17Cd7e80de8580A51f476960626e5f") + teleporterMessage = teleporter.TeleporterMessage{ + MessageID: big.NewInt(1), + SenderAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), + DestinationAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), + RequiredGasLimit: big.NewInt(1), + AllowedRelayerAddresses: []common.Address{}, + Receipts: []teleporter.TeleporterMessageReceipt{}, + Message: []byte{1, 2, 3, 4}, + } ) func TestE2E(t *testing.T) { @@ -141,18 +151,18 @@ var _ = ginkgo.AfterSuite(func() { var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { log.Info("Got to ginkgo describe") var ( - subnetA, subnetB ids.ID - blockchainIDA, blockchainIDB ids.ID - chainAURIs, chainBURIs []string - fundedKey *ecdsa.PrivateKey - fundedAddress common.Address - err error - unsignedWarpMsg *avalancheWarp.UnsignedMessage - unsignedWarpMessageID ids.ID - signedWarpMsg *avalancheWarp.Message + subnetA, subnetB ids.ID + blockchainIDA, blockchainIDB ids.ID + chainAURIs, chainBURIs []string + fundedKey *ecdsa.PrivateKey + fundedAddress common.Address + err error + unsignedWarpMsg *avalancheWarp.UnsignedMessage + unsignedWarpMessageID ids.ID + // signedWarpMsg *avalancheWarp.Message chainAWSClient, chainBWSClient ethclient.Client chainID = big.NewInt(99999) - payload = []byte{1, 2, 3} + payload = []byte{} txSigner = types.LatestSignerForChainID(chainID) ) @@ -278,14 +288,22 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) log.Info("Subscribing to new heads") - newHeads := make(chan *types.Header, 10) - sub, err := chainAWSClient.SubscribeNewHead(ctx, newHeads) + // newHeadsA := make(chan *types.Header, 10) + // sub, err := chainAWSClient.SubscribeNewHead(ctx, newHeadsA) + // gomega.Expect(err).Should(gomega.BeNil()) + // defer sub.Unsubscribe() + + newHeadsB := make(chan *types.Header, 10) + sub, err := chainBWSClient.SubscribeNewHead(ctx, newHeadsB) gomega.Expect(err).Should(gomega.BeNil()) defer sub.Unsubscribe() startingNonce, err := chainAWSClient.NonceAt(ctx, fundedAddress, nil) gomega.Expect(err).Should(gomega.BeNil()) + payload, err = teleporter.PackTeleporterMessage(common.Hash(blockchainIDB), teleporterMessage) + gomega.Expect(err).Should(gomega.BeNil()) + packedInput, err := warp.PackSendWarpMessage(warp.SendWarpMessageInput{ DestinationChainID: common.Hash(blockchainIDB), DestinationAddress: fundedAddress, @@ -304,16 +322,16 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { }) signedTx, err := types.SignTx(tx, txSigner, fundedKey) gomega.Expect(err).Should(gomega.BeNil()) - log.Info("Sending sendWarpMessage transaction", "txHash", signedTx.Hash()) + log.Info("Sending sendWarpMessage transaction", "destinationChainID", blockchainIDB, "txHash", signedTx.Hash()) err = chainAWSClient.SendTransaction(ctx, signedTx) gomega.Expect(err).Should(gomega.BeNil()) log.Info("Waiting for new block confirmation") - newHead := <-newHeads + newHead := <-newHeadsB blockHash := newHead.Hash() log.Info("Fetching relevant warp logs from the newly produced block") - logs, err := chainAWSClient.FilterLogs(ctx, interfaces.FilterQuery{ + logs, err := chainBWSClient.FilterLogs(ctx, interfaces.FilterQuery{ BlockHash: &blockHash, Addresses: []common.Address{warp.Module.Address}, }) @@ -335,22 +353,22 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { // Loop over each client on chain A to ensure they all have time to accept the block. // Note: if we did not confirm this here, the next stage could be racy since it assumes every node // has accepted the block. - for i, uri := range chainAURIs { - chainAWSURI := toWebsocketURI(uri, blockchainIDA.String()) - log.Info("Creating ethclient for blockchainA", "wsURI", chainAWSURI) - client, err := ethclient.Dial(chainAWSURI) - gomega.Expect(err).Should(gomega.BeNil()) - - // Loop until each node has advanced to >= the height of the block that emitted the warp log - for { - block, err := client.BlockByNumber(ctx, nil) - gomega.Expect(err).Should(gomega.BeNil()) - if block.NumberU64() >= newHead.Number.Uint64() { - log.Info("client accepted the block containing SendWarpMessage", "client", i, "height", block.NumberU64()) - break - } - } - } + // for i, uri := range chainAURIs { + // chainAWSURI := toWebsocketURI(uri, blockchainIDA.String()) + // log.Info("Creating ethclient for blockchainA", "wsURI", chainAWSURI) + // client, err := ethclient.Dial(chainAWSURI) + // gomega.Expect(err).Should(gomega.BeNil()) + + // // Loop until each node has advanced to >= the height of the block that emitted the warp log + // for { + // block, err := client.BlockByNumber(ctx, nil) + // gomega.Expect(err).Should(gomega.BeNil()) + // if block.NumberU64() >= newHead.Number.Uint64() { + // log.Info("client accepted the block containing SendWarpMessage", "client", i, "height", block.NumberU64()) + // break + // } + // } + // } }) }) From 3994285cfd55db0f3f57b9e0902fec51f89e14ca Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 31 Aug 2023 23:45:43 +0000 Subject: [PATCH 15/56] extra debug logs and get chainB nonce --- tests/e2e/e2e_test.go | 9 ++++++++- vms/evm/destination_client.go | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index ed58210b..0744c555 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -216,6 +216,8 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { hostB, portB, err := getURIHostAndPort(subnetBDetails.ValidatorURIs[0]) gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Setting up relayer config", "hostA", hostA, "portA", portA, "blockChainA", blockchainIDA, "hostB", hostB, "portB", portB, "blockChainB", blockchainIDB) + relayerConfig := config.Config{ LogLevel: logging.Info.LowerString(), NetworkID: 1337, @@ -301,12 +303,17 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { startingNonce, err := chainAWSClient.NonceAt(ctx, fundedAddress, nil) gomega.Expect(err).Should(gomega.BeNil()) + nonce, err := chainBWSClient.NonceAt(ctx, fundedAddress, nil) + gomega.Expect(err).Should(gomega.BeNil()) + + log.Info("Packing teleporter message", "nonceA", startingNonce, "nonceB", nonce) + payload, err = teleporter.PackTeleporterMessage(common.Hash(blockchainIDB), teleporterMessage) gomega.Expect(err).Should(gomega.BeNil()) packedInput, err := warp.PackSendWarpMessage(warp.SendWarpMessageInput{ DestinationChainID: common.Hash(blockchainIDB), - DestinationAddress: fundedAddress, + DestinationAddress: teleporterContractAddress, Payload: payload, }) gomega.Expect(err).Should(gomega.BeNil()) diff --git a/vms/evm/destination_client.go b/vms/evm/destination_client.go index 57ade4ce..02e3dda1 100644 --- a/vms/evm/destination_client.go +++ b/vms/evm/destination_client.go @@ -79,6 +79,9 @@ func NewDestinationClient(logger logging.Logger, subnetInfo config.DestinationSu if err != nil { logger.Error( "Failed to get nonce", + zap.String("eoa", eoa.String()), + zap.String("chainID", destinationID.String()), + zap.String("rpcEndpoint", subnetInfo.GetNodeRPCEndpoint()), zap.Error(err), ) return nil, err From 50e2d5ea86e4d4be3abda6a407690fe0398a1f52 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Fri, 1 Sep 2023 00:05:27 +0000 Subject: [PATCH 16/56] replacing default chainID --- tests/e2e/e2e_test.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 0744c555..1d971b68 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -124,7 +124,6 @@ var _ = ginkgo.BeforeSuite(func() { gomega.Expect(err).Should(gomega.BeNil()) // Issue transactions to activate the proposerVM fork on the receiving chain - chainID := big.NewInt(99999) fundedKey, err := crypto.HexToECDSA(fundedKeyStr) gomega.Expect(err).Should(gomega.BeNil()) subnetB := manager.GetSubnets()[1] @@ -135,8 +134,10 @@ var _ = ginkgo.BeforeSuite(func() { uri := toWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) client, err := ethclient.Dial(uri) gomega.Expect(err).Should(gomega.BeNil()) + chainBIDInt, err := client.ChainID(ctx) + gomega.Expect(err).Should(gomega.BeNil()) - err = utils.IssueTxsToActivateProposerVMFork(ctx, chainID, fundedKey, client) + err = utils.IssueTxsToActivateProposerVMFork(ctx, chainBIDInt, fundedKey, client) gomega.Expect(err).Should(gomega.BeNil()) }) @@ -161,9 +162,8 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { unsignedWarpMessageID ids.ID // signedWarpMsg *avalancheWarp.Message chainAWSClient, chainBWSClient ethclient.Client - chainID = big.NewInt(99999) + chainAIDInt *big.Int payload = []byte{} - txSigner = types.LatestSignerForChainID(chainID) ) fundedKey, err = crypto.HexToECDSA(fundedKeyStr) @@ -197,10 +197,16 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { _, err = ethclient.Dial(chainAWSURI) gomega.Expect(err).Should(gomega.BeNil()) + chainAIDInt, err = chainAWSClient.ChainID(context.Background()) + gomega.Expect(err).Should(gomega.BeNil()) + chainBWSURI := toWebsocketURI(chainBURIs[0], blockchainIDB.String()) log.Info("Creating ethclient for blockchainB", "wsURI", chainBWSURI) _, err = ethclient.Dial(chainBWSURI) gomega.Expect(err).Should(gomega.BeNil()) + + // chainBIDInt, err = chainBWSClient.ChainID(context.Background()) + // gomega.Expect(err).Should(gomega.BeNil()) }) ginkgo.It("Set up relayer config", ginkgo.Label("Relayer", "Setup Relayer"), func() { @@ -318,7 +324,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { }) gomega.Expect(err).Should(gomega.BeNil()) tx := types.NewTx(&types.DynamicFeeTx{ - ChainID: chainID, + ChainID: chainAIDInt, Nonce: startingNonce, To: &warp.Module.Address, Gas: 200_000, @@ -327,6 +333,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { Value: common.Big0, Data: packedInput, }) + txSigner := types.LatestSignerForChainID(chainAIDInt) signedTx, err := types.SignTx(tx, txSigner, fundedKey) gomega.Expect(err).Should(gomega.BeNil()) log.Info("Sending sendWarpMessage transaction", "destinationChainID", blockchainIDB, "txHash", signedTx.Hash()) From f15e704347d25b97108f9509cde3ebb54b66f0cb Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Fri, 1 Sep 2023 00:12:07 +0000 Subject: [PATCH 17/56] fix eth client declarations --- tests/e2e/e2e_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 1d971b68..67819916 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -137,6 +137,8 @@ var _ = ginkgo.BeforeSuite(func() { chainBIDInt, err := client.ChainID(ctx) gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Got chain ID int", "chainID", chainBIDInt.String()) + err = utils.IssueTxsToActivateProposerVMFork(ctx, chainBIDInt, fundedKey, client) gomega.Expect(err).Should(gomega.BeNil()) }) @@ -194,15 +196,17 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { chainAWSURI := toWebsocketURI(chainAURIs[0], blockchainIDA.String()) log.Info("Creating ethclient for blockchainA", "wsURI", chainAWSURI) - _, err = ethclient.Dial(chainAWSURI) + chainAWSClient, err = ethclient.Dial(chainAWSURI) gomega.Expect(err).Should(gomega.BeNil()) chainAIDInt, err = chainAWSClient.ChainID(context.Background()) gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Got chain ID int", "chainID", chainAIDInt.String()) + chainBWSURI := toWebsocketURI(chainBURIs[0], blockchainIDB.String()) log.Info("Creating ethclient for blockchainB", "wsURI", chainBWSURI) - _, err = ethclient.Dial(chainBWSURI) + chainBWSClient, err = ethclient.Dial(chainBWSURI) gomega.Expect(err).Should(gomega.BeNil()) // chainBIDInt, err = chainBWSClient.ChainID(context.Background()) From dd9d68cf6ae7b9172c61a270868034d5777dfa96 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Fri, 1 Sep 2023 06:41:57 +0000 Subject: [PATCH 18/56] fix for relayer config chain ID, need to figure out relayer logs in parallel --- tests/e2e/e2e_test.go | 98 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 84 insertions(+), 14 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 67819916..aa8fa11f 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -11,6 +11,7 @@ import ( "strconv" "strings" "testing" + "time" "github.com/ava-labs/avalanche-network-runner/rpcpb" "github.com/ava-labs/avalanchego/ids" @@ -50,6 +51,7 @@ var ( Receipts: []teleporter.TeleporterMessageReceipt{}, Message: []byte{1, 2, 3, 4}, } + out = []byte{} ) func TestE2E(t *testing.T) { @@ -68,6 +70,10 @@ func toWebsocketURI(uri string, blockchainID string) string { return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) } +func toRPCURI(uri string, blockchainID string) string { + return fmt.Sprintf("http://%s/ext/bc/%s/rpc", strings.TrimPrefix(uri, "http://"), blockchainID) +} + // BeforeSuite builds the awm-relayer binary, starts the default network and adds 10 new nodes as validators with BLS keys // registered on the P-Chain. // Adds two disjoint sets of 5 of the new validator nodes to validate two new subnets with a @@ -149,11 +155,14 @@ var _ = ginkgo.AfterSuite(func() { gomega.Expect(manager.TeardownNetwork()).Should(gomega.BeNil()) gomega.Expect(os.Remove(warpChainConfigPath)).Should(gomega.BeNil()) gomega.Expect(os.Remove(relayerConfigPath)).Should(gomega.BeNil()) + fmt.Println(string(out)) + log.Info("Relayer finished") }) var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { log.Info("Got to ginkgo describe") var ( + subnetIDs []ids.ID subnetA, subnetB ids.ID blockchainIDA, blockchainIDB ids.ID chainAURIs, chainBURIs []string @@ -175,7 +184,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { fundedAddress = crypto.PubkeyToAddress(fundedKey.PublicKey) ginkgo.It("Setup subnet URIs", ginkgo.Label("Relayer", "SetupWarp"), func() { - subnetIDs := manager.GetSubnets() + subnetIDs = manager.GetSubnets() gomega.Expect(len(subnetIDs)).Should(gomega.Equal(2)) subnetA = subnetIDs[0] @@ -214,19 +223,25 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { }) ginkgo.It("Set up relayer config", ginkgo.Label("Relayer", "Setup Relayer"), func() { + log.Info("Starting values for chains", "chainA", blockchainIDA.String(), "chainB", blockchainIDB.String()) + log.Info("Starting values for subnet IDs", "subnetA", subnetA.String(), "subnetB", subnetB.String()) subnetADetails, ok := manager.GetSubnet(subnetA) gomega.Expect(ok).Should(gomega.BeTrue()) + blockchainIDA = subnetADetails.BlockchainID + subnetA = subnetIDs[0] hostA, portA, err := getURIHostAndPort(subnetADetails.ValidatorURIs[0]) gomega.Expect(err).Should(gomega.BeNil()) subnetBDetails, ok := manager.GetSubnet(subnetB) gomega.Expect(ok).Should(gomega.BeTrue()) + blockchainIDB = subnetBDetails.BlockchainID + subnetB = subnetIDs[1] hostB, portB, err := getURIHostAndPort(subnetBDetails.ValidatorURIs[0]) gomega.Expect(err).Should(gomega.BeNil()) - log.Info("Setting up relayer config", "hostA", hostA, "portA", portA, "blockChainA", blockchainIDA, "hostB", hostB, "portB", portB, "blockChainB", blockchainIDB) + log.Info("Setting up relayer config", "hostA", hostA, "portA", portA, "blockChainA", blockchainIDA.String(), "hostB", hostB, "portB", portB, "blockChainB", blockchainIDB.String(), "subnetA", subnetA.String(), "subnetB", subnetB.String()) relayerConfig := config.Config{ LogLevel: logging.Info.LowerString(), @@ -278,24 +293,71 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { log.Info("Created awm-relayer config", "configPath", relayerConfigPath, "config", string(data)) }) - ginkgo.It("Build + Run Relayer", ginkgo.Label("Relayer", "Run Relayer"), func() { - // Build the awm-relayer binary - cmd := exec.Command("./scripts/build.sh") - out, err := cmd.CombinedOutput() - fmt.Println(string(out)) + ginkgo.It("RPC endpoints", ginkgo.Label("Relayer", "RPC Endpoints"), func() { + // Check that the RPC endpoints are available + chainARPCURI := toRPCURI(chainAURIs[0], blockchainIDA.String()) + log.Info("Creating ethclient for blockchainA", "rpcURI", chainARPCURI) + chainARPCClient, err := ethclient.Dial(chainARPCURI) + gomega.Expect(err).Should(gomega.BeNil()) + + chainBRPCURI := toRPCURI(chainBURIs[0], blockchainIDB.String()) + log.Info("Creating ethclient for blockchainB", "rpcURI", chainBRPCURI) + chainBRPCClient, err := ethclient.Dial(chainBRPCURI) gomega.Expect(err).Should(gomega.BeNil()) - // Run awm relayer binary with config path - cmd = exec.Command("./build/awm-relayer", "--config-file", relayerConfigPath) - out, err = cmd.CombinedOutput() - fmt.Println(string(out)) + // Check that the RPC endpoints are available + chainIDA, err := chainARPCClient.ChainID(context.Background()) gomega.Expect(err).Should(gomega.BeNil()) - log.Info("Running relayer") + + chainIDB, err := chainBRPCClient.ChainID(context.Background()) + gomega.Expect(err).Should(gomega.BeNil()) + + log.Info("Got chain IDs", "chainIDA", chainIDA.String(), "chainIDB", chainIDB.String()) + + // Get nonce with rpc endpoints + nonce, err := chainARPCClient.NonceAt(context.Background(), fundedAddress, nil) + gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Got nonce from chainA", "nonce", nonce) + + nonce, err = chainBRPCClient.NonceAt(context.Background(), fundedAddress, nil) + gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Got nonce from chainB", "nonce", nonce) }) + // ginkgo.It("Build + Run Relayer", ginkgo.Label("Relayer", "Run Relayer"), func() { + // // Build the awm-relayer binary + // cmd := exec.Command("./scripts/build.sh") + // out, err := cmd.CombinedOutput() + // fmt.Println(string(out)) + // gomega.Expect(err).Should(gomega.BeNil()) + + // // Run awm relayer binary with config path + // cmd = exec.Command("./build/awm-relayer", "--config-file", relayerConfigPath) + // out, err = cmd.CombinedOutput() + // fmt.Println(string(out)) + // gomega.Expect(err).Should(gomega.BeNil()) + // log.Info("Running relayer") + // }) // Send a transaction to Subnet A to issue a Warp Message to Subnet B ginkgo.It("Send Message from A to B", ginkgo.Label("Warp", "SendWarp"), func() { ctx := context.Background() + go func() { + // Build the awm-relayer binary + log.Info("Build and running relayer in goroutine") + cmd := exec.Command("./scripts/build.sh") + out, err = cmd.CombinedOutput() + fmt.Println(string(out)) + gomega.Expect(err).Should(gomega.BeNil()) + + // Run awm relayer binary with config path + cmd = exec.Command("./build/awm-relayer", "--config-file", relayerConfigPath) + err = cmd.Start() + defer func() { + fmt.Println(string(out)) + gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Relayer finished") + }() + }() gomega.Expect(err).Should(gomega.BeNil()) @@ -345,8 +407,16 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) log.Info("Waiting for new block confirmation") - newHead := <-newHeadsB - blockHash := newHead.Hash() + ticker := time.NewTimer(15 * time.Second) + var blockHash common.Hash + select { + case newHead := <-newHeadsB: + log.Info("Received new head", "height", newHead.Number.Uint64()) + blockHash = newHead.Hash() + case <-ticker.C: + log.Info("Timed out waiting for new block") + os.Exit(1) + } log.Info("Fetching relevant warp logs from the newly produced block") logs, err := chainBWSClient.FilterLogs(ctx, interfaces.FilterQuery{ From dffd4dd15279af97feb0caa4c606b9b2405db626 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Fri, 1 Sep 2023 07:27:52 +0000 Subject: [PATCH 19/56] relays to destination chain but block has no warp message log --- tests/e2e/e2e_test.go | 63 ++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index aa8fa11f..648d0b18 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -1,6 +1,7 @@ package tests import ( + "bufio" "context" "crypto/ecdsa" "encoding/json" @@ -182,6 +183,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { panic(err) } fundedAddress = crypto.PubkeyToAddress(fundedKey.PublicKey) + teleporterContractAddress = fundedAddress ginkgo.It("Setup subnet URIs", ginkgo.Label("Relayer", "SetupWarp"), func() { subnetIDs = manager.GetSubnets() @@ -341,26 +343,38 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { // Send a transaction to Subnet A to issue a Warp Message to Subnet B ginkgo.It("Send Message from A to B", ginkgo.Label("Warp", "SendWarp"), func() { ctx := context.Background() + // Build the awm-relayer binary + log.Info("Build and running relayer in goroutine") + cmd := exec.Command("./scripts/build.sh") + out, err = cmd.CombinedOutput() + fmt.Println(string(out)) + gomega.Expect(err).Should(gomega.BeNil()) + + // Create a channel to communicate with the goroutine + cmdOutput := make(chan string) + + // Run awm relayer binary with config path + cmd = exec.Command("./build/awm-relayer", "--config-file", relayerConfigPath) + + // Set up a pipe to capture the command's output + cmdReader, _ := cmd.StdoutPipe() + + // Start the command + err := cmd.Start() + gomega.Expect(err).Should(gomega.BeNil()) + + // Start a goroutine to read and output the command's stdout go func() { - // Build the awm-relayer binary - log.Info("Build and running relayer in goroutine") - cmd := exec.Command("./scripts/build.sh") - out, err = cmd.CombinedOutput() - fmt.Println(string(out)) - gomega.Expect(err).Should(gomega.BeNil()) - - // Run awm relayer binary with config path - cmd = exec.Command("./build/awm-relayer", "--config-file", relayerConfigPath) - err = cmd.Start() - defer func() { - fmt.Println(string(out)) - gomega.Expect(err).Should(gomega.BeNil()) - log.Info("Relayer finished") - }() + scanner := bufio.NewScanner(cmdReader) + for scanner.Scan() { + log.Info(scanner.Text()) + } + cmdOutput <- "Command execution finished" }() gomega.Expect(err).Should(gomega.BeNil()) + time.Sleep(30 * time.Second) log.Info("Subscribing to new heads") // newHeadsA := make(chan *types.Header, 10) // sub, err := chainAWSClient.SubscribeNewHead(ctx, newHeadsA) @@ -407,16 +421,10 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) log.Info("Waiting for new block confirmation") - ticker := time.NewTimer(15 * time.Second) var blockHash common.Hash - select { - case newHead := <-newHeadsB: - log.Info("Received new head", "height", newHead.Number.Uint64()) - blockHash = newHead.Hash() - case <-ticker.C: - log.Info("Timed out waiting for new block") - os.Exit(1) - } + newHead := <-newHeadsB + log.Info("Received new head", "height", newHead.Number.Uint64()) + blockHash = newHead.Hash() log.Info("Fetching relevant warp logs from the newly produced block") logs, err := chainBWSClient.FilterLogs(ctx, interfaces.FilterQuery{ @@ -457,6 +465,13 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { // } // } // } + // Wait for the command to finish (if needed) + err = cmd.Wait() + gomega.Expect(err).Should(gomega.BeNil()) + + // You can also check the command's output status + result := <-cmdOutput + log.Info(result) }) }) From 8ec2183a13bee82260abf189f9ee63e276dd1372 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Fri, 1 Sep 2023 20:16:31 +0000 Subject: [PATCH 20/56] draft working e2e test --- .gitignore | 5 +- messages/teleporter/message.go | 2 +- messages/teleporter/message_manager.go | 4 +- messages/teleporter/message_test.go | 2 +- tests/e2e/e2e_test.go | 117 +++++++++++++------------ vms/evm/destination_client.go | 34 +++---- 6 files changed, 80 insertions(+), 84 deletions(-) diff --git a/.gitignore b/.gitignore index e33a2c17..bb56d130 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build/ __debug_bin -.vscode* \ No newline at end of file +.vscode* + +# Ginkgo test binaries +*.test diff --git a/messages/teleporter/message.go b/messages/teleporter/message.go index 0d467bef..da8755f5 100644 --- a/messages/teleporter/message.go +++ b/messages/teleporter/message.go @@ -35,7 +35,7 @@ type ReceiveCrossChainMessageInput struct { } // unpack Teleporter message bytes according to EVM ABI encoding rules -func unpackTeleporterMessage(messageBytes []byte) (*TeleporterMessage, error) { +func UnpackTeleporterMessage(messageBytes []byte) (*TeleporterMessage, error) { args := abi.Arguments{ { Name: "teleporterMessage", diff --git a/messages/teleporter/message_manager.go b/messages/teleporter/message_manager.go index e7cca282..a0a70da3 100644 --- a/messages/teleporter/message_manager.go +++ b/messages/teleporter/message_manager.go @@ -73,7 +73,7 @@ func NewMessageManager( // ShouldSendMessage returns true if the message should be sent to the destination chain func (m *messageManager) ShouldSendMessage(warpMessageInfo *vmtypes.WarpMessageInfo, destinationChainID ids.ID) (bool, error) { // Unpack the teleporter message and add it to the cache - teleporterMessage, err := unpackTeleporterMessage(warpMessageInfo.WarpPayload) + teleporterMessage, err := UnpackTeleporterMessage(warpMessageInfo.WarpPayload) if err != nil { m.logger.Error( "Failed unpacking teleporter message.", @@ -113,7 +113,7 @@ func (m *messageManager) SendMessage(signedMessage *warp.Message, parsedVmPayloa zap.String("warpMessageID", signedMessage.ID().String()), ) var err error - teleporterMessage, err = unpackTeleporterMessage(parsedVmPayload) + teleporterMessage, err = UnpackTeleporterMessage(parsedVmPayload) if err != nil { m.logger.Error( "Failed unpacking teleporter message.", diff --git a/messages/teleporter/message_test.go b/messages/teleporter/message_test.go index e71e6772..38abf1fc 100644 --- a/messages/teleporter/message_test.go +++ b/messages/teleporter/message_test.go @@ -42,7 +42,7 @@ func TestPackUnpackTeleporterMessage(t *testing.T) { t.FailNow() } - unpacked, err := unpackTeleporterMessage(b) + unpacked, err := UnpackTeleporterMessage(b) if err != nil { t.Errorf("failed to unpack teleporter message: %v", err) t.FailNow() diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 648d0b18..42f45001 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -22,11 +22,12 @@ import ( "github.com/ava-labs/awm-relayer/messages/teleporter" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/ethclient" - "github.com/ava-labs/subnet-evm/interfaces" "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/plugin/evm" "github.com/ava-labs/subnet-evm/tests/utils" "github.com/ava-labs/subnet-evm/tests/utils/runner" + predicateutils "github.com/ava-labs/subnet-evm/utils/predicate" + warpPayload "github.com/ava-labs/subnet-evm/warp/payload" "github.com/ava-labs/subnet-evm/x/warp" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -163,16 +164,14 @@ var _ = ginkgo.AfterSuite(func() { var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { log.Info("Got to ginkgo describe") var ( - subnetIDs []ids.ID - subnetA, subnetB ids.ID - blockchainIDA, blockchainIDB ids.ID - chainAURIs, chainBURIs []string - fundedKey *ecdsa.PrivateKey - fundedAddress common.Address - err error - unsignedWarpMsg *avalancheWarp.UnsignedMessage - unsignedWarpMessageID ids.ID - // signedWarpMsg *avalancheWarp.Message + subnetIDs []ids.ID + subnetA, subnetB ids.ID + blockchainIDA, blockchainIDB ids.ID + chainAURIs, chainBURIs []string + fundedKey *ecdsa.PrivateKey + fundedAddress common.Address + err error + receivedWarpMessage *avalancheWarp.Message chainAWSClient, chainBWSClient ethclient.Client chainAIDInt *big.Int payload = []byte{} @@ -354,7 +353,8 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { cmdOutput := make(chan string) // Run awm relayer binary with config path - cmd = exec.Command("./build/awm-relayer", "--config-file", relayerConfigPath) + relayerContext, relayerCancel := context.WithCancel(ctx) + cmd = exec.CommandContext(relayerContext, "./build/awm-relayer", "--config-file", relayerConfigPath) // Set up a pipe to capture the command's output cmdReader, _ := cmd.StdoutPipe() @@ -374,7 +374,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) - time.Sleep(30 * time.Second) + time.Sleep(15 * time.Second) log.Info("Subscribing to new heads") // newHeadsA := make(chan *types.Header, 10) // sub, err := chainAWSClient.SubscribeNewHead(ctx, newHeadsA) @@ -426,52 +426,53 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { log.Info("Received new head", "height", newHead.Number.Uint64()) blockHash = newHead.Hash() - log.Info("Fetching relevant warp logs from the newly produced block") - logs, err := chainBWSClient.FilterLogs(ctx, interfaces.FilterQuery{ - BlockHash: &blockHash, - Addresses: []common.Address{warp.Module.Address}, - }) + block, err := chainBWSClient.BlockByHash(ctx, blockHash) + gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Got block", "blockHash", blockHash, "blockNumber", block.NumberU64(), "transactions", block.Transactions(), "block", block) + accessLists := block.Transactions()[0].AccessList() + gomega.Expect(len(accessLists)).Should(gomega.Equal(1)) + gomega.Expect(accessLists[0].Address).Should(gomega.Equal(warp.Module.Address)) + + // Check the transaction storage key has warp message we're expecting + storageKeyHashes := accessLists[0].StorageKeys + packedPredicate := predicateutils.HashSliceToBytes(storageKeyHashes) + predicateBytes, err := predicateutils.UnpackPredicate(packedPredicate) + gomega.Expect(err).Should(gomega.BeNil()) + receivedWarpMessage, err = avalancheWarp.ParseMessage(predicateBytes) + gomega.Expect(err).Should(gomega.BeNil()) + + // Check that the transaction is no longer pending + txHash := block.Transactions()[0].Hash() + _, isPending, err := chainBWSClient.TransactionByHash(ctx, txHash) + gomega.Expect(err).Should(gomega.BeNil()) + gomega.Expect(isPending).Should(gomega.BeFalse()) + + receipt, err := chainBWSClient.TransactionReceipt(ctx, txHash) + gomega.Expect(err).Should(gomega.BeNil()) + gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + + log.Info("Finished sending warp message, closing down output channel") + + // Cancel the command and stop the relayer + relayerCancel() + _ = cmd.Wait() + }) + + ginkgo.It("Verify Warp Message", ginkgo.Label("Relay", "VerifyWarp"), func() { + gomega.Expect(receivedWarpMessage.SourceChainID).Should(gomega.Equal(blockchainIDA)) + addressedPayload, err := warpPayload.ParseAddressedPayload(receivedWarpMessage.Payload) + gomega.Expect(err).Should(gomega.BeNil()) + + receivedDestinationID, err := ids.ToID(addressedPayload.DestinationChainID.Bytes()) + gomega.Expect(err).Should(gomega.BeNil()) + gomega.Expect(receivedDestinationID).Should(gomega.Equal(blockchainIDB)) + gomega.Expect(addressedPayload.DestinationAddress).Should(gomega.Equal(teleporterContractAddress)) + gomega.Expect(addressedPayload.Payload).Should(gomega.Equal(payload)) + + // Check that the teleporter message is correct + receivedTeleporterMessage, err := teleporter.UnpackTeleporterMessage(addressedPayload.Payload) gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(len(logs)).Should(gomega.Equal(1)) - - // Check for relevant warp log from subscription and ensure that it matches - // the log extracted from the last block. - txLog := logs[0] - log.Info("Parsing logData as unsigned warp message") - unsignedMsg, err := avalancheWarp.ParseUnsignedMessage(txLog.Data) - gomega.Expect(err).Should(gomega.BeNil()) - - // Set local variables for the duration of the test - unsignedWarpMessageID = unsignedMsg.ID() - unsignedWarpMsg = unsignedMsg - log.Info("Parsed unsignedWarpMsg", "unsignedWarpMessageID", unsignedWarpMessageID, "unsignedWarpMessage", unsignedWarpMsg) - - // Loop over each client on chain A to ensure they all have time to accept the block. - // Note: if we did not confirm this here, the next stage could be racy since it assumes every node - // has accepted the block. - // for i, uri := range chainAURIs { - // chainAWSURI := toWebsocketURI(uri, blockchainIDA.String()) - // log.Info("Creating ethclient for blockchainA", "wsURI", chainAWSURI) - // client, err := ethclient.Dial(chainAWSURI) - // gomega.Expect(err).Should(gomega.BeNil()) - - // // Loop until each node has advanced to >= the height of the block that emitted the warp log - // for { - // block, err := client.BlockByNumber(ctx, nil) - // gomega.Expect(err).Should(gomega.BeNil()) - // if block.NumberU64() >= newHead.Number.Uint64() { - // log.Info("client accepted the block containing SendWarpMessage", "client", i, "height", block.NumberU64()) - // break - // } - // } - // } - // Wait for the command to finish (if needed) - err = cmd.Wait() - gomega.Expect(err).Should(gomega.BeNil()) - - // You can also check the command's output status - result := <-cmdOutput - log.Info(result) + gomega.Expect(*receivedTeleporterMessage).Should(gomega.Equal(teleporterMessage)) }) }) diff --git a/vms/evm/destination_client.go b/vms/evm/destination_client.go index 02e3dda1..fc48121b 100644 --- a/vms/evm/destination_client.go +++ b/vms/evm/destination_client.go @@ -137,32 +137,24 @@ func (tdc *destinationClient) SendTx(signedMessage *avalancheWarp.Message, return err } - // Pack the signed message to be delivered in the storage slots. - // The predicate bytes are packed with a delimiter of 0xff. - predicateBytes := predicateutils.PackPredicate(signedMessage.Bytes()) - to := common.HexToAddress(toAddress) - gasFeeCap := baseFee.Mul(baseFee, big.NewInt(BaseFeeFactor)) gasFeeCap.Add(gasFeeCap, big.NewInt(MaxPriorityFeePerGas)) // Construct the actual transaction to broadcast on the destination chain - tx := types.NewTx(&types.DynamicFeeTx{ - ChainID: destinationChainIDBigInt, - Nonce: tdc.currentNonce, - To: &to, - Gas: gasLimit, - GasFeeCap: gasFeeCap, - GasTipCap: gasTipCap, - Value: big.NewInt(0), - Data: callData, - AccessList: types.AccessList{ - { - Address: warp.ContractAddress, - StorageKeys: predicateutils.BytesToHashSlice(predicateBytes), - }, - }, - }) + tx := predicateutils.NewPredicateTx( + destinationChainIDBigInt, + tdc.currentNonce, + &to, + gasLimit, + gasFeeCap, + gasTipCap, + big.NewInt(0), + callData, + types.AccessList{}, + warp.ContractAddress, + signedMessage.Bytes(), + ) // Sign and send the transaction on the destination chain signer := types.LatestSignerForChainID(destinationChainIDBigInt) From 00cf1be2c424edf8404ad02a096042b3d2c121df Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Fri, 1 Sep 2023 20:23:41 +0000 Subject: [PATCH 21/56] clean up logs and commented test code --- tests/e2e/e2e_test.go | 32 ++++++++------------------------ vms/destination_client.go | 2 ++ vms/evm/destination_client.go | 3 --- 3 files changed, 10 insertions(+), 27 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 42f45001..e5a848f8 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -325,36 +325,24 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { log.Info("Got nonce from chainB", "nonce", nonce) }) - // ginkgo.It("Build + Run Relayer", ginkgo.Label("Relayer", "Run Relayer"), func() { - // // Build the awm-relayer binary - // cmd := exec.Command("./scripts/build.sh") - // out, err := cmd.CombinedOutput() - // fmt.Println(string(out)) - // gomega.Expect(err).Should(gomega.BeNil()) - - // // Run awm relayer binary with config path - // cmd = exec.Command("./build/awm-relayer", "--config-file", relayerConfigPath) - // out, err = cmd.CombinedOutput() - // fmt.Println(string(out)) - // gomega.Expect(err).Should(gomega.BeNil()) - // log.Info("Running relayer") - // }) - // Send a transaction to Subnet A to issue a Warp Message to Subnet B - ginkgo.It("Send Message from A to B", ginkgo.Label("Warp", "SendWarp"), func() { - ctx := context.Background() + ginkgo.It("Build Relayer", ginkgo.Label("Relayer", "Build Relayer"), func() { // Build the awm-relayer binary - log.Info("Build and running relayer in goroutine") cmd := exec.Command("./scripts/build.sh") - out, err = cmd.CombinedOutput() + out, err := cmd.CombinedOutput() fmt.Println(string(out)) gomega.Expect(err).Should(gomega.BeNil()) + }) + + // Send a transaction to Subnet A to issue a Warp Message to Subnet B + ginkgo.It("Send Message from A to B", ginkgo.Label("Warp", "SendWarp"), func() { + ctx := context.Background() // Create a channel to communicate with the goroutine cmdOutput := make(chan string) // Run awm relayer binary with config path relayerContext, relayerCancel := context.WithCancel(ctx) - cmd = exec.CommandContext(relayerContext, "./build/awm-relayer", "--config-file", relayerConfigPath) + cmd := exec.CommandContext(relayerContext, "./build/awm-relayer", "--config-file", relayerConfigPath) // Set up a pipe to capture the command's output cmdReader, _ := cmd.StdoutPipe() @@ -376,10 +364,6 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { time.Sleep(15 * time.Second) log.Info("Subscribing to new heads") - // newHeadsA := make(chan *types.Header, 10) - // sub, err := chainAWSClient.SubscribeNewHead(ctx, newHeadsA) - // gomega.Expect(err).Should(gomega.BeNil()) - // defer sub.Unsubscribe() newHeadsB := make(chan *types.Header, 10) sub, err := chainBWSClient.SubscribeNewHead(ctx, newHeadsB) diff --git a/vms/destination_client.go b/vms/destination_client.go index cec3b06b..beb961aa 100644 --- a/vms/destination_client.go +++ b/vms/destination_client.go @@ -43,6 +43,7 @@ func CreateDestinationClients(logger logging.Logger, relayerConfig config.Config if err != nil { logger.Error( "Failed to decode base-58 encoded source chain ID", + zap.String("chainID", chainID.String()), zap.Error(err), ) return nil, err @@ -59,6 +60,7 @@ func CreateDestinationClients(logger logging.Logger, relayerConfig config.Config if err != nil { logger.Error( "Could not create destination client", + zap.String("chainID", chainID.String()), zap.Error(err), ) return nil, err diff --git a/vms/evm/destination_client.go b/vms/evm/destination_client.go index fc48121b..84e3058b 100644 --- a/vms/evm/destination_client.go +++ b/vms/evm/destination_client.go @@ -79,9 +79,6 @@ func NewDestinationClient(logger logging.Logger, subnetInfo config.DestinationSu if err != nil { logger.Error( "Failed to get nonce", - zap.String("eoa", eoa.String()), - zap.String("chainID", destinationID.String()), - zap.String("rpcEndpoint", subnetInfo.GetNodeRPCEndpoint()), zap.Error(err), ) return nil, err From 630df61833db8adec6b87fb55d1beb01992e6095 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Fri, 1 Sep 2023 20:44:11 +0000 Subject: [PATCH 22/56] fixing blockchainB overwrite and clean up scripts --- .gitignore | 4 +++- scripts/e2e_test.sh | 2 -- tests/e2e/e2e_test.go | 36 ++++++++---------------------------- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/.gitignore b/.gitignore index bb56d130..09f209b2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,7 @@ __debug_bin .vscode* -# Ginkgo test binaries +# Ginkgo test outputs +main.log +server.log *.test diff --git a/scripts/e2e_test.sh b/scripts/e2e_test.sh index 00300c31..4649e256 100755 --- a/scripts/e2e_test.sh +++ b/scripts/e2e_test.sh @@ -10,8 +10,6 @@ source "$AWM_RELAYER_PATH"/scripts/constants.sh source "$AWM_RELAYER_PATH"/scripts/versions.sh -RUN_E2E=true - # Build ginkgo # to install the ginkgo binary (required for test build and run) go install -v github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION} diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index e5a848f8..647e1d3f 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -53,19 +53,15 @@ var ( Receipts: []teleporter.TeleporterMessageReceipt{}, Message: []byte{1, 2, 3, 4}, } - out = []byte{} ) func TestE2E(t *testing.T) { - log.Info("RUN_E2E value is", "value", os.Getenv("RUN_E2E")) if os.Getenv("RUN_E2E") == "" { t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") } gomega.RegisterFailHandler(ginkgo.Fail) ginkgo.RunSpecs(t, "Relayer e2e test") - - log.Info("Ran ginkgo specs") } func toWebsocketURI(uri string, blockchainID string) string { @@ -81,7 +77,6 @@ func toRPCURI(uri string, blockchainID string) string { // Adds two disjoint sets of 5 of the new validator nodes to validate two new subnets with a // a single Subnet-EVM blockchain. var _ = ginkgo.BeforeSuite(func() { - log.Info("Got to ginkgo before suite") ctx := context.Background() var err error @@ -145,24 +140,21 @@ var _ = ginkgo.BeforeSuite(func() { chainBIDInt, err := client.ChainID(ctx) gomega.Expect(err).Should(gomega.BeNil()) - log.Info("Got chain ID int", "chainID", chainBIDInt.String()) - err = utils.IssueTxsToActivateProposerVMFork(ctx, chainBIDInt, fundedKey, client) gomega.Expect(err).Should(gomega.BeNil()) + + log.Info("Set up ginkgo before suite") }) var _ = ginkgo.AfterSuite(func() { - log.Info("Got to ginkgo after suite") + log.Info("Running ginkgo after suite") gomega.Expect(manager).ShouldNot(gomega.BeNil()) gomega.Expect(manager.TeardownNetwork()).Should(gomega.BeNil()) gomega.Expect(os.Remove(warpChainConfigPath)).Should(gomega.BeNil()) gomega.Expect(os.Remove(relayerConfigPath)).Should(gomega.BeNil()) - fmt.Println(string(out)) - log.Info("Relayer finished") }) var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { - log.Info("Got to ginkgo describe") var ( subnetIDs []ids.ID subnetA, subnetB ids.ID @@ -198,7 +190,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { subnetB = subnetIDs[1] subnetBDetails, ok := manager.GetSubnet(subnetB) gomega.Expect(ok).Should(gomega.BeTrue()) - blockchainIDB := subnetBDetails.BlockchainID + blockchainIDB = subnetBDetails.BlockchainID gomega.Expect(len(subnetBDetails.ValidatorURIs)).Should(gomega.Equal(5)) chainBURIs = append(chainBURIs, subnetBDetails.ValidatorURIs...) @@ -212,34 +204,22 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { chainAIDInt, err = chainAWSClient.ChainID(context.Background()) gomega.Expect(err).Should(gomega.BeNil()) - log.Info("Got chain ID int", "chainID", chainAIDInt.String()) - chainBWSURI := toWebsocketURI(chainBURIs[0], blockchainIDB.String()) log.Info("Creating ethclient for blockchainB", "wsURI", chainBWSURI) chainBWSClient, err = ethclient.Dial(chainBWSURI) gomega.Expect(err).Should(gomega.BeNil()) - // chainBIDInt, err = chainBWSClient.ChainID(context.Background()) - // gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Finished setting up warp", "chainA", blockchainIDA.String(), "chainB", blockchainIDB.String()) }) ginkgo.It("Set up relayer config", ginkgo.Label("Relayer", "Setup Relayer"), func() { log.Info("Starting values for chains", "chainA", blockchainIDA.String(), "chainB", blockchainIDB.String()) log.Info("Starting values for subnet IDs", "subnetA", subnetA.String(), "subnetB", subnetB.String()) - subnetADetails, ok := manager.GetSubnet(subnetA) - gomega.Expect(ok).Should(gomega.BeTrue()) - blockchainIDA = subnetADetails.BlockchainID - subnetA = subnetIDs[0] - hostA, portA, err := getURIHostAndPort(subnetADetails.ValidatorURIs[0]) + hostA, portA, err := getURIHostAndPort(chainAURIs[0]) gomega.Expect(err).Should(gomega.BeNil()) - subnetBDetails, ok := manager.GetSubnet(subnetB) - gomega.Expect(ok).Should(gomega.BeTrue()) - blockchainIDB = subnetBDetails.BlockchainID - subnetB = subnetIDs[1] - - hostB, portB, err := getURIHostAndPort(subnetBDetails.ValidatorURIs[0]) + hostB, portB, err := getURIHostAndPort(chainBURIs[0]) gomega.Expect(err).Should(gomega.BeNil()) log.Info("Setting up relayer config", "hostA", hostA, "portA", portA, "blockChainA", blockchainIDA.String(), "hostB", hostB, "portB", portB, "blockChainB", blockchainIDB.String(), "subnetA", subnetA.String(), "subnetB", subnetB.String()) @@ -247,7 +227,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { relayerConfig := config.Config{ LogLevel: logging.Info.LowerString(), NetworkID: 1337, - PChainAPIURL: subnetADetails.ValidatorURIs[0], + PChainAPIURL: chainAURIs[0], EncryptConnection: false, SourceSubnets: []config.SourceSubnet{ { From 56739c5434f28e2f775ae4928bfbd58f3a2b1d86 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Fri, 1 Sep 2023 20:53:01 +0000 Subject: [PATCH 23/56] copyrights and clean up workflow --- .github/workflows/test.yml | 3 --- scripts/e2e_test.sh | 3 +++ tests/e2e/e2e_test.go | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2a1f6bc9..ae88b5ee 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -52,16 +52,13 @@ jobs: go-version: "1.20.7" - name: Install AvalancheGo Release - shell: bash run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh - name: Build Subnet-EVM Plugin Binary - shell: bash run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy - name: Checkout awm-relayer repository uses: actions/checkout@v3 - name: Run E2E Tests - shell: bash run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh diff --git a/scripts/e2e_test.sh b/scripts/e2e_test.sh index 4649e256..fa38a0fd 100755 --- a/scripts/e2e_test.sh +++ b/scripts/e2e_test.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash +# Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +# See the file LICENSE for licensing terms. + set -e AWM_RELAYER_PATH=$( diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 647e1d3f..bb967fd2 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -1,3 +1,6 @@ +// Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + package tests import ( @@ -176,7 +179,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { fundedAddress = crypto.PubkeyToAddress(fundedKey.PublicKey) teleporterContractAddress = fundedAddress - ginkgo.It("Setup subnet URIs", ginkgo.Label("Relayer", "SetupWarp"), func() { + ginkgo.It("Setup subnet URIs", ginkgo.Label("Relayer", "Setup"), func() { subnetIDs = manager.GetSubnets() gomega.Expect(len(subnetIDs)).Should(gomega.Equal(2)) @@ -209,13 +212,10 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { chainBWSClient, err = ethclient.Dial(chainBWSURI) gomega.Expect(err).Should(gomega.BeNil()) - log.Info("Finished setting up warp", "chainA", blockchainIDA.String(), "chainB", blockchainIDB.String()) + log.Info("Finished setting up e2e test subnet variables") }) ginkgo.It("Set up relayer config", ginkgo.Label("Relayer", "Setup Relayer"), func() { - log.Info("Starting values for chains", "chainA", blockchainIDA.String(), "chainB", blockchainIDB.String()) - log.Info("Starting values for subnet IDs", "subnetA", subnetA.String(), "subnetB", subnetB.String()) - hostA, portA, err := getURIHostAndPort(chainAURIs[0]) gomega.Expect(err).Should(gomega.BeNil()) From c81ce8cff69051dea213f1d12fe60394920d8ad7 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Tue, 5 Sep 2023 20:23:17 +0000 Subject: [PATCH 24/56] use separate teleporter key for teleporter contract address --- tests/e2e/e2e_test.go | 45 ++++++++++--------------------------------- tests/e2e/warp.json | 3 +++ 2 files changed, 13 insertions(+), 35 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index bb967fd2..88ea9b3b 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -40,13 +40,14 @@ import ( ) const fundedKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" +const teleporterKeyStr = "d26c3344074df322e7c66ad0d2357d96f0d07d0f40038264d1d64d276709da41" var ( anrConfig = runner.NewDefaultANRConfig() manager = runner.NewNetworkManager(anrConfig) warpChainConfigPath string relayerConfigPath string - teleporterContractAddress = common.HexToAddress("27aE10273D17Cd7e80de8580A51f476960626e5f") + teleporterContractAddress = common.HexToAddress("1dD31B5351e76d51F4B152ce64fE5cf594694De5") teleporterMessage = teleporter.TeleporterMessage{ MessageID: big.NewInt(1), SenderAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), @@ -75,7 +76,7 @@ func toRPCURI(uri string, blockchainID string) string { return fmt.Sprintf("http://%s/ext/bc/%s/rpc", strings.TrimPrefix(uri, "http://"), blockchainID) } -// BeforeSuite builds the awm-relayer binary, starts the default network and adds 10 new nodes as validators with BLS keys +// BeforeSuite starts the default network and adds 10 new nodes as validators with BLS keys // registered on the P-Chain. // Adds two disjoint sets of 5 of the new validator nodes to validate two new subnets with a // a single Subnet-EVM blockchain. @@ -165,6 +166,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { chainAURIs, chainBURIs []string fundedKey *ecdsa.PrivateKey fundedAddress common.Address + teleporterKey *ecdsa.PrivateKey err error receivedWarpMessage *avalancheWarp.Message chainAWSClient, chainBWSClient ethclient.Client @@ -177,7 +179,11 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { panic(err) } fundedAddress = crypto.PubkeyToAddress(fundedKey.PublicKey) - teleporterContractAddress = fundedAddress + + teleporterKey, err = crypto.HexToECDSA(teleporterKeyStr) + if err != nil { + panic(err) + } ginkgo.It("Setup subnet URIs", ginkgo.Label("Relayer", "Setup"), func() { subnetIDs = manager.GetSubnets() @@ -274,37 +280,6 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { log.Info("Created awm-relayer config", "configPath", relayerConfigPath, "config", string(data)) }) - ginkgo.It("RPC endpoints", ginkgo.Label("Relayer", "RPC Endpoints"), func() { - // Check that the RPC endpoints are available - chainARPCURI := toRPCURI(chainAURIs[0], blockchainIDA.String()) - log.Info("Creating ethclient for blockchainA", "rpcURI", chainARPCURI) - chainARPCClient, err := ethclient.Dial(chainARPCURI) - gomega.Expect(err).Should(gomega.BeNil()) - - chainBRPCURI := toRPCURI(chainBURIs[0], blockchainIDB.String()) - log.Info("Creating ethclient for blockchainB", "rpcURI", chainBRPCURI) - chainBRPCClient, err := ethclient.Dial(chainBRPCURI) - gomega.Expect(err).Should(gomega.BeNil()) - - // Check that the RPC endpoints are available - chainIDA, err := chainARPCClient.ChainID(context.Background()) - gomega.Expect(err).Should(gomega.BeNil()) - - chainIDB, err := chainBRPCClient.ChainID(context.Background()) - gomega.Expect(err).Should(gomega.BeNil()) - - log.Info("Got chain IDs", "chainIDA", chainIDA.String(), "chainIDB", chainIDB.String()) - - // Get nonce with rpc endpoints - nonce, err := chainARPCClient.NonceAt(context.Background(), fundedAddress, nil) - gomega.Expect(err).Should(gomega.BeNil()) - log.Info("Got nonce from chainA", "nonce", nonce) - - nonce, err = chainBRPCClient.NonceAt(context.Background(), fundedAddress, nil) - gomega.Expect(err).Should(gomega.BeNil()) - log.Info("Got nonce from chainB", "nonce", nonce) - }) - ginkgo.It("Build Relayer", ginkgo.Label("Relayer", "Build Relayer"), func() { // Build the awm-relayer binary cmd := exec.Command("./scripts/build.sh") @@ -378,7 +353,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { Data: packedInput, }) txSigner := types.LatestSignerForChainID(chainAIDInt) - signedTx, err := types.SignTx(tx, txSigner, fundedKey) + signedTx, err := types.SignTx(tx, txSigner, teleporterKey) gomega.Expect(err).Should(gomega.BeNil()) log.Info("Sending sendWarpMessage transaction", "destinationChainID", blockchainIDB, "txHash", signedTx.Hash()) err = chainAWSClient.SendTransaction(ctx, signedTx) diff --git a/tests/e2e/warp.json b/tests/e2e/warp.json index 2c04535e..d6e45380 100644 --- a/tests/e2e/warp.json +++ b/tests/e2e/warp.json @@ -32,6 +32,9 @@ }, "0x0Fa8EA536Be85F32724D57A37758761B86416123": { "balance": "0x52B7D2DCC80CD2E4000000" + }, + "1dD31B5351e76d51F4B152ce64fE5cf594694De5": { + "balance": "0x52B7D2DCC80CD2E4000000" } }, "nonce": "0x0", From 30871f07bcaf6822b087b4638e9c16d5400ebf13 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Tue, 5 Sep 2023 20:33:11 +0000 Subject: [PATCH 25/56] pr cleanups and removing hardcoded teleporter string --- config/config_test.go | 2 +- tests/e2e/e2e_test.go | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/config/config_test.go b/config/config_test.go index 5c99b1d5..c9e8a23d 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -39,7 +39,7 @@ var ( EncryptConnection: false, MessageContracts: map[string]MessageProtocolConfig{ testAddress: { - MessageFormat: "teleporter", + MessageFormat: TELEPORTER.String(), }, }, }, diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 88ea9b3b..55a7ade2 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -245,7 +245,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { APINodePort: portA, MessageContracts: map[string]config.MessageProtocolConfig{ teleporterContractAddress.Hex(): { - MessageFormat: "teleporter", + MessageFormat: config.TELEPORTER.String(), Settings: map[string]interface{}{ "reward-address": fundedAddress.Hex(), }, @@ -266,7 +266,6 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { }, } - // relayerConfigPath := "./tests/e2e/relayer-config.json" data, err := json.MarshalIndent(relayerConfig, "", "\t") gomega.Expect(err).Should(gomega.BeNil()) @@ -288,7 +287,7 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) }) - // Send a transaction to Subnet A to issue a Warp Message to Subnet B + // Send a transaction to Subnet A to issue a Warp Message from the Teleporter contract to Subnet B ginkgo.It("Send Message from A to B", ginkgo.Label("Warp", "SendWarp"), func() { ctx := context.Background() @@ -325,13 +324,13 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) defer sub.Unsubscribe() - startingNonce, err := chainAWSClient.NonceAt(ctx, fundedAddress, nil) + nonceA, err := chainAWSClient.NonceAt(ctx, fundedAddress, nil) gomega.Expect(err).Should(gomega.BeNil()) - nonce, err := chainBWSClient.NonceAt(ctx, fundedAddress, nil) + nonceB, err := chainBWSClient.NonceAt(ctx, fundedAddress, nil) gomega.Expect(err).Should(gomega.BeNil()) - log.Info("Packing teleporter message", "nonceA", startingNonce, "nonceB", nonce) + log.Info("Packing teleporter message", "nonceA", nonceA, "nonceB", nonceB) payload, err = teleporter.PackTeleporterMessage(common.Hash(blockchainIDB), teleporterMessage) gomega.Expect(err).Should(gomega.BeNil()) @@ -342,9 +341,11 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { Payload: payload, }) gomega.Expect(err).Should(gomega.BeNil()) + + // Send a transaction that simulates the Teleporter contract calling sendWarpMessage with a Teleporter message payload tx := types.NewTx(&types.DynamicFeeTx{ ChainID: chainAIDInt, - Nonce: startingNonce, + Nonce: nonceA, To: &warp.Module.Address, Gas: 200_000, GasFeeCap: big.NewInt(225 * params.GWei), From cc775c28635218f2bd94501a3d5655fee7ba1000 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Tue, 5 Sep 2023 20:48:12 +0000 Subject: [PATCH 26/56] readme update with testing --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 5e2536b4..c18fd382 100644 --- a/README.md +++ b/README.md @@ -37,3 +37,31 @@ The relayer consists of the following components:
+ +## Testing + +--- + +### Unit tests + +Unit tests can be ran locally by running the command in root of the project: + +``` +go test ./... +``` + +### E2E tests + +E2E tests are ran as part of CI, but can also be ran locally. To run the E2E tests locally, you need to have the `avalanchego` build path and vm binary set up. For example with [subnet-evm](https://github.com/ava-labs/subnet-evm): + +``` +cd +BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh +./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +``` + +Then, in the root of the `awm-relayer` project, run: + +``` +AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh +``` \ No newline at end of file From 14057b74670ce09c24381698a2aa5b41dab7c8d5 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Wed, 6 Sep 2023 21:20:52 +0000 Subject: [PATCH 27/56] moves tests under tests directory and cleaning up for pr --- .github/workflows/test.yml | 98 ++++++++++++++++++++----------------- README.md | 10 ++-- scripts/e2e_test.sh | 13 ++--- scripts/versions.sh | 6 +-- tests/e2e/warp.json | 50 ------------------- tests/{e2e => }/e2e_test.go | 50 +++++-------------- tests/utils.go | 40 +++++++++++++++ tests/warp-genesis.json | 50 +++++++++++++++++++ 8 files changed, 169 insertions(+), 148 deletions(-) delete mode 100644 tests/e2e/warp.json rename tests/{e2e => }/e2e_test.go (92%) create mode 100644 tests/utils.go create mode 100644 tests/warp-genesis.json diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8104e8ca..d81e37eb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,64 +1,70 @@ # Copyright (C) 2023, Ava Labs, Inc. All rights reserved. # See the file LICENSE for licensing terms. -name: Relayer Tests +name: Tests on: - push: - branches: - - "*" + push: + branches: + - main + pull_request: + branches: + - "*" + +env: + GO_VERSION: "1.20.7" jobs: - build-test-relayer: - name: Build + Unit tests - runs-on: ubuntu-20.04 + build-test-relayer: + name: Build + Unit tests + runs-on: ubuntu-20.04 - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - path: awm-relayer + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + path: awm-relayer - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: "1.20.7" + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: $GO_VERSION - - name: Build Relayer - run: | - cd awm-relayer - go mod tidy - ./scripts/build.sh + - name: Build Relayer + run: | + cd awm-relayer + go mod tidy + ./scripts/build.sh - - name: Run Relayer Unit Tests - run: | - cd awm-relayer - ./scripts/test.sh + - name: Run Relayer Unit Tests + run: | + cd awm-relayer + ./scripts/test.sh - e2e_tests: - runs-on: ubuntu-20.04 - name: e2e_tests + e2e_tests: + runs-on: ubuntu-20.04 + name: e2e_tests - steps: - - name: Checkout subnet-evm repository - uses: actions/checkout@v3 - with: - repository: ava-labs/subnet-evm - ref: v0.5.4 + steps: + - name: Checkout subnet-evm repository + uses: actions/checkout@v4 + with: + repository: ava-labs/subnet-evm + ref: v0.5.4 - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: "1.20.7" + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: $GO_VERSION - - name: Install AvalancheGo Release - run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh + - name: Install AvalancheGo Release + run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh - - name: Build Subnet-EVM Plugin Binary - run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy + - name: Build Subnet-EVM Plugin Binary + run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy - - name: Checkout awm-relayer repository - uses: actions/checkout@v3 + - name: Checkout awm-relayer repository + uses: actions/checkout@v3 - - name: Run E2E Tests - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh + - name: Run E2E Tests + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh diff --git a/README.md b/README.md index c18fd382..be7e52d5 100644 --- a/README.md +++ b/README.md @@ -46,22 +46,22 @@ The relayer consists of the following components: Unit tests can be ran locally by running the command in root of the project: -``` -go test ./... +```bash +./scripts/test.sh ``` ### E2E tests E2E tests are ran as part of CI, but can also be ran locally. To run the E2E tests locally, you need to have the `avalanchego` build path and vm binary set up. For example with [subnet-evm](https://github.com/ava-labs/subnet-evm): -``` -cd +```bash +cd subnet-evm BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy ``` Then, in the root of the `awm-relayer` project, run: -``` +```bash AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh ``` \ No newline at end of file diff --git a/scripts/e2e_test.sh b/scripts/e2e_test.sh index fa38a0fd..a235a3ee 100755 --- a/scripts/e2e_test.sh +++ b/scripts/e2e_test.sh @@ -4,25 +4,26 @@ set -e -AWM_RELAYER_PATH=$( +RELAYER_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" cd .. && pwd ) -source "$AWM_RELAYER_PATH"/scripts/constants.sh +source "$RELAYER_PATH"/scripts/constants.sh -source "$AWM_RELAYER_PATH"/scripts/versions.sh +source "$RELAYER_PATH"/scripts/versions.sh # Build ginkgo # to install the ginkgo binary (required for test build and run) go install -v github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION} -ACK_GINKGO_RC=true ginkgo build ./tests/e2e +ginkgo build ./tests/ # Run the tests echo "Running e2e tests $RUN_E2E" -RUN_E2E=true ./tests/e2e/e2e.test \ +RUN_E2E=true ./tests/tests.test \ --ginkgo.vv \ --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} - echo "e2e tests passed" \ No newline at end of file +echo "e2e tests passed" +exit 0 \ No newline at end of file diff --git a/scripts/versions.sh b/scripts/versions.sh index 10fa37e8..30f63c90 100755 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -3,8 +3,8 @@ # See the file LICENSE for licensing terms. # Set up the versions to be used -awm_relayer_version=${AWM_RELAYER_VERSION:-'v0.0.1'} -subnet_evm_version=${SUBNET_EVM_VERSION:-'v0.5.2-warp-rc.0'} +awm_relayer_version=${AWM_RELAYER_VERSION:-'v0.2.1'} +subnet_evm_version=${SUBNET_EVM_VERSION:-'v0.5.4'} # Don't export them as they're used in the context of other calls -avalanche_version=${AVALANCHE_VERSION:-'v1.10.2'} +avalanche_version=${AVALANCHE_VERSION:-'v1.10.9'} GINKGO_VERSION=${GINKGO_VERSION:-'v2.2.0'} diff --git a/tests/e2e/warp.json b/tests/e2e/warp.json deleted file mode 100644 index d6e45380..00000000 --- a/tests/e2e/warp.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "config": { - "chainId": 99999, - "homesteadBlock": 0, - "eip150Block": 0, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "subnetEVMTimestamp": 0, - "feeConfig": { - "gasLimit": 20000000, - "minBaseFee": 1000000000, - "targetGas": 100000000, - "baseFeeChangeDenominator": 48, - "minBlockGasCost": 0, - "maxBlockGasCost": 10000000, - "targetBlockRate": 2, - "blockGasCostStep": 500000 - }, - "warpConfig": { - "blockTimestamp": 0 - } - }, - "alloc": { - "8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC": { - "balance": "0x52B7D2DCC80CD2E4000000" - }, - "0x0Fa8EA536Be85F32724D57A37758761B86416123": { - "balance": "0x52B7D2DCC80CD2E4000000" - }, - "1dD31B5351e76d51F4B152ce64fE5cf594694De5": { - "balance": "0x52B7D2DCC80CD2E4000000" - } - }, - "nonce": "0x0", - "timestamp": "0x0", - "extraData": "0x00", - "gasLimit": "0x1312D00", - "difficulty": "0x0", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "coinbase": "0x0000000000000000000000000000000000000000", - "number": "0x0", - "gasUsed": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" -} diff --git a/tests/e2e/e2e_test.go b/tests/e2e_test.go similarity index 92% rename from tests/e2e/e2e_test.go rename to tests/e2e_test.go index 55a7ade2..b7b88282 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e_test.go @@ -12,8 +12,6 @@ import ( "math/big" "os" "os/exec" - "strconv" - "strings" "testing" "time" @@ -47,7 +45,7 @@ var ( manager = runner.NewNetworkManager(anrConfig) warpChainConfigPath string relayerConfigPath string - teleporterContractAddress = common.HexToAddress("1dD31B5351e76d51F4B152ce64fE5cf594694De5") + teleporterContractAddress = common.HexToAddress("0x1dD31B5351e76d51F4B152ce64fE5cf594694De5") teleporterMessage = teleporter.TeleporterMessage{ MessageID: big.NewInt(1), SenderAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), @@ -68,14 +66,6 @@ func TestE2E(t *testing.T) { ginkgo.RunSpecs(t, "Relayer e2e test") } -func toWebsocketURI(uri string, blockchainID string) string { - return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) -} - -func toRPCURI(uri string, blockchainID string) string { - return fmt.Sprintf("http://%s/ext/bc/%s/rpc", strings.TrimPrefix(uri, "http://"), blockchainID) -} - // BeforeSuite starts the default network and adds 10 new nodes as validators with BLS keys // registered on the P-Chain. // Adds two disjoint sets of 5 of the new validator nodes to validate two new subnets with a @@ -110,7 +100,7 @@ var _ = ginkgo.BeforeSuite(func() { []*rpcpb.BlockchainSpec{ { VmName: evm.IDStr, - Genesis: "./tests/e2e/warp.json", + Genesis: "./tests/warp-genesis.json", ChainConfig: warpChainConfigPath, SubnetSpec: &rpcpb.SubnetSpec{ SubnetConfig: "", @@ -119,7 +109,7 @@ var _ = ginkgo.BeforeSuite(func() { }, { VmName: evm.IDStr, - Genesis: "./tests/e2e/warp.json", + Genesis: "./tests/warp-genesis.json", ChainConfig: warpChainConfigPath, SubnetSpec: &rpcpb.SubnetSpec{ SubnetConfig: "", @@ -138,7 +128,9 @@ var _ = ginkgo.BeforeSuite(func() { gomega.Expect(ok).Should(gomega.BeTrue()) chainBID := subnetBDetails.BlockchainID + // uri := toWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) uri := toWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) + client, err := ethclient.Dial(uri) gomega.Expect(err).Should(gomega.BeNil()) chainBIDInt, err := client.ChainID(ctx) @@ -158,7 +150,13 @@ var _ = ginkgo.AfterSuite(func() { gomega.Expect(os.Remove(relayerConfigPath)).Should(gomega.BeNil()) }) -var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { +// Ginkgo describe node that acts as a container for the relayer e2e tests. This test suite +// will run in order, starting off by setting up the subnet URIs and creating a relayer config +// file. It will then build the relayer binary and run it with the config file. The relayer +// will then send a transaction to the source subnet to issue a Warp message simulting a transaction +// sent from the Teleporter contract. The relayer will then wait for the transaction to be confirmed +// on the destination subnet and verify that the Warp message was received and unpacked correctly. +var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { var ( subnetIDs []ids.ID subnetA, subnetB ids.ID @@ -415,27 +413,3 @@ var _ = ginkgo.Describe("[Relayer]", ginkgo.Ordered, func() { gomega.Expect(*receivedTeleporterMessage).Should(gomega.Equal(teleporterMessage)) }) }) - -func getURIHostAndPort(uri string) (string, uint32, error) { - // At a minimum uri should have http:// of 7 characters - gomega.Expect(len(uri)).Should(gomega.BeNumerically(">", 7)) - if uri[:7] == "http://" { - uri = uri[7:] - } else if uri[:8] == "https://" { - uri = uri[8:] - } else { - return "", 0, fmt.Errorf("invalid uri: %s", uri) - } - - // Split the uri into host and port - hostAndPort := strings.Split(uri, ":") - gomega.Expect(len(hostAndPort)).Should(gomega.Equal(2)) - - // Parse the port - port, err := strconv.ParseUint(hostAndPort[1], 10, 32) - if err != nil { - return "", 0, fmt.Errorf("failed to parse port: %w", err) - } - - return hostAndPort[0], uint32(port), nil -} diff --git a/tests/utils.go b/tests/utils.go new file mode 100644 index 00000000..479cd0ce --- /dev/null +++ b/tests/utils.go @@ -0,0 +1,40 @@ +// Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package tests + +import ( + "fmt" + "strconv" + "strings" + + "github.com/onsi/gomega" +) + +func toWebsocketURI(uri string, blockchainID string) string { + return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) +} + +func getURIHostAndPort(uri string) (string, uint32, error) { + // At a minimum uri should have http:// of 7 characters + gomega.Expect(len(uri)).Should(gomega.BeNumerically(">", 7)) + if uri[:7] == "http://" { + uri = uri[7:] + } else if uri[:8] == "https://" { + uri = uri[8:] + } else { + return "", 0, fmt.Errorf("invalid uri: %s", uri) + } + + // Split the uri into host and port + hostAndPort := strings.Split(uri, ":") + gomega.Expect(len(hostAndPort)).Should(gomega.Equal(2)) + + // Parse the port + port, err := strconv.ParseUint(hostAndPort[1], 10, 32) + if err != nil { + return "", 0, fmt.Errorf("failed to parse port: %w", err) + } + + return hostAndPort[0], uint32(port), nil +} diff --git a/tests/warp-genesis.json b/tests/warp-genesis.json new file mode 100644 index 00000000..2560bba0 --- /dev/null +++ b/tests/warp-genesis.json @@ -0,0 +1,50 @@ +{ + "config": { + "chainId": 99999, + "homesteadBlock": 0, + "eip150Block": 0, + "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "subnetEVMTimestamp": 0, + "feeConfig": { + "gasLimit": 20000000, + "minBaseFee": 1000000000, + "targetGas": 100000000, + "baseFeeChangeDenominator": 48, + "minBlockGasCost": 0, + "maxBlockGasCost": 10000000, + "targetBlockRate": 2, + "blockGasCostStep": 500000 + }, + "warpConfig": { + "blockTimestamp": 0 + } + }, + "alloc": { + "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0x0Fa8EA536Be85F32724D57A37758761B86416123": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0x1dD31B5351e76d51F4B152ce64fE5cf594694De5": { + "balance": "0x52B7D2DCC80CD2E4000000" + } + }, + "nonce": "0x0", + "timestamp": "0x0", + "extraData": "0x00", + "gasLimit": "0x1312D00", + "difficulty": "0x0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" +} From 48bd712c71d7c17532c071adda6b81acae1c9f53 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Wed, 6 Sep 2023 21:24:47 +0000 Subject: [PATCH 28/56] add constant and check that warp genesis file exists --- tests/e2e_test.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/e2e_test.go b/tests/e2e_test.go index b7b88282..a9f21ec3 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -37,8 +37,11 @@ import ( "github.com/onsi/gomega" ) -const fundedKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" -const teleporterKeyStr = "d26c3344074df322e7c66ad0d2357d96f0d07d0f40038264d1d64d276709da41" +const ( + fundedKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" + teleporterKeyStr = "d26c3344074df322e7c66ad0d2357d96f0d07d0f40038264d1d64d276709da41" + warpGenesisFile = "./tests/warp-genesis.json" +) var ( anrConfig = runner.NewDefaultANRConfig() @@ -91,6 +94,10 @@ var _ = ginkgo.BeforeSuite(func() { gomega.Expect(err).Should(gomega.BeNil()) warpChainConfigPath = f.Name() + // Make sure that the warp genesis file exists + _, err = os.Stat(warpGenesisFile) + gomega.Expect(err).Should(gomega.BeNil()) + // Construct the network using the avalanche-network-runner _, err = manager.StartDefaultNetwork(ctx) gomega.Expect(err).Should(gomega.BeNil()) @@ -100,7 +107,7 @@ var _ = ginkgo.BeforeSuite(func() { []*rpcpb.BlockchainSpec{ { VmName: evm.IDStr, - Genesis: "./tests/warp-genesis.json", + Genesis: warpGenesisFile, ChainConfig: warpChainConfigPath, SubnetSpec: &rpcpb.SubnetSpec{ SubnetConfig: "", @@ -109,7 +116,7 @@ var _ = ginkgo.BeforeSuite(func() { }, { VmName: evm.IDStr, - Genesis: "./tests/warp-genesis.json", + Genesis: warpGenesisFile, ChainConfig: warpChainConfigPath, SubnetSpec: &rpcpb.SubnetSpec{ SubnetConfig: "", From 401c80d3eb248e1a24854cde8b95727364507e73 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Wed, 6 Sep 2023 21:29:57 +0000 Subject: [PATCH 29/56] fix go version in workflow --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d81e37eb..dfb5f801 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: $GO_VERSION + go-version: ${{ env.GO_VERSION }} - name: Build Relayer run: | @@ -55,7 +55,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: $GO_VERSION + go-version: ${{ env.GO_VERSION }} - name: Install AvalancheGo Release run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh @@ -64,7 +64,7 @@ jobs: run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy - name: Checkout awm-relayer repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Run E2E Tests run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh From 894a920743cf78d0cc2e3b5cbc0a71c4ec8f9986 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 7 Sep 2023 19:52:00 +0000 Subject: [PATCH 30/56] clean up variable declaration and testing --- tests/e2e_test.go | 54 +++++++++++++++++++++++------------------------ tests/utils.go | 2 +- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/tests/e2e_test.go b/tests/e2e_test.go index a9f21ec3..b1d05503 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -78,7 +78,7 @@ var _ = ginkgo.BeforeSuite(func() { var err error // Name 10 new validators (which should have BLS key registered) - subnetANodeNames := make([]string, 0) + subnetANodeNames := []string{} subnetBNodeNames := []string{} for i := 1; i <= 10; i++ { n := fmt.Sprintf("node%d-bls", i) @@ -135,8 +135,7 @@ var _ = ginkgo.BeforeSuite(func() { gomega.Expect(ok).Should(gomega.BeTrue()) chainBID := subnetBDetails.BlockchainID - // uri := toWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) - uri := toWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) + uri := httpToWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) client, err := ethclient.Dial(uri) gomega.Expect(err).Should(gomega.BeNil()) @@ -168,7 +167,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { subnetIDs []ids.ID subnetA, subnetB ids.ID blockchainIDA, blockchainIDB ids.ID - chainAURIs, chainBURIs []string + chainANodeURIs, chainBNodeURIs []string fundedKey *ecdsa.PrivateKey fundedAddress common.Address teleporterKey *ecdsa.PrivateKey @@ -176,7 +175,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { receivedWarpMessage *avalancheWarp.Message chainAWSClient, chainBWSClient ethclient.Client chainAIDInt *big.Int - payload = []byte{} + payload []byte ) fundedKey, err = crypto.HexToECDSA(fundedKeyStr) @@ -197,20 +196,20 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { subnetA = subnetIDs[0] subnetADetails, ok := manager.GetSubnet(subnetA) gomega.Expect(ok).Should(gomega.BeTrue()) - blockchainIDA = subnetADetails.BlockchainID gomega.Expect(len(subnetADetails.ValidatorURIs)).Should(gomega.Equal(5)) - chainAURIs = append(chainAURIs, subnetADetails.ValidatorURIs...) + blockchainIDA = subnetADetails.BlockchainID + chainANodeURIs = append(chainANodeURIs, subnetADetails.ValidatorURIs...) subnetB = subnetIDs[1] subnetBDetails, ok := manager.GetSubnet(subnetB) gomega.Expect(ok).Should(gomega.BeTrue()) - blockchainIDB = subnetBDetails.BlockchainID gomega.Expect(len(subnetBDetails.ValidatorURIs)).Should(gomega.Equal(5)) - chainBURIs = append(chainBURIs, subnetBDetails.ValidatorURIs...) + blockchainIDB = subnetBDetails.BlockchainID + chainBNodeURIs = append(chainBNodeURIs, subnetBDetails.ValidatorURIs...) - log.Info("Created URIs for both subnets", "ChainAURIs", chainAURIs, "ChainBURIs", chainBURIs, "blockchainIDA", blockchainIDA, "blockchainIDB", blockchainIDB) + log.Info("Created URIs for both subnets", "ChainAURIs", chainANodeURIs, "ChainBURIs", chainBNodeURIs, "blockchainIDA", blockchainIDA, "blockchainIDB", blockchainIDB) - chainAWSURI := toWebsocketURI(chainAURIs[0], blockchainIDA.String()) + chainAWSURI := httpToWebsocketURI(chainANodeURIs[0], blockchainIDA.String()) log.Info("Creating ethclient for blockchainA", "wsURI", chainAWSURI) chainAWSClient, err = ethclient.Dial(chainAWSURI) gomega.Expect(err).Should(gomega.BeNil()) @@ -218,7 +217,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { chainAIDInt, err = chainAWSClient.ChainID(context.Background()) gomega.Expect(err).Should(gomega.BeNil()) - chainBWSURI := toWebsocketURI(chainBURIs[0], blockchainIDB.String()) + chainBWSURI := httpToWebsocketURI(chainBNodeURIs[0], blockchainIDB.String()) log.Info("Creating ethclient for blockchainB", "wsURI", chainBWSURI) chainBWSClient, err = ethclient.Dial(chainBWSURI) gomega.Expect(err).Should(gomega.BeNil()) @@ -227,10 +226,10 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { }) ginkgo.It("Set up relayer config", ginkgo.Label("Relayer", "Setup Relayer"), func() { - hostA, portA, err := getURIHostAndPort(chainAURIs[0]) + hostA, portA, err := getURIHostAndPort(chainANodeURIs[0]) gomega.Expect(err).Should(gomega.BeNil()) - hostB, portB, err := getURIHostAndPort(chainBURIs[0]) + hostB, portB, err := getURIHostAndPort(chainBNodeURIs[0]) gomega.Expect(err).Should(gomega.BeNil()) log.Info("Setting up relayer config", "hostA", hostA, "portA", portA, "blockChainA", blockchainIDA.String(), "hostB", hostB, "portB", portB, "blockChainB", blockchainIDB.String(), "subnetA", subnetA.String(), "subnetB", subnetB.String()) @@ -238,7 +237,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { relayerConfig := config.Config{ LogLevel: logging.Info.LowerString(), NetworkID: 1337, - PChainAPIURL: chainAURIs[0], + PChainAPIURL: chainANodeURIs[0], EncryptConnection: false, SourceSubnets: []config.SourceSubnet{ { @@ -321,14 +320,6 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) - time.Sleep(15 * time.Second) - log.Info("Subscribing to new heads") - - newHeadsB := make(chan *types.Header, 10) - sub, err := chainBWSClient.SubscribeNewHead(ctx, newHeadsB) - gomega.Expect(err).Should(gomega.BeNil()) - defer sub.Unsubscribe() - nonceA, err := chainAWSClient.NonceAt(ctx, fundedAddress, nil) gomega.Expect(err).Should(gomega.BeNil()) @@ -361,6 +352,17 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { txSigner := types.LatestSignerForChainID(chainAIDInt) signedTx, err := types.SignTx(tx, txSigner, teleporterKey) gomega.Expect(err).Should(gomega.BeNil()) + gomega.Expect(signedTx.Hash()).Should(gomega.Equal(tx.Hash())) + + // Sleep for some time to make sure relayer has started up and subscribed. + time.Sleep(15 * time.Second) + log.Info("Subscribing to new heads on destination chain") + + newHeadsB := make(chan *types.Header, 10) + sub, err := chainBWSClient.SubscribeNewHead(ctx, newHeadsB) + gomega.Expect(err).Should(gomega.BeNil()) + defer sub.Unsubscribe() + log.Info("Sending sendWarpMessage transaction", "destinationChainID", blockchainIDB, "txHash", signedTx.Hash()) err = chainAWSClient.SendTransaction(ctx, signedTx) gomega.Expect(err).Should(gomega.BeNil()) @@ -386,12 +388,8 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { receivedWarpMessage, err = avalancheWarp.ParseMessage(predicateBytes) gomega.Expect(err).Should(gomega.BeNil()) - // Check that the transaction is no longer pending + // Check that the transaction has successful receipt status txHash := block.Transactions()[0].Hash() - _, isPending, err := chainBWSClient.TransactionByHash(ctx, txHash) - gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(isPending).Should(gomega.BeFalse()) - receipt, err := chainBWSClient.TransactionReceipt(ctx, txHash) gomega.Expect(err).Should(gomega.BeNil()) gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) diff --git a/tests/utils.go b/tests/utils.go index 479cd0ce..ddd080fe 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -11,7 +11,7 @@ import ( "github.com/onsi/gomega" ) -func toWebsocketURI(uri string, blockchainID string) string { +func httpToWebsocketURI(uri string, blockchainID string) string { return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) } From 9fa062beb232d003d3ea1d62aa6a1a75a1272bf5 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Thu, 7 Sep 2023 20:03:08 +0000 Subject: [PATCH 31/56] remove incorrect check since signed tx has type prefixed --- tests/e2e_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e_test.go b/tests/e2e_test.go index b1d05503..b9dfb205 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -352,7 +352,6 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { txSigner := types.LatestSignerForChainID(chainAIDInt) signedTx, err := types.SignTx(tx, txSigner, teleporterKey) gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(signedTx.Hash()).Should(gomega.Equal(tx.Hash())) // Sleep for some time to make sure relayer has started up and subscribed. time.Sleep(15 * time.Second) From f880c9b56b1ec77ffc3e9df46cdcd5f48cd305fb Mon Sep 17 00:00:00 2001 From: Cameron Schultz Date: Wed, 13 Sep 2023 09:55:41 -0500 Subject: [PATCH 32/56] cleanup readme --- README.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index be7e52d5..42e945fd 100644 --- a/README.md +++ b/README.md @@ -52,16 +52,22 @@ Unit tests can be ran locally by running the command in root of the project: ### E2E tests -E2E tests are ran as part of CI, but can also be ran locally. To run the E2E tests locally, you need to have the `avalanchego` build path and vm binary set up. For example with [subnet-evm](https://github.com/ava-labs/subnet-evm): +E2E tests are ran as part of CI, but can also be ran locally. To run the E2E tests locally, you'll need to do the following: +- Install Gingko following the intructions [here](https://onsi.github.io/ginkgo/#installing-ginkgo) +- Clone `subnet-evm` from [Github](https://github.com/ava-labs/subnet-evm) and checkout the correct version as specified in `go.mod` or `scripts/versions.sh` + +Next, set up the `avalanchego` build path and `subnet-evm` binary, making sure to install everything in a writeable location (here we use `~/tmp`): ```bash cd subnet-evm -BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh -./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +BASEDIR=~/tmp/e2e-test AVALANCHEGO_BUILD_PATH=~/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh +./scripts/build.sh ~/tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy ``` Then, in the root of the `awm-relayer` project, run: ```bash -AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh -``` \ No newline at end of file +AVALANCHEGO_BUILD_PATH=~/tmp/e2e-test/avalanchego DATA_DIR=~/tmp/e2e-test/data ./scripts/e2e_test.sh +``` + +Note that any additional E2E tests that run VMs other than `subnet-evm` will need to install and setup the VM binary in the same way. \ No newline at end of file From 33328e75d8ce332919b3732439f2e0b009b26c6e Mon Sep 17 00:00:00 2001 From: Cameron Schultz Date: Wed, 13 Sep 2023 10:13:16 -0500 Subject: [PATCH 33/56] e2e test cleanup --- tests/e2e_test.go | 31 +++++++++++++++++-------------- tests/utils.go | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/tests/e2e_test.go b/tests/e2e_test.go index b9dfb205..b2a0831f 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -21,9 +21,9 @@ import ( avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/awm-relayer/config" "github.com/ava-labs/awm-relayer/messages/teleporter" + "github.com/ava-labs/awm-relayer/peers" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/ethclient" - "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/plugin/evm" "github.com/ava-labs/subnet-evm/tests/utils" "github.com/ava-labs/subnet-evm/tests/utils/runner" @@ -232,11 +232,21 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { hostB, portB, err := getURIHostAndPort(chainBNodeURIs[0]) gomega.Expect(err).Should(gomega.BeNil()) - log.Info("Setting up relayer config", "hostA", hostA, "portA", portA, "blockChainA", blockchainIDA.String(), "hostB", hostB, "portB", portB, "blockChainB", blockchainIDB.String(), "subnetA", subnetA.String(), "subnetB", subnetB.String()) + log.Info( + "Setting up relayer config", + "hostA", hostA, + "portA", portA, + "blockChainA", blockchainIDA.String(), + "hostB", hostB, + "portB", portB, + "blockChainB", blockchainIDB.String(), + "subnetA", subnetA.String(), + "subnetB", subnetB.String(), + ) relayerConfig := config.Config{ LogLevel: logging.Info.LowerString(), - NetworkID: 1337, + NetworkID: peers.LocalNetworkID, PChainAPIURL: chainANodeURIs[0], EncryptConnection: false, SourceSubnets: []config.SourceSubnet{ @@ -339,16 +349,8 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) // Send a transaction that simulates the Teleporter contract calling sendWarpMessage with a Teleporter message payload - tx := types.NewTx(&types.DynamicFeeTx{ - ChainID: chainAIDInt, - Nonce: nonceA, - To: &warp.Module.Address, - Gas: 200_000, - GasFeeCap: big.NewInt(225 * params.GWei), - GasTipCap: big.NewInt(params.GWei), - Value: common.Big0, - Data: packedInput, - }) + tx := newTestTeleporterMessage(chainAIDInt, nonceA, packedInput) + txSigner := types.LatestSignerForChainID(chainAIDInt) signedTx, err := types.SignTx(tx, txSigner, teleporterKey) gomega.Expect(err).Should(gomega.BeNil()) @@ -366,6 +368,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { err = chainAWSClient.SendTransaction(ctx, signedTx) gomega.Expect(err).Should(gomega.BeNil()) + // Get the latest block from Subnet B log.Info("Waiting for new block confirmation") var blockHash common.Hash newHead := <-newHeadsB @@ -400,7 +403,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { _ = cmd.Wait() }) - ginkgo.It("Verify Warp Message", ginkgo.Label("Relay", "VerifyWarp"), func() { + ginkgo.It("Validate Received Warp Message Values", ginkgo.Label("Relay", "VerifyWarp"), func() { gomega.Expect(receivedWarpMessage.SourceChainID).Should(gomega.Equal(blockchainIDA)) addressedPayload, err := warpPayload.ParseAddressedPayload(receivedWarpMessage.Payload) gomega.Expect(err).Should(gomega.BeNil()) diff --git a/tests/utils.go b/tests/utils.go index ddd080fe..a176fed4 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -5,12 +5,25 @@ package tests import ( "fmt" + "math/big" "strconv" "strings" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/x/warp" + "github.com/ethereum/go-ethereum/common" "github.com/onsi/gomega" ) +var ( + defaultTeleporterMessageGas uint64 = 200_000 + defaultTeleporterMessageGasFeeCap = big.NewInt(225 * params.GWei) + defaultTeleporterMessageGasTipCap = big.NewInt(params.GWei) + defaultTeleporterMessageValue = common.Big0 + warpPrecompileAddress = warp.Module.Address +) + func httpToWebsocketURI(uri string, blockchainID string) string { return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) } @@ -38,3 +51,16 @@ func getURIHostAndPort(uri string) (string, uint32, error) { return hostAndPort[0], uint32(port), nil } + +func newTestTeleporterMessage(chainIDInt *big.Int, nonce uint64, data []byte) *types.Transaction { + return types.NewTx(&types.DynamicFeeTx{ + ChainID: chainIDInt, + Nonce: nonce, + To: &warpPrecompileAddress, + Gas: defaultTeleporterMessageGas, + GasFeeCap: defaultTeleporterMessageGasFeeCap, + GasTipCap: defaultTeleporterMessageGasTipCap, + Value: defaultTeleporterMessageValue, + Data: data, + }) +} From 9c142dde020c05105a3babff1120e02ac02fd46d Mon Sep 17 00:00:00 2001 From: Cameron Schultz Date: Wed, 13 Sep 2023 10:23:59 -0500 Subject: [PATCH 34/56] fix unit test job --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9b73ffe3..3c100f83 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,14 +20,14 @@ jobs: runs-on: ubuntu-20.04 steps: - - name: Checkout awm-relayer repository - uses: actions/checkout@v4 - - name: Setup Go uses: actions/setup-go@v4 with: go-version: ${{ env.GO_VERSION }} + - name: Checkout awm-relayer repository + uses: actions/checkout@v4 + - name: Build Relayer run: | cd awm-relayer From 02e234b5bb886ad597e84ffa9add858e6bdc25ca Mon Sep 17 00:00:00 2001 From: Cameron Schultz Date: Wed, 13 Sep 2023 10:25:07 -0500 Subject: [PATCH 35/56] fix unit test job again --- .github/workflows/test.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3c100f83..92cd9a83 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,14 +30,11 @@ jobs: - name: Build Relayer run: | - cd awm-relayer go mod tidy ./scripts/build.sh - name: Run Relayer Unit Tests - run: | - cd awm-relayer - ./scripts/test.sh + run: ./scripts/test.sh e2e_tests: runs-on: ubuntu-20.04 From bfaf9e3126d487cde1669ce6fbc20171acec8f83 Mon Sep 17 00:00:00 2001 From: Cameron Schultz Date: Thu, 14 Sep 2023 15:25:17 -0500 Subject: [PATCH 36/56] check message already delivered e2e --- tests/e2e_test.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/e2e_test.go b/tests/e2e_test.go index b2a0831f..3ece0b6b 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -370,10 +370,9 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { // Get the latest block from Subnet B log.Info("Waiting for new block confirmation") - var blockHash common.Hash newHead := <-newHeadsB log.Info("Received new head", "height", newHead.Number.Uint64()) - blockHash = newHead.Hash() + blockHash := newHead.Hash() block, err := chainBWSClient.BlockByHash(ctx, blockHash) gomega.Expect(err).Should(gomega.BeNil()) @@ -396,6 +395,21 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + // Try sending the same Teleporter message again. This should fail to be delivered + { + tx := newTestTeleporterMessage(chainAIDInt, nonceA+1, packedInput) + txSigner := types.LatestSignerForChainID(chainAIDInt) + signedTx, err := types.SignTx(tx, txSigner, teleporterKey) + gomega.Expect(err).Should(gomega.BeNil()) + + log.Info("Resending sendWarpMessage transaction", "destinationChainID", blockchainIDB, "txHash", signedTx.Hash()) + err = chainAWSClient.SendTransaction(ctx, signedTx) + gomega.Expect(err).Should(gomega.BeNil()) + + // We should not receive a new block on subnet B, since the relayer should have seen the Teleporter message was already delivered + gomega.Consistently(newHeadsB, 10*time.Second, 500*time.Millisecond).ShouldNot(gomega.Receive()) + } + log.Info("Finished sending warp message, closing down output channel") // Cancel the command and stop the relayer From 79b32524ede04039e20155c41c3cf393872ab1ad Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 14 Sep 2023 21:07:20 +0000 Subject: [PATCH 37/56] set storage location in e2e test --- tests/e2e_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/e2e_test.go b/tests/e2e_test.go index 3ece0b6b..90e653b6 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -249,6 +249,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { NetworkID: peers.LocalNetworkID, PChainAPIURL: chainANodeURIs[0], EncryptConnection: false, + StorageLocation: fmt.Sprintf("%s/.awm-relayer-storage",os.TempDir()), SourceSubnets: []config.SourceSubnet{ { SubnetID: subnetA.String(), From b43e68c367308770d2908adc0c6e21562ca32124 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 14 Sep 2023 23:50:36 +0000 Subject: [PATCH 38/56] wip --- tests/UniversalTeleporterDeployerAddress.txt | 1 + ...UniversalTeleporterDeployerTransaction.txt | 1 + ...rsalTeleporterMessengerContractAddress.txt | 1 + tests/e2e_test.go | 201 +++++++++++++++--- tests/utils.go | 32 ++- 5 files changed, 210 insertions(+), 26 deletions(-) create mode 100755 tests/UniversalTeleporterDeployerAddress.txt create mode 100755 tests/UniversalTeleporterDeployerTransaction.txt create mode 100755 tests/UniversalTeleporterMessengerContractAddress.txt diff --git a/tests/UniversalTeleporterDeployerAddress.txt b/tests/UniversalTeleporterDeployerAddress.txt new file mode 100755 index 00000000..07be42a5 --- /dev/null +++ b/tests/UniversalTeleporterDeployerAddress.txt @@ -0,0 +1 @@ +0x49db6B95B7005c0adfac0629cb1Ac77ADbDEDafE \ No newline at end of file diff --git a/tests/UniversalTeleporterDeployerTransaction.txt b/tests/UniversalTeleporterDeployerTransaction.txt new file mode 100755 index 00000000..8c0229a9 --- /dev/null +++ b/tests/UniversalTeleporterDeployerTransaction.txt @@ -0,0 +1 @@ +0xf92f0080860246139ca800833d09008080b92eac60a06040523480156200001157600080fd5b506001600081905580556040805163084279ef60e31b8152905173020000000000000000000000000000000000000591634213cf789160048083019260209291908290030181865afa1580156200006c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009291906200009b565b608052620000b5565b600060208284031215620000ae57600080fd5b5051919050565b608051612dd4620000d86000396000818161047a01526105f40152612dd46000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c806365171908116100de578063b771b3bc11610097578063cd3f2daa11610071578063cd3f2daa14610462578063d127dc9b14610475578063df20e8bc1461049c578063e03555df146104af57600080fd5b8063b771b3bc146103f0578063c473eef8146103fe578063c9bb11431461043757600080fd5b806365171908146102da57806366533d12146102fd578063781f97441461037a57806382f2c43a146103a35780638f12376f146103d55780639a496900146103dd57600080fd5b806322296c3a1161013057806322296c3a1461022d57806329ec9beb1461024057806333e890fe146102605780635bf91119146102945780636192762c1461029c57806362448850146102c757600080fd5b80631008518114610178578063105343711461018d57806319570c74146101a85780631af671f8146101bb57806321f18054146101ce578063220c95681461021a575b600080fd5b61018b610186366004611c57565b6104e5565b005b610195600581565b6040519081526020015b60405180910390f35b61018b6101b6366004611c7b565b6108c9565b61018b6101c9366004611cd2565b610a6f565b6102026101dc366004611d18565b60056020908152600092835260408084209091529082529020546001600160a01b031681565b6040516001600160a01b03909116815260200161019f565b610195610228366004611d18565b610bc3565b61018b61023b366004611c57565b610be4565b61019561024e366004611d3a565b60026020526000908152604090205481565b61020261026e366004611d18565b60009182526005602090815260408084209284529190529020546001600160a01b031690565b610195600481565b6101956102aa366004611d53565b600760209081526000928352604080842090915290825290205481565b6101956102d5366004611d8c565b610c5e565b6102ed6102e8366004611e04565b610d10565b604051901515815260200161019f565b61034f61030b366004611d18565b60046020908152600092835260408084208252918352918190208054825180840190935260018201546001600160a01b031683526002909101549282019290925282565b6040805192835281516001600160a01b0316602080850191909152909101519082015260600161019f565b610202610388366004611d3a565b6003602052600090815260409020546001600160a01b031681565b6103b66103b1366004611d18565b610d57565b604080516001600160a01b03909316835260208301919091520161019f565b610195604481565b6101956103eb366004611e58565b610da0565b6102026005600160991b0181565b61019561040c366004611d53565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205490565b610195610445366004611d18565b600660209081526000928352604080842090915290825290205481565b61018b610470366004611cd2565b610f20565b6101957f000000000000000000000000000000000000000000000000000000000000000081565b6101956104aa366004611d3a565b611139565b6102ed6104bd366004611d18565b60009182526005602090815260408084209284529190529020546001600160a01b0316151590565b60018054146105075760405163a815ca6b60e01b815260040160405180910390fd5b60026001556001600160a01b0381166105335760405163f69d505160e01b815260040160405180910390fd5b6000806005600160991b016001600160a01b0316631f9b40ec6040518163ffffffff1660e01b8152600401600060405180830381865afa15801561057b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105a39190810190612022565b91509150806105c557604051636b2f19e960e01b815260040160405180910390fd5b60208201516001600160a01b031630146105f25760405163e942653d60e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008260400151146106365760405163ba7cf01760e01b815260040160405180910390fd5b60608201516001600160a01b0316301461066357604051635209852960e01b815260040160405180910390fd5b6000826080015180602001905181019061067d9190612230565b83516000908152600560209081526040808320845184529091529020549091506001600160a01b0316156106c45760405163d68df41f60e01b815260040160405180910390fd5b6106d2338260800151611144565b6106ef57604051633c20627b60e01b815260040160405180910390fd5b8251600090815260056020908152604080832084518452909152902080546001600160a01b0319166001600160a01b03861617905560c0810151511561073b57825161073b90826111b9565b60a08101515160005b818110156107965760008360a0015182815181106107645761076461231a565b602002602001015190506107858660000151826000015183602001516112c0565b5061078f81612346565b9050610744565b5083516000908152600360205260409020546001600160a01b03168061080b576040516107c290611c22565b604051809103906000f0801580156107de573d6000803e3d6000fd5b508551600090815260036020526040902080546001600160a01b0319166001600160a01b03831617905590505b604080518082018252845181526001600160a01b0388811660208301529151634877bcdd60e11b8152918316916390ef79ba9161084a9160040161235f565b600060405180830381600087803b15801561086457600080fd5b505af1158015610878573d6000803e3d6000fd5b50505050826000015185600001517f522ce4da81e9fb994bf6a122282939647b6e69817be443f7d1c152e76a082cc7856040516108b5919061243c565b60405180910390a350506001805550505050565b6001600054146108ec5760405163880a040960e01b815260040160405180910390fd5b6002600090815581900361091357604051632e206d3360e21b815260040160405180910390fd5b6001600160a01b03821661093a5760405163338065fb60e11b815260040160405180910390fd5b60008481526004602090815260408083208684529091529020546109715760405163d68df41f60e01b815260040160405180910390fd5b60008481526004602090815260408083208684529091529020600101546001600160a01b038381169116146109b95760405163338065fb60e11b815260040160405180910390fd5b60006109c58383611390565b60008681526004602090815260408083208884529091528120600201805492935083929091906109f69084906124cb565b90915550506000858152600460209081526040808320878452825291829020825160018201546001600160a01b0316815260029091015491810191909152859187917f28fe05eedf0479c9159e5b6dd2a28c93fa1a408eba22dc801fd9bc493a7fc0c2910160405180910390a350506001600055505050565b600160005414610a925760405163880a040960e01b815260040160405180910390fd5b600260009081558281526004602090815260408083208435845290915290205480610ad0576040516328915ac760e01b815260040160405180910390fd5b600082604051602001610ae39190612663565b604051602081830303815290604052905081818051906020012014610b1b57604051638b56642d60e01b815260040160405180910390fd5b8260000135847f7491aecf1f3e24837ce48fd97fc8729fc036cebb3e5078643f3301b72852aa0785604051610b509190612663565b60405180910390a360405163125ce2d160e11b81526005600160991b01906324b9c5a290610b8690879030908690600401612733565b600060405180830381600087803b158015610ba057600080fd5b505af1158015610bb4573d6000803e3d6000fd5b50506001600055505050505050565b60008281526004602090815260408083208484529091529020545b92915050565b3360009081526007602090815260408083206001600160a01b038516845290915281205490819003610c2957604051630d1102c760e21b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b0387168085529252822091909155610c5a91836114b4565b5050565b6000600160005414610c835760405163880a040960e01b815260040160405180910390fd5b6002600055610d058235610c9d6040850160208601611c57565b604085016080860135610cb360a088018861275d565b610cc060c08a018a6127a6565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610d009250508b359050611517565b6116fa565b600160005592915050565b6000610d4f8484848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061114492505050565b949350505050565b6000828152600460209081526040808320848452825291829020825180840190935260018101546001600160a01b031680845260029091015492909101829052905b9250929050565b6000600160005414610dc55760405163880a040960e01b815260040160405180910390fd5b60026000908155856001600160401b03811115610de457610de4611ef0565b604051908082528060200260200182016040528015610e2957816020015b6040805180820190915260008082526020820152815260200190600190039081610e025790505b50905060005b86811015610eea576000888883818110610e4b57610e4b61231a565b60008d815260056020908152604080832093820295909501358083529290529290922054919250506001600160a01b031680610e9a576040516303bbb48b60e01b815260040160405180910390fd5b6040518060400160405280838152602001826001600160a01b0316815250848481518110610eca57610eca61231a565b602002602001018190525050508080610ee290612346565b915050610e2f565b5060408051600080825260208201909252610f0f918a918890829089908990886116fa565b600160005598975050505050505050565b6001805414610f425760405163a815ca6b60e01b815260040160405180910390fd5b600260015560008281526006602090815260408083208435845290915290205480610f80576040516328915ac760e01b815260040160405180910390fd5b8082604051602001610f929190612663565b6040516020818303038152906040528051906020012014610fc657604051638b56642d60e01b815260040160405180910390fd5b610fd66060830160408401611c57565b6001600160a01b03163b60000361100057604051635209852960e01b815260040160405180910390fd5b60405182359084907f3d5f30e93c1e27cda0e05a7b9e51144613a816cd90561f8493393bbcf4e0035890600090a360008381526006602090815260408083208535845290915280822082905561105c9060608501908501611c57565b6001600160a01b0316846110766040860160208701611c57565b61108360c08701876127a6565b60405160240161109694939291906127ec565b60408051601f198184030181529181526020820180516001600160e01b031663643477d560e11b179052516110cb9190612817565b6000604051808303816000865af19150503d8060008114611108576040519150601f19603f3d011682016040523d82523d6000602084013e61110d565b606091505b505090508061112f5760405163990b27a960e01b815260040160405180910390fd5b5050600180555050565b6000610bde82611952565b6000815160000361115757506001610bde565b60005b82518110156111af57836001600160a01b031683828151811061117f5761117f61231a565b60200260200101516001600160a01b03160361119f576001915050610bde565b6111a881612346565b905061115a565b5060009392505050565b80606001515a10156111de576040516307099c5360e21b815260040160405180910390fd5b80604001516001600160a01b03163b6000036111fe57610c5a828261196c565b600081604001516001600160a01b031682606001518484602001518560c0015160405160240161123093929190612733565b60408051601f198184030181529181526020820180516001600160e01b031663643477d560e11b179052516112659190612817565b60006040518083038160008787f1925050503d80600081146112a3576040519150601f19603f3d011682016040523d82523d6000602084013e6112a8565b606091505b50509050806112bb576112bb838361196c565b505050565b60008381526004602090815260408083208584528252918290208251808401845281548152835180850190945260018201546001600160a01b031684526002909101548383015290810191909152805161131a5750505050565b600084815260046020908152604080832086845282528083208381556001810180546001600160a01b031916905560020183905583820180518301516001600160a01b03878116865260078552838620925151168552925282208054919290916113859084906124cb565b909155505050505050565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa1580156113d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113fd9190612833565b90506114146001600160a01b0385163330866119ea565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa15801561145b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147f9190612833565b90508181116114a157604051632c1e664f60e11b815260040160405180910390fd5b6114ab828261284c565b95945050505050565b6040516001600160a01b0383166024820152604481018290526112bb90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611a28565b6000818152600360205260409020546060906001600160a01b03168061157c576040805160008082526020820190925290611574565b604080518082019091526000808252602082015281526020019060019003908161154d5790505b509392505050565b6000600590506000826001600160a01b031663949d225d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e69190612833565b905060058110156115f5578091505b816001600160401b0381111561160d5761160d611ef0565b60405190808252806020026020018201604052801561165257816020015b604080518082019091526000808252602082015281526020019060019003908161162b5790505b50935060005b828110156116f157836001600160a01b031663957908d16040518163ffffffff1660e01b815260040160408051808303816000875af115801561169f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c3919061285f565b8582815181106116d5576116d561231a565b6020026020010181905250806116ea90612346565b9050611658565b50505050919050565b600061170589611952565b905060006040518060e00160405280838152602001336001600160a01b031681526020018a6001600160a01b031681526020018881526020018787808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250938552505050602080830187905260409283018890529151929350916117959184910161243c565b60408051601f1981840301815291815260008d8152600260209081529181208690559192508a0135156118155760006117d160208c018c611c57565b6001600160a01b0316036117f85760405163338065fb60e11b815260040160405180910390fd5b61181261180860208c018c611c57565b8b60200135611390565b90505b60405180604001604052808380519060200120815260200160405180604001604052808d600001602081019061184b9190611c57565b6001600160a01b03908116825260209182018690529190925260008f8152600483526040808220898352845290819020845181559383015180516001860180546001600160a01b03191691909416179092559101516002909201919091555184908d907f7491aecf1f3e24837ce48fd97fc8729fc036cebb3e5078643f3301b72852aa07906118db90879061243c565b60405180910390a360405163125ce2d160e11b81526005600160991b01906324b9c5a290611911908f9030908790600401612733565b600060405180830381600087803b15801561192b57600080fd5b505af115801561193f573d6000803e3d6000fd5b5050505050505098975050505050505050565b600081815260026020526040812054610bde9060016124cb565b8060405160200161197d919061243c565b60408051601f198184030181528282528051602091820120600086815260068352838120865182529092529190205581519083907f50e5f3de5b0b3e6c82553b7e0f5f7080a291be07aa30a311084a9457f4a956bc906119de90859061243c565b60405180910390a35050565b6040516001600160a01b0380851660248301528316604482015260648101829052611a229085906323b872dd60e01b906084016114e0565b50505050565b6000611a7d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611aff9092919063ffffffff16565b8051909150156112bb5780806020019051810190611a9b919061287b565b6112bb5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b6060610d4f848460008585600080866001600160a01b03168587604051611b269190612817565b60006040518083038185875af1925050503d8060008114611b63576040519150601f19603f3d011682016040523d82523d6000602084013e611b68565b606091505b5091509150611b7987838387611b84565b979650505050505050565b60608315611bf3578251600003611bec576001600160a01b0385163b611bec5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611af6565b5081610d4f565b610d4f8383815115611c085781518083602001fd5b8060405162461bcd60e51b8152600401611af69190612896565b6104f5806128aa83390190565b6001600160a01b0381168114611c4457600080fd5b50565b8035611c5281611c2f565b919050565b600060208284031215611c6957600080fd5b8135611c7481611c2f565b9392505050565b60008060008060808587031215611c9157600080fd5b84359350602085013592506040850135611caa81611c2f565b9396929550929360600135925050565b600060e08284031215611ccc57600080fd5b50919050565b60008060408385031215611ce557600080fd5b8235915060208301356001600160401b03811115611d0257600080fd5b611d0e85828601611cba565b9150509250929050565b60008060408385031215611d2b57600080fd5b50508035926020909101359150565b600060208284031215611d4c57600080fd5b5035919050565b60008060408385031215611d6657600080fd5b8235611d7181611c2f565b91506020830135611d8181611c2f565b809150509250929050565b600060208284031215611d9e57600080fd5b81356001600160401b03811115611db457600080fd5b610d4f84828501611cba565b60008083601f840112611dd257600080fd5b5081356001600160401b03811115611de957600080fd5b6020830191508360208260051b8501011115610d9957600080fd5b600080600060408486031215611e1957600080fd5b8335611e2481611c2f565b925060208401356001600160401b03811115611e3f57600080fd5b611e4b86828701611dc0565b9497909650939450505050565b60008060008060008086880360a0811215611e7257600080fd5b8735965060208801356001600160401b0380821115611e9057600080fd5b611e9c8b838c01611dc0565b90985096508691506040603f1984011215611eb657600080fd5b60408a01955060808a0135925080831115611ed057600080fd5b5050611ede89828a01611dc0565b979a9699509497509295939492505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715611f2857611f28611ef0565b60405290565b60405160e081016001600160401b0381118282101715611f2857611f28611ef0565b604051601f8201601f191681016001600160401b0381118282101715611f7857611f78611ef0565b604052919050565b8051611c5281611c2f565b60005b83811015611fa6578181015183820152602001611f8e565b50506000910152565b600082601f830112611fc057600080fd5b81516001600160401b03811115611fd957611fd9611ef0565b611fec601f8201601f1916602001611f50565b81815284602083860101111561200157600080fd5b610d4f826020830160208701611f8b565b80518015158114611c5257600080fd5b6000806040838503121561203557600080fd5b82516001600160401b038082111561204c57600080fd5b9084019060a0828703121561206057600080fd5b612068611f06565b82518152602083015161207a81611c2f565b602082015260408381015190820152606083015161209781611c2f565b60608201526080830151828111156120ae57600080fd5b6120ba88828601611faf565b60808301525093506120d191505060208401612012565b90509250929050565b60006001600160401b038211156120f3576120f3611ef0565b5060051b60200190565b600082601f83011261210e57600080fd5b8151602061212361211e836120da565b611f50565b82815260059290921b8401810191818101908684111561214257600080fd5b8286015b8481101561216657805161215981611c2f565b8352918301918301612146565b509695505050505050565b60006040828403121561218357600080fd5b604051604081018181106001600160401b03821117156121a5576121a5611ef0565b80604052508091508251815260208301516121bf81611c2f565b6020919091015292915050565b600082601f8301126121dd57600080fd5b815160206121ed61211e836120da565b82815260069290921b8401810191818101908684111561220c57600080fd5b8286015b84811015612166576122228882612171565b835291830191604001612210565b60006020828403121561224257600080fd5b81516001600160401b038082111561225957600080fd5b9083019060e0828603121561226d57600080fd5b612275611f2e565b8251815261228560208401611f80565b602082015261229660408401611f80565b6040820152606083015160608201526080830151828111156122b757600080fd5b6122c3878286016120fd565b60808301525060a0830151828111156122db57600080fd5b6122e7878286016121cc565b60a08301525060c0830151828111156122ff57600080fd5b61230b87828601611faf565b60c08301525095945050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161235857612358612330565b5060010190565b815181526020808301516001600160a01b03169082015260408101610bde565b600081518084526020808501945080840160005b838110156123b85781516001600160a01b031687529582019590820190600101612393565b509495945050505050565b600081518084526020808501945080840160005b838110156123b8576123fd878351805182526020908101516001600160a01b0316910152565b60409690960195908201906001016123d7565b60008151808452612428816020860160208601611f8b565b601f01601f19169290920160200192915050565b60208152815160208201526000602083015160018060a01b038082166040850152806040860151166060850152505060608301516080830152608083015160e060a084015261248f61010084018261237f565b905060a0840151601f19808584030160c08601526124ad83836123c3565b925060c08601519150808584030160e0860152506114ab8282612410565b80820180821115610bde57610bde612330565b6000808335601e198436030181126124f557600080fd5b83016020810192503590506001600160401b0381111561251457600080fd5b8060051b3603821315610d9957600080fd5b8183526000602080850194508260005b858110156123b857813561254981611c2f565b6001600160a01b031687529582019590820190600101612536565b6000808335601e1984360301811261257b57600080fd5b83016020810192503590506001600160401b0381111561259a57600080fd5b8060061b3603821315610d9957600080fd5b8183526000602080850194508260005b858110156123b85781358752828201356125d581611c2f565b6001600160a01b03168784015260409687019691909101906001016125bc565b6000808335601e1984360301811261260c57600080fd5b83016020810192503590506001600160401b0381111561262b57600080fd5b803603821315610d9957600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60208152813560208201526000602083013561267e81611c2f565b6001600160a01b031660408381019190915261269b908401611c47565b6001600160a01b038116606084015250606083013560808301526126c260808401846124de565b60e060a08501526126d861010085018284612526565b9150506126e860a0850185612564565b601f19808685030160c08701526127008483856125ac565b935061270f60c08801886125f5565b93509150808685030160e08701525061272983838361263a565b9695505050505050565b8381526001600160a01b03831660208201526060604082018190526000906114ab90830184612410565b6000808335601e1984360301811261277457600080fd5b8301803591506001600160401b0382111561278e57600080fd5b6020019150600581901b3603821315610d9957600080fd5b6000808335601e198436030181126127bd57600080fd5b8301803591506001600160401b038211156127d757600080fd5b602001915036819003821315610d9957600080fd5b8481526001600160a01b0384166020820152606060408201819052600090612729908301848661263a565b60008251612829818460208701611f8b565b9190910192915050565b60006020828403121561284557600080fd5b5051919050565b81810381811115610bde57610bde612330565b60006040828403121561287157600080fd5b611c748383612171565b60006020828403121561288d57600080fd5b611c7482612012565b602081526000611c74602083018461241056fe60a06040526000600155600060025534801561001a57600080fd5b50336080526080516104ae6100476000396000818160ac01528181610187015261027d01526104ae6000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c806390ef79ba1161005b57806390ef79ba146100e6578063949d225d146100fb578063957908d114610103578063ddf0b0091461012f57600080fd5b80633df4ddf41461008257806347799da81461009e5780638da5cb5b146100a7575b600080fd5b61008b60015481565b6040519081526020015b60405180910390f35b61008b60025481565b6100ce7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610095565b6100f96100f436600461037b565b61017c565b005b61008b610247565b61010b61025e565b60408051825181526020928301516001600160a01b03169281019290925201610095565b61015f61013d366004610393565b600060208190529081526040902080546001909101546001600160a01b031682565b604080519283526001600160a01b03909116602083015201610095565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101c4576040516282b42960e81b815260040160405180910390fd5b6002805482916000918291826101d9836103c2565b91905055815260200190815260200160002081816101f791906103f3565b5061020a90506040820160208301610428565b6001600160a01b031681600001357fc4193cc773105974437d05cb715f0f6ec12111aaea921df69ece51d70093f12760405160405180910390a350565b6000600154600254610259919061044c565b905090565b6040805180820190915260008082526020820152336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102ba576040516282b42960e81b815260040160405180910390fd5b6001546002548190036102e0576040516331dcf2b560e01b815260040160405180910390fd5b600081815260208181526040808320815180830190925280548252600180820180546001600160a01b0381168587015287875294869052949091556001600160a01b0319909216909255909250610338908290610465565b600155602082015182516040516001600160a01b03909216917f05a9686ec81d1f07f4a996660cf66d8c3f2fd0fdfd7bb23458fe7a7df30c9ce790600090a35090565b60006040828403121561038d57600080fd5b50919050565b6000602082840312156103a557600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b6000600182016103d4576103d46103ac565b5060010190565b6001600160a01b03811681146103f057600080fd5b50565b81358155600181016020830135610409816103db565b81546001600160a01b0319166001600160a01b03919091161790555050565b60006020828403121561043a57600080fd5b8135610445816103db565b9392505050565b8181038181111561045f5761045f6103ac565b92915050565b8082018082111561045f5761045f6103ac56fea26469706673582212201f6f4e9e1d83f1bcfa7c7487cc9c21f177d4329423f05a5a949d0559295932b064736f6c63430008120033a264697066735822122058e26683966fa9a61e65952938630ff9606e956955de4e05ddaf6c2929152c8364736f6c634300081200331ba03333333333333333333333333333333333333333333333333333333333333333a03333333333333333333333333333333333333333333333333333333333333333 \ No newline at end of file diff --git a/tests/UniversalTeleporterMessengerContractAddress.txt b/tests/UniversalTeleporterMessengerContractAddress.txt new file mode 100755 index 00000000..0e3d6647 --- /dev/null +++ b/tests/UniversalTeleporterMessengerContractAddress.txt @@ -0,0 +1 @@ +0xF3106362ca2B4291DE3e130Cd0335F0eC4d70b26 \ No newline at end of file diff --git a/tests/e2e_test.go b/tests/e2e_test.go index 90e653b6..b5fe510c 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -22,8 +22,10 @@ import ( "github.com/ava-labs/awm-relayer/config" "github.com/ava-labs/awm-relayer/messages/teleporter" "github.com/ava-labs/awm-relayer/peers" + relayerEvm "github.com/ava-labs/awm-relayer/vms/evm" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/ethclient" + "github.com/ava-labs/subnet-evm/interfaces" "github.com/ava-labs/subnet-evm/plugin/evm" "github.com/ava-labs/subnet-evm/tests/utils" "github.com/ava-labs/subnet-evm/tests/utils/runner" @@ -38,9 +40,8 @@ import ( ) const ( - fundedKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" - teleporterKeyStr = "d26c3344074df322e7c66ad0d2357d96f0d07d0f40038264d1d64d276709da41" - warpGenesisFile = "./tests/warp-genesis.json" + fundedKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" + warpGenesisFile = "./tests/warp-genesis.json" ) var ( @@ -48,7 +49,7 @@ var ( manager = runner.NewNetworkManager(anrConfig) warpChainConfigPath string relayerConfigPath string - teleporterContractAddress = common.HexToAddress("0x1dD31B5351e76d51F4B152ce64fE5cf594694De5") + teleporterContractAddress common.Address teleporterMessage = teleporter.TeleporterMessage{ MessageID: big.NewInt(1), SenderAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), @@ -170,11 +171,11 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { chainANodeURIs, chainBNodeURIs []string fundedKey *ecdsa.PrivateKey fundedAddress common.Address - teleporterKey *ecdsa.PrivateKey err error receivedWarpMessage *avalancheWarp.Message chainAWSClient, chainBWSClient ethclient.Client chainAIDInt *big.Int + chainBIDInt *big.Int payload []byte ) @@ -184,11 +185,6 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { } fundedAddress = crypto.PubkeyToAddress(fundedKey.PublicKey) - teleporterKey, err = crypto.HexToECDSA(teleporterKeyStr) - if err != nil { - panic(err) - } - ginkgo.It("Setup subnet URIs", ginkgo.Label("Relayer", "Setup"), func() { subnetIDs = manager.GetSubnets() gomega.Expect(len(subnetIDs)).Should(gomega.Equal(2)) @@ -222,9 +218,122 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { chainBWSClient, err = ethclient.Dial(chainBWSURI) gomega.Expect(err).Should(gomega.BeNil()) + chainBIDInt, err = chainBWSClient.ChainID(context.Background()) + gomega.Expect(err).Should(gomega.BeNil()) + log.Info("Finished setting up e2e test subnet variables") }) + ginkgo.It("Deploy Teleporter Contract", ginkgo.Label("Relayer", "Deploy Teleporter"), func() { + ctx := context.Background() + + // Read in the Teleporter contract information + teleporterContractAddress = common.BytesToAddress(readHexTextFile("./tests/UniversalTeleporterMessengerContractAddress.txt")) + teleporterDeployerAddress := common.BytesToAddress(readHexTextFile("./tests/UniversalTeleporterDeployerAddress.txt")) + teleporterDeployerTransaction := readHexTextFile("./tests/UniversalTeleporterDeployerTransaction.txt") + + nonceA, err := chainAWSClient.NonceAt(ctx, fundedAddress, nil) + gomega.Expect(err).Should(gomega.BeNil()) + + nonceB, err := chainBWSClient.NonceAt(ctx, fundedAddress, nil) + gomega.Expect(err).Should(gomega.BeNil()) + + gasTipCapA, err := chainAWSClient.SuggestGasTipCap(context.Background()) + gomega.Expect(err).Should(gomega.BeNil()) + gasTipCapB, err := chainBWSClient.SuggestGasTipCap(context.Background()) + gomega.Expect(err).Should(gomega.BeNil()) + + baseFeeA, err := chainAWSClient.EstimateBaseFee(context.Background()) + gasFeeCapA := baseFeeA.Mul(baseFeeA, big.NewInt(relayerEvm.BaseFeeFactor)) + gasFeeCapA.Add(gasFeeCapA, big.NewInt(relayerEvm.MaxPriorityFeePerGas)) + + baseFeeB, err := chainBWSClient.EstimateBaseFee(context.Background()) + gasFeeCapB := baseFeeB.Mul(baseFeeB, big.NewInt(relayerEvm.BaseFeeFactor)) + gasFeeCapB.Add(gasFeeCapB, big.NewInt(relayerEvm.MaxPriorityFeePerGas)) + + // Fund the deployer address + { + txA := types.NewTx(&types.DynamicFeeTx{ + ChainID: chainAIDInt, + Nonce: nonceA, + To: &teleporterDeployerAddress, + Gas: defaultTeleporterMessageGas, + GasFeeCap: gasFeeCapA, + GasTipCap: gasTipCapA, + Value: common.Big1, + }) + txSignerA := types.LatestSignerForChainID(chainAIDInt) + triggerTxA, err := types.SignTx(txA, txSignerA, fundedKey) + gomega.Expect(err).Should(gomega.BeNil()) + err = chainAWSClient.SendTransaction(ctx, triggerTxA) + gomega.Expect(err).Should(gomega.BeNil()) + time.Sleep(5 * time.Second) + receipt, err := chainAWSClient.TransactionReceipt(ctx, triggerTxA.Hash()) + gomega.Expect(err).Should(gomega.BeNil()) + gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + } + { + txB := types.NewTx(&types.DynamicFeeTx{ + ChainID: chainBIDInt, + Nonce: nonceB, + To: &teleporterDeployerAddress, + Gas: defaultTeleporterMessageGas, + GasFeeCap: gasFeeCapB, + GasTipCap: gasTipCapB, + Value: big.NewInt(1_000_000_000), + }) + txSignerB := types.LatestSignerForChainID(chainBIDInt) + triggerTxB, err := types.SignTx(txB, txSignerB, fundedKey) + gomega.Expect(err).Should(gomega.BeNil()) + err = chainBWSClient.SendTransaction(ctx, triggerTxB) + gomega.Expect(err).Should(gomega.BeNil()) + time.Sleep(5 * time.Second) + receipt, err := chainBWSClient.TransactionReceipt(ctx, triggerTxB.Hash()) + gomega.Expect(err).Should(gomega.BeNil()) + gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + } + // Deploy Teleporter on the two subnets + { + deployA := types.NewTx(&types.DynamicFeeTx{ + ChainID: chainAIDInt, + Nonce: nonceA + 1, + Gas: 20_000_000, + GasFeeCap: gasFeeCapA, + GasTipCap: gasTipCapA, + Data: teleporterDeployerTransaction, + }) + txSignerA := types.LatestSignerForChainID(chainAIDInt) + triggerTxA, err := types.SignTx(deployA, txSignerA, fundedKey) + gomega.Expect(err).Should(gomega.BeNil()) + err = chainAWSClient.SendTransaction(ctx, triggerTxA) + gomega.Expect(err).Should(gomega.BeNil()) + time.Sleep(5 * time.Second) + receipt, err := chainAWSClient.TransactionReceipt(ctx, triggerTxA.Hash()) + log.Info("Deployed Teleporter on chainA", "receipt", receipt, "err", err) + gomega.Expect(err).Should(gomega.BeNil()) + gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + } + { + deployB := types.NewTx(&types.DynamicFeeTx{ + ChainID: chainBIDInt, + Nonce: nonceB + 1, + Gas: 20_000_000, + GasFeeCap: gasFeeCapB, + GasTipCap: gasTipCapB, + Data: teleporterDeployerTransaction, + }) + txSignerB := types.LatestSignerForChainID(chainBIDInt) + triggerTxB, err := types.SignTx(deployB, txSignerB, fundedKey) + gomega.Expect(err).Should(gomega.BeNil()) + err = chainAWSClient.SendTransaction(ctx, triggerTxB) + gomega.Expect(err).Should(gomega.BeNil()) + time.Sleep(5 * time.Second) + receipt, err := chainBWSClient.TransactionReceipt(ctx, triggerTxB.Hash()) + gomega.Expect(err).Should(gomega.BeNil()) + gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + } + }) + ginkgo.It("Set up relayer config", ginkgo.Label("Relayer", "Setup Relayer"), func() { hostA, portA, err := getURIHostAndPort(chainANodeURIs[0]) gomega.Expect(err).Should(gomega.BeNil()) @@ -249,7 +358,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { NetworkID: peers.LocalNetworkID, PChainAPIURL: chainANodeURIs[0], EncryptConnection: false, - StorageLocation: fmt.Sprintf("%s/.awm-relayer-storage",os.TempDir()), + StorageLocation: fmt.Sprintf("%s/.awm-relayer-storage", os.TempDir()), SourceSubnets: []config.SourceSubnet{ { SubnetID: subnetA.String(), @@ -339,21 +448,27 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { log.Info("Packing teleporter message", "nonceA", nonceA, "nonceB", nonceB) - payload, err = teleporter.PackTeleporterMessage(common.Hash(blockchainIDB), teleporterMessage) - gomega.Expect(err).Should(gomega.BeNil()) - - packedInput, err := warp.PackSendWarpMessage(warp.SendWarpMessageInput{ - DestinationChainID: common.Hash(blockchainIDB), - DestinationAddress: teleporterContractAddress, - Payload: payload, - }) + data, err := teleporter.EVMTeleporterContractABI.Pack( + "sendCrossChainMessage", + TeleporterMessageInput{ + DestinationChainID: blockchainIDB, + DestinationAddress: fundedAddress, + FeeInfo: FeeInfo{ + ContractAddress: fundedAddress, + Amount: big.NewInt(0), + }, + RequiredGasLimit: big.NewInt(1_000_000), + AllowedRelayerAddresses: []common.Address{}, + Message: []byte{}, + }, + ) gomega.Expect(err).Should(gomega.BeNil()) // Send a transaction that simulates the Teleporter contract calling sendWarpMessage with a Teleporter message payload - tx := newTestTeleporterMessage(chainAIDInt, nonceA, packedInput) + tx := newTestTeleporterMessage(chainAIDInt, teleporterContractAddress, nonceA, data) txSigner := types.LatestSignerForChainID(chainAIDInt) - signedTx, err := types.SignTx(tx, txSigner, teleporterKey) + signedTx, err := types.SignTx(tx, txSigner, fundedKey) gomega.Expect(err).Should(gomega.BeNil()) // Sleep for some time to make sure relayer has started up and subscribed. @@ -365,10 +480,37 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) defer sub.Unsubscribe() + logsA := make(chan types.Log, 10) + subA, err := chainAWSClient.SubscribeFilterLogs( + ctx, + interfaces.FilterQuery{ + // Topics: [][]common.Hash{ + // {warp.WarpABI.Events["SendWarpMessage"].ID}, + // {}, + // {}, + // }, + Addresses: []common.Address{ + teleporterContractAddress, + }, + }, + logsA, + ) + gomega.Expect(err).Should(gomega.BeNil()) + defer subA.Unsubscribe() + log.Info("Sending sendWarpMessage transaction", "destinationChainID", blockchainIDB, "txHash", signedTx.Hash()) err = chainAWSClient.SendTransaction(ctx, signedTx) gomega.Expect(err).Should(gomega.BeNil()) + time.Sleep(5 * time.Second) + receipt, err := chainAWSClient.TransactionReceipt(ctx, signedTx.Hash()) + gomega.Expect(err).Should(gomega.BeNil()) + gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + + log.Info("Waiting for log") + newLogsA := <-logsA + log.Info("Received new log", newLogsA) + // Get the latest block from Subnet B log.Info("Waiting for new block confirmation") newHead := <-newHeadsB @@ -392,15 +534,26 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { // Check that the transaction has successful receipt status txHash := block.Transactions()[0].Hash() - receipt, err := chainBWSClient.TransactionReceipt(ctx, txHash) + receipt, err = chainBWSClient.TransactionReceipt(ctx, txHash) gomega.Expect(err).Should(gomega.BeNil()) gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) // Try sending the same Teleporter message again. This should fail to be delivered { - tx := newTestTeleporterMessage(chainAIDInt, nonceA+1, packedInput) + data, err := teleporter.EVMTeleporterContractABI.Pack( + "sendCrossChainMessage", + TeleporterMessageInput{ + DestinationChainID: blockchainIDB, + DestinationAddress: fundedAddress, + FeeInfo: FeeInfo{}, + RequiredGasLimit: big.NewInt(1_000_000), + AllowedRelayerAddresses: []common.Address{}, + Message: []byte{}, + }, + ) + tx := newTestTeleporterMessage(chainAIDInt, teleporterContractAddress, nonceA+1, data) txSigner := types.LatestSignerForChainID(chainAIDInt) - signedTx, err := types.SignTx(tx, txSigner, teleporterKey) + signedTx, err := types.SignTx(tx, txSigner, fundedKey) gomega.Expect(err).Should(gomega.BeNil()) log.Info("Resending sendWarpMessage transaction", "destinationChainID", blockchainIDB, "txHash", signedTx.Hash()) diff --git a/tests/utils.go b/tests/utils.go index a176fed4..c47aac02 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -4,11 +4,14 @@ package tests import ( + "encoding/hex" "fmt" "math/big" + "os" "strconv" "strings" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/coreth/params" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/x/warp" @@ -24,6 +27,21 @@ var ( warpPrecompileAddress = warp.Module.Address ) +// Teleporter contract sendCrossChainMessage input type +type TeleporterMessageInput struct { + DestinationChainID ids.ID + DestinationAddress common.Address + FeeInfo FeeInfo + RequiredGasLimit *big.Int + Message []byte + AllowedRelayerAddresses []common.Address +} + +type FeeInfo struct { + ContractAddress common.Address + Amount *big.Int +} + func httpToWebsocketURI(uri string, blockchainID string) string { return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) } @@ -52,11 +70,11 @@ func getURIHostAndPort(uri string) (string, uint32, error) { return hostAndPort[0], uint32(port), nil } -func newTestTeleporterMessage(chainIDInt *big.Int, nonce uint64, data []byte) *types.Transaction { +func newTestTeleporterMessage(chainIDInt *big.Int, teleporterAddress common.Address, nonce uint64, data []byte) *types.Transaction { return types.NewTx(&types.DynamicFeeTx{ ChainID: chainIDInt, Nonce: nonce, - To: &warpPrecompileAddress, + To: &teleporterAddress, Gas: defaultTeleporterMessageGas, GasFeeCap: defaultTeleporterMessageGasFeeCap, GasTipCap: defaultTeleporterMessageGasTipCap, @@ -64,3 +82,13 @@ func newTestTeleporterMessage(chainIDInt *big.Int, nonce uint64, data []byte) *t Data: data, }) } + +func readHexTextFile(filename string) []byte { + fileData, err := os.ReadFile(filename) + gomega.Expect(err).Should(gomega.BeNil()) + hexString := string(fileData) + hexString = hexString[2:] // remove 0x prefix + data, err := hex.DecodeString(hexString) + gomega.Expect(err).Should(gomega.BeNil()) + return data +} From 15955c4e53f9e5e82f112c4edd06e3c11a1274f9 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Fri, 15 Sep 2023 20:10:11 +0000 Subject: [PATCH 39/56] e2e tests deploy teleporter --- tests/e2e_test.go | 201 +++++++++++++++++----------------------------- tests/utils.go | 4 + 2 files changed, 78 insertions(+), 127 deletions(-) diff --git a/tests/e2e_test.go b/tests/e2e_test.go index b5fe510c..eb98105d 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -23,9 +23,9 @@ import ( "github.com/ava-labs/awm-relayer/messages/teleporter" "github.com/ava-labs/awm-relayer/peers" relayerEvm "github.com/ava-labs/awm-relayer/vms/evm" + "github.com/ava-labs/coreth/rpc" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/ethclient" - "github.com/ava-labs/subnet-evm/interfaces" "github.com/ava-labs/subnet-evm/plugin/evm" "github.com/ava-labs/subnet-evm/tests/utils" "github.com/ava-labs/subnet-evm/tests/utils/runner" @@ -33,6 +33,7 @@ import ( warpPayload "github.com/ava-labs/subnet-evm/warp/payload" "github.com/ava-labs/subnet-evm/x/warp" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/onsi/ginkgo/v2" @@ -47,13 +48,14 @@ const ( var ( anrConfig = runner.NewDefaultANRConfig() manager = runner.NewNetworkManager(anrConfig) + fundedAddress = common.HexToAddress("0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC") warpChainConfigPath string relayerConfigPath string teleporterContractAddress common.Address teleporterMessage = teleporter.TeleporterMessage{ MessageID: big.NewInt(1), - SenderAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), - DestinationAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), + SenderAddress: fundedAddress, + DestinationAddress: fundedAddress, RequiredGasLimit: big.NewInt(1), AllowedRelayerAddresses: []common.Address{}, Receipts: []teleporter.TeleporterMessageReceipt{}, @@ -165,25 +167,27 @@ var _ = ginkgo.AfterSuite(func() { // on the destination subnet and verify that the Warp message was received and unpacked correctly. var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { var ( - subnetIDs []ids.ID - subnetA, subnetB ids.ID - blockchainIDA, blockchainIDB ids.ID - chainANodeURIs, chainBNodeURIs []string - fundedKey *ecdsa.PrivateKey - fundedAddress common.Address - err error - receivedWarpMessage *avalancheWarp.Message - chainAWSClient, chainBWSClient ethclient.Client - chainAIDInt *big.Int - chainBIDInt *big.Int - payload []byte + subnetIDs []ids.ID + subnetA, subnetB ids.ID + blockchainIDA, blockchainIDB ids.ID + chainANodeURIs, chainBNodeURIs []string + fundedKey *ecdsa.PrivateKey + err error + receivedWarpMessage *avalancheWarp.Message + chainBWSClient ethclient.Client + chainARPCClient, chainBRPCClient ethclient.Client + chainARPCURI, chainBRPCURI string + chainAIDInt *big.Int + chainBIDInt *big.Int + payload []byte + relayerCmd *exec.Cmd + relayerCancel context.CancelFunc ) fundedKey, err = crypto.HexToECDSA(fundedKeyStr) if err != nil { panic(err) } - fundedAddress = crypto.PubkeyToAddress(fundedKey.PublicKey) ginkgo.It("Setup subnet URIs", ginkgo.Label("Relayer", "Setup"), func() { subnetIDs = manager.GetSubnets() @@ -206,19 +210,23 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { log.Info("Created URIs for both subnets", "ChainAURIs", chainANodeURIs, "ChainBURIs", chainBNodeURIs, "blockchainIDA", blockchainIDA, "blockchainIDB", blockchainIDB) chainAWSURI := httpToWebsocketURI(chainANodeURIs[0], blockchainIDA.String()) - log.Info("Creating ethclient for blockchainA", "wsURI", chainAWSURI) - chainAWSClient, err = ethclient.Dial(chainAWSURI) + chainARPCURI = httpToRPCURI(chainANodeURIs[0], blockchainIDA.String()) + log.Info("Creating ethclient for blockchainA", "wsURI", chainAWSURI, "rpcURL, chainARPCURI") + chainARPCClient, err = ethclient.Dial(chainARPCURI) gomega.Expect(err).Should(gomega.BeNil()) - chainAIDInt, err = chainAWSClient.ChainID(context.Background()) + chainAIDInt, err = chainARPCClient.ChainID(context.Background()) gomega.Expect(err).Should(gomega.BeNil()) chainBWSURI := httpToWebsocketURI(chainBNodeURIs[0], blockchainIDB.String()) + chainBRPCURI = httpToRPCURI(chainBNodeURIs[0], blockchainIDB.String()) log.Info("Creating ethclient for blockchainB", "wsURI", chainBWSURI) chainBWSClient, err = ethclient.Dial(chainBWSURI) gomega.Expect(err).Should(gomega.BeNil()) + chainBRPCClient, err = ethclient.Dial(chainBRPCURI) + gomega.Expect(err).Should(gomega.BeNil()) - chainBIDInt, err = chainBWSClient.ChainID(context.Background()) + chainBIDInt, err = chainBRPCClient.ChainID(context.Background()) gomega.Expect(err).Should(gomega.BeNil()) log.Info("Finished setting up e2e test subnet variables") @@ -232,27 +240,28 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { teleporterDeployerAddress := common.BytesToAddress(readHexTextFile("./tests/UniversalTeleporterDeployerAddress.txt")) teleporterDeployerTransaction := readHexTextFile("./tests/UniversalTeleporterDeployerTransaction.txt") - nonceA, err := chainAWSClient.NonceAt(ctx, fundedAddress, nil) + nonceA, err := chainARPCClient.NonceAt(ctx, fundedAddress, nil) gomega.Expect(err).Should(gomega.BeNil()) - nonceB, err := chainBWSClient.NonceAt(ctx, fundedAddress, nil) + nonceB, err := chainBRPCClient.NonceAt(ctx, fundedAddress, nil) gomega.Expect(err).Should(gomega.BeNil()) - gasTipCapA, err := chainAWSClient.SuggestGasTipCap(context.Background()) + gasTipCapA, err := chainARPCClient.SuggestGasTipCap(context.Background()) gomega.Expect(err).Should(gomega.BeNil()) - gasTipCapB, err := chainBWSClient.SuggestGasTipCap(context.Background()) + gasTipCapB, err := chainBRPCClient.SuggestGasTipCap(context.Background()) gomega.Expect(err).Should(gomega.BeNil()) - baseFeeA, err := chainAWSClient.EstimateBaseFee(context.Background()) + baseFeeA, err := chainARPCClient.EstimateBaseFee(context.Background()) gasFeeCapA := baseFeeA.Mul(baseFeeA, big.NewInt(relayerEvm.BaseFeeFactor)) gasFeeCapA.Add(gasFeeCapA, big.NewInt(relayerEvm.MaxPriorityFeePerGas)) - baseFeeB, err := chainBWSClient.EstimateBaseFee(context.Background()) + baseFeeB, err := chainBRPCClient.EstimateBaseFee(context.Background()) gasFeeCapB := baseFeeB.Mul(baseFeeB, big.NewInt(relayerEvm.BaseFeeFactor)) gasFeeCapB.Add(gasFeeCapB, big.NewInt(relayerEvm.MaxPriorityFeePerGas)) // Fund the deployer address { + value := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) // 10eth txA := types.NewTx(&types.DynamicFeeTx{ ChainID: chainAIDInt, Nonce: nonceA, @@ -260,19 +269,20 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { Gas: defaultTeleporterMessageGas, GasFeeCap: gasFeeCapA, GasTipCap: gasTipCapA, - Value: common.Big1, + Value: value, }) txSignerA := types.LatestSignerForChainID(chainAIDInt) triggerTxA, err := types.SignTx(txA, txSignerA, fundedKey) gomega.Expect(err).Should(gomega.BeNil()) - err = chainAWSClient.SendTransaction(ctx, triggerTxA) + err = chainARPCClient.SendTransaction(ctx, triggerTxA) gomega.Expect(err).Should(gomega.BeNil()) time.Sleep(5 * time.Second) - receipt, err := chainAWSClient.TransactionReceipt(ctx, triggerTxA.Hash()) + receipt, err := chainARPCClient.TransactionReceipt(ctx, triggerTxA.Hash()) gomega.Expect(err).Should(gomega.BeNil()) gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) } { + value := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) // 10eth txB := types.NewTx(&types.DynamicFeeTx{ ChainID: chainBIDInt, Nonce: nonceB, @@ -280,57 +290,36 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { Gas: defaultTeleporterMessageGas, GasFeeCap: gasFeeCapB, GasTipCap: gasTipCapB, - Value: big.NewInt(1_000_000_000), + Value: value, }) txSignerB := types.LatestSignerForChainID(chainBIDInt) triggerTxB, err := types.SignTx(txB, txSignerB, fundedKey) gomega.Expect(err).Should(gomega.BeNil()) - err = chainBWSClient.SendTransaction(ctx, triggerTxB) + err = chainBRPCClient.SendTransaction(ctx, triggerTxB) gomega.Expect(err).Should(gomega.BeNil()) time.Sleep(5 * time.Second) - receipt, err := chainBWSClient.TransactionReceipt(ctx, triggerTxB.Hash()) + receipt, err := chainBRPCClient.TransactionReceipt(ctx, triggerTxB.Hash()) gomega.Expect(err).Should(gomega.BeNil()) gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) } // Deploy Teleporter on the two subnets { - deployA := types.NewTx(&types.DynamicFeeTx{ - ChainID: chainAIDInt, - Nonce: nonceA + 1, - Gas: 20_000_000, - GasFeeCap: gasFeeCapA, - GasTipCap: gasTipCapA, - Data: teleporterDeployerTransaction, - }) - txSignerA := types.LatestSignerForChainID(chainAIDInt) - triggerTxA, err := types.SignTx(deployA, txSignerA, fundedKey) - gomega.Expect(err).Should(gomega.BeNil()) - err = chainAWSClient.SendTransaction(ctx, triggerTxA) + rpcClient, err := rpc.DialContext(ctx, chainARPCURI) + err = rpcClient.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(teleporterDeployerTransaction)) gomega.Expect(err).Should(gomega.BeNil()) time.Sleep(5 * time.Second) - receipt, err := chainAWSClient.TransactionReceipt(ctx, triggerTxA.Hash()) - log.Info("Deployed Teleporter on chainA", "receipt", receipt, "err", err) + teleporterCode, err := chainARPCClient.CodeAt(ctx, teleporterContractAddress, nil) gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + gomega.Expect(len(teleporterCode)).Should(gomega.BeNumerically(">", 2)) // 0x is an EOA, contract returns the bytecode } { - deployB := types.NewTx(&types.DynamicFeeTx{ - ChainID: chainBIDInt, - Nonce: nonceB + 1, - Gas: 20_000_000, - GasFeeCap: gasFeeCapB, - GasTipCap: gasTipCapB, - Data: teleporterDeployerTransaction, - }) - txSignerB := types.LatestSignerForChainID(chainBIDInt) - triggerTxB, err := types.SignTx(deployB, txSignerB, fundedKey) - gomega.Expect(err).Should(gomega.BeNil()) - err = chainAWSClient.SendTransaction(ctx, triggerTxB) + rpcClient, err := rpc.DialContext(ctx, chainBRPCURI) + err = rpcClient.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(teleporterDeployerTransaction)) gomega.Expect(err).Should(gomega.BeNil()) time.Sleep(5 * time.Second) - receipt, err := chainBWSClient.TransactionReceipt(ctx, triggerTxB.Hash()) + teleporterCode, err := chainBRPCClient.CodeAt(ctx, teleporterContractAddress, nil) gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + gomega.Expect(len(teleporterCode)).Should(gomega.BeNumerically(">", 2)) // 0x is an EOA, contract returns the bytecode } }) @@ -419,14 +408,15 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { cmdOutput := make(chan string) // Run awm relayer binary with config path - relayerContext, relayerCancel := context.WithCancel(ctx) - cmd := exec.CommandContext(relayerContext, "./build/awm-relayer", "--config-file", relayerConfigPath) + var relayerContext context.Context + relayerContext, relayerCancel = context.WithCancel(ctx) + relayerCmd = exec.CommandContext(relayerContext, "./build/awm-relayer", "--config-file", relayerConfigPath) // Set up a pipe to capture the command's output - cmdReader, _ := cmd.StdoutPipe() + cmdReader, _ := relayerCmd.StdoutPipe() // Start the command - err := cmd.Start() + err := relayerCmd.Start() gomega.Expect(err).Should(gomega.BeNil()) // Start a goroutine to read and output the command's stdout @@ -438,15 +428,14 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { cmdOutput <- "Command execution finished" }() + nonceA, err := chainARPCClient.NonceAt(ctx, fundedAddress, nil) gomega.Expect(err).Should(gomega.BeNil()) - nonceA, err := chainAWSClient.NonceAt(ctx, fundedAddress, nil) - gomega.Expect(err).Should(gomega.BeNil()) - - nonceB, err := chainBWSClient.NonceAt(ctx, fundedAddress, nil) + nonceB, err := chainBRPCClient.NonceAt(ctx, fundedAddress, nil) gomega.Expect(err).Should(gomega.BeNil()) log.Info("Packing teleporter message", "nonceA", nonceA, "nonceB", nonceB) + payload, err = teleporter.PackTeleporterMessage(common.Hash(blockchainIDB), teleporterMessage) data, err := teleporter.EVMTeleporterContractABI.Pack( "sendCrossChainMessage", @@ -457,14 +446,14 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { ContractAddress: fundedAddress, Amount: big.NewInt(0), }, - RequiredGasLimit: big.NewInt(1_000_000), + RequiredGasLimit: big.NewInt(1), AllowedRelayerAddresses: []common.Address{}, - Message: []byte{}, + Message: []byte{1, 2, 3, 4}, }, ) gomega.Expect(err).Should(gomega.BeNil()) - // Send a transaction that simulates the Teleporter contract calling sendWarpMessage with a Teleporter message payload + // Send a transaction to the Teleporter contract tx := newTestTeleporterMessage(chainAIDInt, teleporterContractAddress, nonceA, data) txSigner := types.LatestSignerForChainID(chainAIDInt) @@ -480,46 +469,30 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) defer sub.Unsubscribe() - logsA := make(chan types.Log, 10) - subA, err := chainAWSClient.SubscribeFilterLogs( - ctx, - interfaces.FilterQuery{ - // Topics: [][]common.Hash{ - // {warp.WarpABI.Events["SendWarpMessage"].ID}, - // {}, - // {}, - // }, - Addresses: []common.Address{ - teleporterContractAddress, - }, - }, - logsA, - ) - gomega.Expect(err).Should(gomega.BeNil()) - defer subA.Unsubscribe() - log.Info("Sending sendWarpMessage transaction", "destinationChainID", blockchainIDB, "txHash", signedTx.Hash()) - err = chainAWSClient.SendTransaction(ctx, signedTx) + err = chainARPCClient.SendTransaction(ctx, signedTx) gomega.Expect(err).Should(gomega.BeNil()) time.Sleep(5 * time.Second) - receipt, err := chainAWSClient.TransactionReceipt(ctx, signedTx.Hash()) + receipt, err := chainARPCClient.TransactionReceipt(ctx, signedTx.Hash()) gomega.Expect(err).Should(gomega.BeNil()) gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) - log.Info("Waiting for log") - newLogsA := <-logsA - log.Info("Received new log", newLogsA) - // Get the latest block from Subnet B log.Info("Waiting for new block confirmation") newHead := <-newHeadsB log.Info("Received new head", "height", newHead.Number.Uint64()) blockHash := newHead.Hash() - - block, err := chainBWSClient.BlockByHash(ctx, blockHash) + block, err := chainBRPCClient.BlockByHash(ctx, blockHash) gomega.Expect(err).Should(gomega.BeNil()) - log.Info("Got block", "blockHash", blockHash, "blockNumber", block.NumberU64(), "transactions", block.Transactions(), "block", block) + log.Info( + "Got block", + "blockHash", blockHash, + "blockNumber", block.NumberU64(), + "transactions", block.Transactions(), + "numTransactions", len(block.Transactions()), + "block", block, + ) accessLists := block.Transactions()[0].AccessList() gomega.Expect(len(accessLists)).Should(gomega.Equal(1)) gomega.Expect(accessLists[0].Address).Should(gomega.Equal(warp.Module.Address)) @@ -534,41 +507,15 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { // Check that the transaction has successful receipt status txHash := block.Transactions()[0].Hash() - receipt, err = chainBWSClient.TransactionReceipt(ctx, txHash) + receipt, err = chainBRPCClient.TransactionReceipt(ctx, txHash) gomega.Expect(err).Should(gomega.BeNil()) gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) - // Try sending the same Teleporter message again. This should fail to be delivered - { - data, err := teleporter.EVMTeleporterContractABI.Pack( - "sendCrossChainMessage", - TeleporterMessageInput{ - DestinationChainID: blockchainIDB, - DestinationAddress: fundedAddress, - FeeInfo: FeeInfo{}, - RequiredGasLimit: big.NewInt(1_000_000), - AllowedRelayerAddresses: []common.Address{}, - Message: []byte{}, - }, - ) - tx := newTestTeleporterMessage(chainAIDInt, teleporterContractAddress, nonceA+1, data) - txSigner := types.LatestSignerForChainID(chainAIDInt) - signedTx, err := types.SignTx(tx, txSigner, fundedKey) - gomega.Expect(err).Should(gomega.BeNil()) - - log.Info("Resending sendWarpMessage transaction", "destinationChainID", blockchainIDB, "txHash", signedTx.Hash()) - err = chainAWSClient.SendTransaction(ctx, signedTx) - gomega.Expect(err).Should(gomega.BeNil()) - - // We should not receive a new block on subnet B, since the relayer should have seen the Teleporter message was already delivered - gomega.Consistently(newHeadsB, 10*time.Second, 500*time.Millisecond).ShouldNot(gomega.Receive()) - } - log.Info("Finished sending warp message, closing down output channel") // Cancel the command and stop the relayer relayerCancel() - _ = cmd.Wait() + _ = relayerCmd.Wait() }) ginkgo.It("Validate Received Warp Message Values", ginkgo.Label("Relay", "VerifyWarp"), func() { diff --git a/tests/utils.go b/tests/utils.go index c47aac02..80c6339d 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -46,6 +46,10 @@ func httpToWebsocketURI(uri string, blockchainID string) string { return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) } +func httpToRPCURI(uri string, blockchainID string) string { + return fmt.Sprintf("http://%s/ext/bc/%s/rpc", strings.TrimPrefix(uri, "http://"), blockchainID) +} + func getURIHostAndPort(uri string) (string, uint32, error) { // At a minimum uri should have http:// of 7 characters gomega.Expect(len(uri)).Should(gomega.BeNumerically(">", 7)) From 93020e510673574f6db6175dede167f8f67b7e6c Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Fri, 15 Sep 2023 20:52:07 +0000 Subject: [PATCH 40/56] e2e test already delivered message --- go.mod | 4 +- tests/e2e_test.go | 121 ++++++++++++++++++++++++++++++++++++---------- tests/utils.go | 32 +++++++++++- 3 files changed, 128 insertions(+), 29 deletions(-) diff --git a/go.mod b/go.mod index c5f596a3..6ad7e584 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,12 @@ go 1.18 require ( github.com/ava-labs/avalanche-network-runner v1.7.2-0.20230825150237-723bc7b31724 github.com/ava-labs/avalanchego v1.10.9 + github.com/ava-labs/coreth v0.12.5-rc.3 github.com/ava-labs/subnet-evm v0.5.4 github.com/ethereum/go-ethereum v1.12.0 github.com/onsi/ginkgo/v2 v2.12.0 github.com/onsi/gomega v1.27.10 + github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.16.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.16.0 @@ -19,7 +21,6 @@ require ( require ( github.com/Microsoft/go-winio v0.5.2 // indirect - github.com/ava-labs/coreth v0.12.5-rc.3 // indirect github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 // indirect @@ -55,7 +56,6 @@ require ( github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/otiai10/copy v1.11.0 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect diff --git a/tests/e2e_test.go b/tests/e2e_test.go index eb98105d..7a468ca3 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -4,7 +4,6 @@ package tests import ( - "bufio" "context" "crypto/ecdsa" "encoding/json" @@ -20,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/awm-relayer/config" + "github.com/ava-labs/awm-relayer/database" "github.com/ava-labs/awm-relayer/messages/teleporter" "github.com/ava-labs/awm-relayer/peers" relayerEvm "github.com/ava-labs/awm-relayer/vms/evm" @@ -61,6 +61,7 @@ var ( Receipts: []teleporter.TeleporterMessageReceipt{}, Message: []byte{1, 2, 3, 4}, } + storageLocation = fmt.Sprintf("%s/.awm-relayer-storage", os.TempDir()) ) func TestE2E(t *testing.T) { @@ -347,7 +348,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { NetworkID: peers.LocalNetworkID, PChainAPIURL: chainANodeURIs[0], EncryptConnection: false, - StorageLocation: fmt.Sprintf("%s/.awm-relayer-storage", os.TempDir()), + StorageLocation: storageLocation, SourceSubnets: []config.SourceSubnet{ { SubnetID: subnetA.String(), @@ -404,29 +405,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { ginkgo.It("Send Message from A to B", ginkgo.Label("Warp", "SendWarp"), func() { ctx := context.Background() - // Create a channel to communicate with the goroutine - cmdOutput := make(chan string) - - // Run awm relayer binary with config path - var relayerContext context.Context - relayerContext, relayerCancel = context.WithCancel(ctx) - relayerCmd = exec.CommandContext(relayerContext, "./build/awm-relayer", "--config-file", relayerConfigPath) - - // Set up a pipe to capture the command's output - cmdReader, _ := relayerCmd.StdoutPipe() - - // Start the command - err := relayerCmd.Start() - gomega.Expect(err).Should(gomega.BeNil()) - - // Start a goroutine to read and output the command's stdout - go func() { - scanner := bufio.NewScanner(cmdReader) - for scanner.Scan() { - log.Info(scanner.Text()) - } - cmdOutput <- "Command execution finished" - }() + relayerCmd, relayerCancel = runRelayerExecutable(ctx) nonceA, err := chainARPCClient.NonceAt(ctx, fundedAddress, nil) gomega.Expect(err).Should(gomega.BeNil()) @@ -511,6 +490,61 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + // // Try sending the same Teleporter message again. This should fail to be delivered + // { + // // Kill the relayer, then reset the warden db + // relayerCancel() + // _ = relayerCmd.Wait() + + // // Run awm relayer binary with config path + // var relayerContext context.Context + // relayerContext, relayerCancel = context.WithCancel(ctx) + // relayerCmd := exec.CommandContext(relayerContext, "./build/awm-relayer", "--config-file", relayerConfigPath) + + // // Set up a pipe to capture the command's output + // cmdReader, _ := relayerCmd.StdoutPipe() + + // // Start the command + // err := relayerCmd.Start() + // gomega.Expect(err).Should(gomega.BeNil()) + + // // Start a goroutine to read and output the command's stdout + // go func() { + // scanner := bufio.NewScanner(cmdReader) + // for scanner.Scan() { + // log.Info(scanner.Text()) + // } + // cmdOutput <- "Command execution finished" + // }() + // } + // { + // data, err := teleporter.EVMTeleporterContractABI.Pack( + // "sendCrossChainMessage", + // TeleporterMessageInput{ + // DestinationChainID: blockchainIDB, + // DestinationAddress: fundedAddress, + // FeeInfo: FeeInfo{ + // ContractAddress: fundedAddress, + // Amount: big.NewInt(0), + // }, + // RequiredGasLimit: big.NewInt(1_000_000), + // AllowedRelayerAddresses: []common.Address{}, + // Message: []byte{}, + // }, + // ) + // tx := newTestTeleporterMessage(chainAIDInt, teleporterContractAddress, nonceA+1, data) + // txSigner := types.LatestSignerForChainID(chainAIDInt) + // signedTx, err := types.SignTx(tx, txSigner, fundedKey) + // gomega.Expect(err).Should(gomega.BeNil()) + + // log.Info("Resending sendWarpMessage transaction", "destinationChainID", blockchainIDB, "txHash", signedTx.Hash()) + // err = chainARPCClient.SendTransaction(ctx, signedTx) + // gomega.Expect(err).Should(gomega.BeNil()) + + // // We should not receive a new block on subnet B, since the relayer should have seen the Teleporter message was already delivered + // gomega.Consistently(newHeadsB, 10*time.Second, 500*time.Millisecond).ShouldNot(gomega.Receive()) + // } + log.Info("Finished sending warp message, closing down output channel") // Cancel the command and stop the relayer @@ -518,7 +552,42 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { _ = relayerCmd.Wait() }) - ginkgo.It("Validate Received Warp Message Values", ginkgo.Label("Relay", "VerifyWarp"), func() { + ginkgo.It("Try relaying already delivered message", ginkgo.Label("Relayer", "RelayerAlreadyDeliveredMessage"), func() { + ctx := context.Background() + logger := logging.NewLogger( + "awm-relayer", + logging.NewWrappedCore( + logging.Info, + os.Stdout, + logging.JSON.ConsoleEncoder(), + ), + ) + jsonDB, err := database.NewJSONFileStorage(logger, storageLocation, []ids.ID{blockchainIDA, blockchainIDB}) + gomega.Expect(err).Should(gomega.BeNil()) + + // Modify the JSON database to force the relayer to re-process old blocks + + jsonDB.Put(blockchainIDA, []byte(database.LatestProcessedBlockKey), []byte("0")) + jsonDB.Put(blockchainIDB, []byte(database.LatestProcessedBlockKey), []byte("0")) + + // Subscribe to the destination chain block published + newHeadsB := make(chan *types.Header, 10) + sub, err := chainBWSClient.SubscribeNewHead(ctx, newHeadsB) + gomega.Expect(err).Should(gomega.BeNil()) + defer sub.Unsubscribe() + + // Run the relayer + relayerCmd, relayerCancel = runRelayerExecutable(ctx) + + // We should not receive a new block on subnet B, since the relayer should have seen the Teleporter message was already delivered + gomega.Consistently(newHeadsB, 10*time.Second, 500*time.Millisecond).ShouldNot(gomega.Receive()) + + // Cancel the command and stop the relayer + relayerCancel() + _ = relayerCmd.Wait() + }) + + ginkgo.It("Validate Received Warp Message Values", ginkgo.Label("Relaery", "VerifyWarp"), func() { gomega.Expect(receivedWarpMessage.SourceChainID).Should(gomega.Equal(blockchainIDA)) addressedPayload, err := warpPayload.ParseAddressedPayload(receivedWarpMessage.Payload) gomega.Expect(err).Should(gomega.BeNil()) diff --git a/tests/utils.go b/tests/utils.go index 80c6339d..e7c1a15f 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -4,18 +4,22 @@ package tests import ( + "bufio" + "context" "encoding/hex" "fmt" "math/big" "os" + "os/exec" "strconv" "strings" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/coreth/params" "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/x/warp" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" "github.com/onsi/gomega" ) @@ -42,6 +46,32 @@ type FeeInfo struct { Amount *big.Int } +func runRelayerExecutable(ctx context.Context) (*exec.Cmd, context.CancelFunc) { + cmdOutput := make(chan string) + + // Run awm relayer binary with config path + var relayerContext context.Context + relayerContext, relayerCancel := context.WithCancel(ctx) + relayerCmd := exec.CommandContext(relayerContext, "./build/awm-relayer", "--config-file", relayerConfigPath) + + // Set up a pipe to capture the command's output + cmdReader, _ := relayerCmd.StdoutPipe() + + // Start the command + err := relayerCmd.Start() + gomega.Expect(err).Should(gomega.BeNil()) + + // Start a goroutine to read and output the command's stdout + go func() { + scanner := bufio.NewScanner(cmdReader) + for scanner.Scan() { + log.Info(scanner.Text()) + } + cmdOutput <- "Command execution finished" + }() + return relayerCmd, relayerCancel +} + func httpToWebsocketURI(uri string, blockchainID string) string { return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) } From e05ecc4345b44bfa47acb22539a0127533ae737c Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Fri, 15 Sep 2023 21:06:32 +0000 Subject: [PATCH 41/56] linter --- tests/e2e_test.go | 6 +++++- tests/utils.go | 2 -- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/e2e_test.go b/tests/e2e_test.go index 7a468ca3..2b536520 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -253,10 +253,12 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) baseFeeA, err := chainARPCClient.EstimateBaseFee(context.Background()) + gomega.Expect(err).Should(gomega.BeNil()) gasFeeCapA := baseFeeA.Mul(baseFeeA, big.NewInt(relayerEvm.BaseFeeFactor)) gasFeeCapA.Add(gasFeeCapA, big.NewInt(relayerEvm.MaxPriorityFeePerGas)) baseFeeB, err := chainBRPCClient.EstimateBaseFee(context.Background()) + gomega.Expect(err).Should(gomega.BeNil()) gasFeeCapB := baseFeeB.Mul(baseFeeB, big.NewInt(relayerEvm.BaseFeeFactor)) gasFeeCapB.Add(gasFeeCapB, big.NewInt(relayerEvm.MaxPriorityFeePerGas)) @@ -306,6 +308,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { // Deploy Teleporter on the two subnets { rpcClient, err := rpc.DialContext(ctx, chainARPCURI) + gomega.Expect(err).Should(gomega.BeNil()) err = rpcClient.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(teleporterDeployerTransaction)) gomega.Expect(err).Should(gomega.BeNil()) time.Sleep(5 * time.Second) @@ -315,6 +318,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { } { rpcClient, err := rpc.DialContext(ctx, chainBRPCURI) + gomega.Expect(err).Should(gomega.BeNil()) err = rpcClient.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(teleporterDeployerTransaction)) gomega.Expect(err).Should(gomega.BeNil()) time.Sleep(5 * time.Second) @@ -415,6 +419,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { log.Info("Packing teleporter message", "nonceA", nonceA, "nonceB", nonceB) payload, err = teleporter.PackTeleporterMessage(common.Hash(blockchainIDB), teleporterMessage) + gomega.Expect(err).Should(gomega.BeNil()) data, err := teleporter.EVMTeleporterContractABI.Pack( "sendCrossChainMessage", @@ -566,7 +571,6 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) // Modify the JSON database to force the relayer to re-process old blocks - jsonDB.Put(blockchainIDA, []byte(database.LatestProcessedBlockKey), []byte("0")) jsonDB.Put(blockchainIDB, []byte(database.LatestProcessedBlockKey), []byte("0")) diff --git a/tests/utils.go b/tests/utils.go index e7c1a15f..5cdfc3d9 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/params" - "github.com/ava-labs/subnet-evm/x/warp" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/onsi/gomega" @@ -28,7 +27,6 @@ var ( defaultTeleporterMessageGasFeeCap = big.NewInt(225 * params.GWei) defaultTeleporterMessageGasTipCap = big.NewInt(params.GWei) defaultTeleporterMessageValue = common.Big0 - warpPrecompileAddress = warp.Module.Address ) // Teleporter contract sendCrossChainMessage input type From b81ae8ccfb9a4171df42863b014476d364ebb11a Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Tue, 19 Sep 2023 15:58:21 +0000 Subject: [PATCH 42/56] remove commented out code --- tests/e2e_test.go | 55 ----------------------------------------------- 1 file changed, 55 deletions(-) diff --git a/tests/e2e_test.go b/tests/e2e_test.go index 2b536520..0f813a83 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -495,61 +495,6 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { gomega.Expect(err).Should(gomega.BeNil()) gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) - // // Try sending the same Teleporter message again. This should fail to be delivered - // { - // // Kill the relayer, then reset the warden db - // relayerCancel() - // _ = relayerCmd.Wait() - - // // Run awm relayer binary with config path - // var relayerContext context.Context - // relayerContext, relayerCancel = context.WithCancel(ctx) - // relayerCmd := exec.CommandContext(relayerContext, "./build/awm-relayer", "--config-file", relayerConfigPath) - - // // Set up a pipe to capture the command's output - // cmdReader, _ := relayerCmd.StdoutPipe() - - // // Start the command - // err := relayerCmd.Start() - // gomega.Expect(err).Should(gomega.BeNil()) - - // // Start a goroutine to read and output the command's stdout - // go func() { - // scanner := bufio.NewScanner(cmdReader) - // for scanner.Scan() { - // log.Info(scanner.Text()) - // } - // cmdOutput <- "Command execution finished" - // }() - // } - // { - // data, err := teleporter.EVMTeleporterContractABI.Pack( - // "sendCrossChainMessage", - // TeleporterMessageInput{ - // DestinationChainID: blockchainIDB, - // DestinationAddress: fundedAddress, - // FeeInfo: FeeInfo{ - // ContractAddress: fundedAddress, - // Amount: big.NewInt(0), - // }, - // RequiredGasLimit: big.NewInt(1_000_000), - // AllowedRelayerAddresses: []common.Address{}, - // Message: []byte{}, - // }, - // ) - // tx := newTestTeleporterMessage(chainAIDInt, teleporterContractAddress, nonceA+1, data) - // txSigner := types.LatestSignerForChainID(chainAIDInt) - // signedTx, err := types.SignTx(tx, txSigner, fundedKey) - // gomega.Expect(err).Should(gomega.BeNil()) - - // log.Info("Resending sendWarpMessage transaction", "destinationChainID", blockchainIDB, "txHash", signedTx.Hash()) - // err = chainARPCClient.SendTransaction(ctx, signedTx) - // gomega.Expect(err).Should(gomega.BeNil()) - - // // We should not receive a new block on subnet B, since the relayer should have seen the Teleporter message was already delivered - // gomega.Consistently(newHeadsB, 10*time.Second, 500*time.Millisecond).ShouldNot(gomega.Receive()) - // } - log.Info("Finished sending warp message, closing down output channel") // Cancel the command and stop the relayer From f8cbae6de2f7f7d614dbe2ad9fab19600c39836b Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Tue, 19 Sep 2023 19:51:08 +0000 Subject: [PATCH 43/56] rename SanitizeHexString --- config/config.go | 6 +++--- config/config_test.go | 16 ++++++++-------- tests/utils.go | 4 ++-- utils/utils.go | 14 +++++++------- utils/utils_test.go | 4 ++-- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/config/config.go b/config/config.go index af4be165..783e11be 100644 --- a/config/config.go +++ b/config/config.go @@ -119,7 +119,7 @@ func BuildConfig(v *viper.Viper) (Config, bool, error) { if accountPrivateKey != "" { optionOverwritten = true for i := range cfg.DestinationSubnets { - cfg.DestinationSubnets[i].AccountPrivateKey = utils.SanitizeHashString(accountPrivateKey) + cfg.DestinationSubnets[i].AccountPrivateKey = utils.SanitizeHexString(accountPrivateKey) } } else { // Otherwise, check for private keys suffixed with the chain ID and set it for that subnet @@ -128,9 +128,9 @@ func BuildConfig(v *viper.Viper) (Config, bool, error) { subnetAccountPrivateKey := os.Getenv(fmt.Sprintf("%s_%s", accountPrivateKeyEnvVarName, subnet.ChainID)) if subnetAccountPrivateKey != "" { optionOverwritten = true - cfg.DestinationSubnets[i].AccountPrivateKey = utils.SanitizeHashString(subnetAccountPrivateKey) + cfg.DestinationSubnets[i].AccountPrivateKey = utils.SanitizeHexString(subnetAccountPrivateKey) } else { - cfg.DestinationSubnets[i].AccountPrivateKey = utils.SanitizeHashString(cfg.DestinationSubnets[i].AccountPrivateKey) + cfg.DestinationSubnets[i].AccountPrivateKey = utils.SanitizeHexString(cfg.DestinationSubnets[i].AccountPrivateKey) } } } diff --git a/config/config_test.go b/config/config_test.go index ad26118e..f124d3c3 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -302,8 +302,8 @@ func TestGetRelayerAccountPrivateKey_set_pk_in_config(t *testing.T) { resultVerifier: func(c Config) bool { // All destination subnets should have the default private key for i, subnet := range c.DestinationSubnets { - if subnet.AccountPrivateKey != utils.SanitizeHashString(testValidConfig.DestinationSubnets[i].AccountPrivateKey) { - fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHashString(testValidConfig.DestinationSubnets[i].AccountPrivateKey), subnet.AccountPrivateKey) + if subnet.AccountPrivateKey != utils.SanitizeHexString(testValidConfig.DestinationSubnets[i].AccountPrivateKey) { + fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHexString(testValidConfig.DestinationSubnets[i].AccountPrivateKey), subnet.AccountPrivateKey) return false } } @@ -332,12 +332,12 @@ func TestGetRelayerAccountPrivateKey_set_pk_with_subnet_env(t *testing.T) { expectedOverwritten: true, resultVerifier: func(c Config) bool { // All destination subnets should have testPk1 - if c.DestinationSubnets[0].AccountPrivateKey != utils.SanitizeHashString(testPk2) { - fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHashString(testPk2), c.DestinationSubnets[0].AccountPrivateKey) + if c.DestinationSubnets[0].AccountPrivateKey != utils.SanitizeHexString(testPk2) { + fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHexString(testPk2), c.DestinationSubnets[0].AccountPrivateKey) return false } - if c.DestinationSubnets[1].AccountPrivateKey != utils.SanitizeHashString(testPk1) { - fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHashString(testPk1), c.DestinationSubnets[1].AccountPrivateKey) + if c.DestinationSubnets[1].AccountPrivateKey != utils.SanitizeHexString(testPk1) { + fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHexString(testPk1), c.DestinationSubnets[1].AccountPrivateKey) return false } return true @@ -364,8 +364,8 @@ func TestGetRelayerAccountPrivateKey_set_pk_with_global_env(t *testing.T) { resultVerifier: func(c Config) bool { // All destination subnets should have testPk2 for _, subnet := range c.DestinationSubnets { - if subnet.AccountPrivateKey != utils.SanitizeHashString(testPk2) { - fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHashString(testPk2), subnet.AccountPrivateKey) + if subnet.AccountPrivateKey != utils.SanitizeHexString(testPk2) { + fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHexString(testPk2), subnet.AccountPrivateKey) return false } } diff --git a/tests/utils.go b/tests/utils.go index 5cdfc3d9..a576199c 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -15,6 +15,7 @@ import ( "strings" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/awm-relayer/utils" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/params" "github.com/ethereum/go-ethereum/common" @@ -118,8 +119,7 @@ func newTestTeleporterMessage(chainIDInt *big.Int, teleporterAddress common.Addr func readHexTextFile(filename string) []byte { fileData, err := os.ReadFile(filename) gomega.Expect(err).Should(gomega.BeNil()) - hexString := string(fileData) - hexString = hexString[2:] // remove 0x prefix + hexString := utils.SanitizeHexString(string(fileData)) data, err := hex.DecodeString(hexString) gomega.Expect(err).Should(gomega.BeNil()) return data diff --git a/utils/utils.go b/utils/utils.go index 59dc31ba..0f41b0dc 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -87,15 +87,15 @@ func ConvertProtocol(URLString, protocol string) (string, error) { return u.String(), nil } -// SanitizeHashString removes the "0x" prefix from a hex hash string if it exists. +// SanitizeHexString removes the "0x" prefix from a hex string if it exists. // Otherwise, returns the original string. -func SanitizeHashString(hash string) string { - if len(hash)%2 != 0 || len(hash) < 2 { - return hash +func SanitizeHexString(hex string) string { + if len(hex)%2 != 0 || len(hex) < 2 { + return hex } - if hash[:2] == "0x" { - return hash[2:] + if hex[:2] == "0x" { + return hex[2:] } - return hash + return hex } diff --git a/utils/utils_test.go b/utils/utils_test.go index 9b3a9156..e066d366 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -58,7 +58,7 @@ func TestConvertProtocol(t *testing.T) { } } -func TestSanitizeHashString(t *testing.T) { +func TestSanitizeHexString(t *testing.T) { testCases := []struct { hash string expectedResult string @@ -80,7 +80,7 @@ func TestSanitizeHashString(t *testing.T) { }, } for i, testCase := range testCases { - actualResult := SanitizeHashString(testCase.hash) + actualResult := SanitizeHexString(testCase.hash) if actualResult != testCase.expectedResult { t.Errorf("test case %d had unexpected result. Actual: %s, Expected: %s", i, actualResult, testCase.expectedResult) } From 7a9985a491ca8c7dff695bc22ab1c990da8d617b Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Tue, 19 Sep 2023 19:54:57 +0000 Subject: [PATCH 44/56] dot import gomega --- tests/e2e_test.go | 162 +++++++++++++++++++++++----------------------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/tests/e2e_test.go b/tests/e2e_test.go index 0f813a83..2e515ce1 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -37,7 +37,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/onsi/ginkgo/v2" - "github.com/onsi/gomega" + . "github.com/onsi/gomega" ) const ( @@ -69,7 +69,7 @@ func TestE2E(t *testing.T) { t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") } - gomega.RegisterFailHandler(ginkgo.Fail) + RegisterFailHandler(ginkgo.Fail) ginkgo.RunSpecs(t, "Relayer e2e test") } @@ -93,18 +93,18 @@ var _ = ginkgo.BeforeSuite(func() { } } f, err := os.CreateTemp(os.TempDir(), "config.json") - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) _, err = f.Write([]byte(`{"warp-api-enabled": true}`)) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) warpChainConfigPath = f.Name() // Make sure that the warp genesis file exists _, err = os.Stat(warpGenesisFile) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) // Construct the network using the avalanche-network-runner _, err = manager.StartDefaultNetwork(ctx) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) err = manager.SetupNetwork( ctx, anrConfig.AvalancheGoExecPath, @@ -129,35 +129,35 @@ var _ = ginkgo.BeforeSuite(func() { }, }, ) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) // Issue transactions to activate the proposerVM fork on the receiving chain fundedKey, err := crypto.HexToECDSA(fundedKeyStr) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) subnetB := manager.GetSubnets()[1] subnetBDetails, ok := manager.GetSubnet(subnetB) - gomega.Expect(ok).Should(gomega.BeTrue()) + Expect(ok).Should(BeTrue()) chainBID := subnetBDetails.BlockchainID uri := httpToWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) client, err := ethclient.Dial(uri) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) chainBIDInt, err := client.ChainID(ctx) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) err = utils.IssueTxsToActivateProposerVMFork(ctx, chainBIDInt, fundedKey, client) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) log.Info("Set up ginkgo before suite") }) var _ = ginkgo.AfterSuite(func() { log.Info("Running ginkgo after suite") - gomega.Expect(manager).ShouldNot(gomega.BeNil()) - gomega.Expect(manager.TeardownNetwork()).Should(gomega.BeNil()) - gomega.Expect(os.Remove(warpChainConfigPath)).Should(gomega.BeNil()) - gomega.Expect(os.Remove(relayerConfigPath)).Should(gomega.BeNil()) + Expect(manager).ShouldNot(BeNil()) + Expect(manager.TeardownNetwork()).Should(BeNil()) + Expect(os.Remove(warpChainConfigPath)).Should(BeNil()) + Expect(os.Remove(relayerConfigPath)).Should(BeNil()) }) // Ginkgo describe node that acts as a container for the relayer e2e tests. This test suite @@ -192,19 +192,19 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { ginkgo.It("Setup subnet URIs", ginkgo.Label("Relayer", "Setup"), func() { subnetIDs = manager.GetSubnets() - gomega.Expect(len(subnetIDs)).Should(gomega.Equal(2)) + Expect(len(subnetIDs)).Should(Equal(2)) subnetA = subnetIDs[0] subnetADetails, ok := manager.GetSubnet(subnetA) - gomega.Expect(ok).Should(gomega.BeTrue()) - gomega.Expect(len(subnetADetails.ValidatorURIs)).Should(gomega.Equal(5)) + Expect(ok).Should(BeTrue()) + Expect(len(subnetADetails.ValidatorURIs)).Should(Equal(5)) blockchainIDA = subnetADetails.BlockchainID chainANodeURIs = append(chainANodeURIs, subnetADetails.ValidatorURIs...) subnetB = subnetIDs[1] subnetBDetails, ok := manager.GetSubnet(subnetB) - gomega.Expect(ok).Should(gomega.BeTrue()) - gomega.Expect(len(subnetBDetails.ValidatorURIs)).Should(gomega.Equal(5)) + Expect(ok).Should(BeTrue()) + Expect(len(subnetBDetails.ValidatorURIs)).Should(Equal(5)) blockchainIDB = subnetBDetails.BlockchainID chainBNodeURIs = append(chainBNodeURIs, subnetBDetails.ValidatorURIs...) @@ -214,21 +214,21 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { chainARPCURI = httpToRPCURI(chainANodeURIs[0], blockchainIDA.String()) log.Info("Creating ethclient for blockchainA", "wsURI", chainAWSURI, "rpcURL, chainARPCURI") chainARPCClient, err = ethclient.Dial(chainARPCURI) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) chainAIDInt, err = chainARPCClient.ChainID(context.Background()) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) chainBWSURI := httpToWebsocketURI(chainBNodeURIs[0], blockchainIDB.String()) chainBRPCURI = httpToRPCURI(chainBNodeURIs[0], blockchainIDB.String()) log.Info("Creating ethclient for blockchainB", "wsURI", chainBWSURI) chainBWSClient, err = ethclient.Dial(chainBWSURI) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) chainBRPCClient, err = ethclient.Dial(chainBRPCURI) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) chainBIDInt, err = chainBRPCClient.ChainID(context.Background()) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) log.Info("Finished setting up e2e test subnet variables") }) @@ -242,23 +242,23 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { teleporterDeployerTransaction := readHexTextFile("./tests/UniversalTeleporterDeployerTransaction.txt") nonceA, err := chainARPCClient.NonceAt(ctx, fundedAddress, nil) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) nonceB, err := chainBRPCClient.NonceAt(ctx, fundedAddress, nil) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) gasTipCapA, err := chainARPCClient.SuggestGasTipCap(context.Background()) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) gasTipCapB, err := chainBRPCClient.SuggestGasTipCap(context.Background()) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) baseFeeA, err := chainARPCClient.EstimateBaseFee(context.Background()) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) gasFeeCapA := baseFeeA.Mul(baseFeeA, big.NewInt(relayerEvm.BaseFeeFactor)) gasFeeCapA.Add(gasFeeCapA, big.NewInt(relayerEvm.MaxPriorityFeePerGas)) baseFeeB, err := chainBRPCClient.EstimateBaseFee(context.Background()) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) gasFeeCapB := baseFeeB.Mul(baseFeeB, big.NewInt(relayerEvm.BaseFeeFactor)) gasFeeCapB.Add(gasFeeCapB, big.NewInt(relayerEvm.MaxPriorityFeePerGas)) @@ -276,13 +276,13 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { }) txSignerA := types.LatestSignerForChainID(chainAIDInt) triggerTxA, err := types.SignTx(txA, txSignerA, fundedKey) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) err = chainARPCClient.SendTransaction(ctx, triggerTxA) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) time.Sleep(5 * time.Second) receipt, err := chainARPCClient.TransactionReceipt(ctx, triggerTxA.Hash()) - gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + Expect(err).Should(BeNil()) + Expect(receipt.Status).Should(Equal(types.ReceiptStatusSuccessful)) } { value := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) // 10eth @@ -297,43 +297,43 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { }) txSignerB := types.LatestSignerForChainID(chainBIDInt) triggerTxB, err := types.SignTx(txB, txSignerB, fundedKey) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) err = chainBRPCClient.SendTransaction(ctx, triggerTxB) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) time.Sleep(5 * time.Second) receipt, err := chainBRPCClient.TransactionReceipt(ctx, triggerTxB.Hash()) - gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + Expect(err).Should(BeNil()) + Expect(receipt.Status).Should(Equal(types.ReceiptStatusSuccessful)) } // Deploy Teleporter on the two subnets { rpcClient, err := rpc.DialContext(ctx, chainARPCURI) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) err = rpcClient.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(teleporterDeployerTransaction)) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) time.Sleep(5 * time.Second) teleporterCode, err := chainARPCClient.CodeAt(ctx, teleporterContractAddress, nil) - gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(len(teleporterCode)).Should(gomega.BeNumerically(">", 2)) // 0x is an EOA, contract returns the bytecode + Expect(err).Should(BeNil()) + Expect(len(teleporterCode)).Should(BeNumerically(">", 2)) // 0x is an EOA, contract returns the bytecode } { rpcClient, err := rpc.DialContext(ctx, chainBRPCURI) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) err = rpcClient.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(teleporterDeployerTransaction)) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) time.Sleep(5 * time.Second) teleporterCode, err := chainBRPCClient.CodeAt(ctx, teleporterContractAddress, nil) - gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(len(teleporterCode)).Should(gomega.BeNumerically(">", 2)) // 0x is an EOA, contract returns the bytecode + Expect(err).Should(BeNil()) + Expect(len(teleporterCode)).Should(BeNumerically(">", 2)) // 0x is an EOA, contract returns the bytecode } }) ginkgo.It("Set up relayer config", ginkgo.Label("Relayer", "Setup Relayer"), func() { hostA, portA, err := getURIHostAndPort(chainANodeURIs[0]) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) hostB, portB, err := getURIHostAndPort(chainBNodeURIs[0]) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) log.Info( "Setting up relayer config", @@ -385,13 +385,13 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { } data, err := json.MarshalIndent(relayerConfig, "", "\t") - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) f, err := os.CreateTemp(os.TempDir(), "relayer-config.json") - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) _, err = f.Write(data) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) relayerConfigPath = f.Name() log.Info("Created awm-relayer config", "configPath", relayerConfigPath, "config", string(data)) @@ -402,7 +402,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { cmd := exec.Command("./scripts/build.sh") out, err := cmd.CombinedOutput() fmt.Println(string(out)) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) }) // Send a transaction to Subnet A to issue a Warp Message from the Teleporter contract to Subnet B @@ -412,14 +412,14 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { relayerCmd, relayerCancel = runRelayerExecutable(ctx) nonceA, err := chainARPCClient.NonceAt(ctx, fundedAddress, nil) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) nonceB, err := chainBRPCClient.NonceAt(ctx, fundedAddress, nil) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) log.Info("Packing teleporter message", "nonceA", nonceA, "nonceB", nonceB) payload, err = teleporter.PackTeleporterMessage(common.Hash(blockchainIDB), teleporterMessage) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) data, err := teleporter.EVMTeleporterContractABI.Pack( "sendCrossChainMessage", @@ -435,14 +435,14 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { Message: []byte{1, 2, 3, 4}, }, ) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) // Send a transaction to the Teleporter contract tx := newTestTeleporterMessage(chainAIDInt, teleporterContractAddress, nonceA, data) txSigner := types.LatestSignerForChainID(chainAIDInt) signedTx, err := types.SignTx(tx, txSigner, fundedKey) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) // Sleep for some time to make sure relayer has started up and subscribed. time.Sleep(15 * time.Second) @@ -450,17 +450,17 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { newHeadsB := make(chan *types.Header, 10) sub, err := chainBWSClient.SubscribeNewHead(ctx, newHeadsB) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) defer sub.Unsubscribe() log.Info("Sending sendWarpMessage transaction", "destinationChainID", blockchainIDB, "txHash", signedTx.Hash()) err = chainARPCClient.SendTransaction(ctx, signedTx) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) time.Sleep(5 * time.Second) receipt, err := chainARPCClient.TransactionReceipt(ctx, signedTx.Hash()) - gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + Expect(err).Should(BeNil()) + Expect(receipt.Status).Should(Equal(types.ReceiptStatusSuccessful)) // Get the latest block from Subnet B log.Info("Waiting for new block confirmation") @@ -468,7 +468,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { log.Info("Received new head", "height", newHead.Number.Uint64()) blockHash := newHead.Hash() block, err := chainBRPCClient.BlockByHash(ctx, blockHash) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) log.Info( "Got block", "blockHash", blockHash, @@ -478,22 +478,22 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { "block", block, ) accessLists := block.Transactions()[0].AccessList() - gomega.Expect(len(accessLists)).Should(gomega.Equal(1)) - gomega.Expect(accessLists[0].Address).Should(gomega.Equal(warp.Module.Address)) + Expect(len(accessLists)).Should(Equal(1)) + Expect(accessLists[0].Address).Should(Equal(warp.Module.Address)) // Check the transaction storage key has warp message we're expecting storageKeyHashes := accessLists[0].StorageKeys packedPredicate := predicateutils.HashSliceToBytes(storageKeyHashes) predicateBytes, err := predicateutils.UnpackPredicate(packedPredicate) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) receivedWarpMessage, err = avalancheWarp.ParseMessage(predicateBytes) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) // Check that the transaction has successful receipt status txHash := block.Transactions()[0].Hash() receipt, err = chainBRPCClient.TransactionReceipt(ctx, txHash) - gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(receipt.Status).Should(gomega.Equal(types.ReceiptStatusSuccessful)) + Expect(err).Should(BeNil()) + Expect(receipt.Status).Should(Equal(types.ReceiptStatusSuccessful)) log.Info("Finished sending warp message, closing down output channel") @@ -513,7 +513,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { ), ) jsonDB, err := database.NewJSONFileStorage(logger, storageLocation, []ids.ID{blockchainIDA, blockchainIDB}) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) // Modify the JSON database to force the relayer to re-process old blocks jsonDB.Put(blockchainIDA, []byte(database.LatestProcessedBlockKey), []byte("0")) @@ -522,14 +522,14 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { // Subscribe to the destination chain block published newHeadsB := make(chan *types.Header, 10) sub, err := chainBWSClient.SubscribeNewHead(ctx, newHeadsB) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) defer sub.Unsubscribe() // Run the relayer relayerCmd, relayerCancel = runRelayerExecutable(ctx) // We should not receive a new block on subnet B, since the relayer should have seen the Teleporter message was already delivered - gomega.Consistently(newHeadsB, 10*time.Second, 500*time.Millisecond).ShouldNot(gomega.Receive()) + Consistently(newHeadsB, 10*time.Second, 500*time.Millisecond).ShouldNot(Receive()) // Cancel the command and stop the relayer relayerCancel() @@ -537,19 +537,19 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { }) ginkgo.It("Validate Received Warp Message Values", ginkgo.Label("Relaery", "VerifyWarp"), func() { - gomega.Expect(receivedWarpMessage.SourceChainID).Should(gomega.Equal(blockchainIDA)) + Expect(receivedWarpMessage.SourceChainID).Should(Equal(blockchainIDA)) addressedPayload, err := warpPayload.ParseAddressedPayload(receivedWarpMessage.Payload) - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) receivedDestinationID, err := ids.ToID(addressedPayload.DestinationChainID.Bytes()) - gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(receivedDestinationID).Should(gomega.Equal(blockchainIDB)) - gomega.Expect(addressedPayload.DestinationAddress).Should(gomega.Equal(teleporterContractAddress)) - gomega.Expect(addressedPayload.Payload).Should(gomega.Equal(payload)) + Expect(err).Should(BeNil()) + Expect(receivedDestinationID).Should(Equal(blockchainIDB)) + Expect(addressedPayload.DestinationAddress).Should(Equal(teleporterContractAddress)) + Expect(addressedPayload.Payload).Should(Equal(payload)) // Check that the teleporter message is correct receivedTeleporterMessage, err := teleporter.UnpackTeleporterMessage(addressedPayload.Payload) - gomega.Expect(err).Should(gomega.BeNil()) - gomega.Expect(*receivedTeleporterMessage).Should(gomega.Equal(teleporterMessage)) + Expect(err).Should(BeNil()) + Expect(*receivedTeleporterMessage).Should(Equal(teleporterMessage)) }) }) From f116ba27f8b93dadd701b6763442e3dc276f56df Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 20 Sep 2023 14:19:14 +0000 Subject: [PATCH 45/56] rename PackSendCrossChainMessageEvent --- messages/teleporter/message_test.go | 2 +- messages/teleporter/utils.go | 2 +- tests/e2e_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/messages/teleporter/message_test.go b/messages/teleporter/message_test.go index 38abf1fc..0f5d3e37 100644 --- a/messages/teleporter/message_test.go +++ b/messages/teleporter/message_test.go @@ -36,7 +36,7 @@ func testTeleporterMessage(messageID int64) TeleporterMessage { func TestPackUnpackTeleporterMessage(t *testing.T) { message := testTeleporterMessage(4) - b, err := PackTeleporterMessage(common.HexToHash("0x03"), message) + b, err := PackSendCrossChainMessageEvent(common.HexToHash("0x03"), message) if err != nil { t.Errorf("failed to pack teleporter message: %v", err) t.FailNow() diff --git a/messages/teleporter/utils.go b/messages/teleporter/utils.go index bc3e5081..b3c8a5c1 100644 --- a/messages/teleporter/utils.go +++ b/messages/teleporter/utils.go @@ -51,7 +51,7 @@ func CalculateReceiveMessageGasLimit(numSigners int, executionRequiredGasLimit * // Pack the SendCrossChainMessage event type. PackEvent is documented as not supporting struct types, so this should be used // with caution. Here, we only use it for testing purposes. In a real setting, the Teleporter contract should pack the event. -func PackTeleporterMessage(destinationChainID common.Hash, message TeleporterMessage) ([]byte, error) { +func PackSendCrossChainMessageEvent(destinationChainID common.Hash, message TeleporterMessage) ([]byte, error) { _, hashes, err := EVMTeleporterContractABI.PackEvent("SendCrossChainMessage", destinationChainID, message.MessageID, message) return hashes, err } diff --git a/tests/e2e_test.go b/tests/e2e_test.go index 2e515ce1..7faca1f9 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -418,7 +418,7 @@ var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { Expect(err).Should(BeNil()) log.Info("Packing teleporter message", "nonceA", nonceA, "nonceB", nonceB) - payload, err = teleporter.PackTeleporterMessage(common.Hash(blockchainIDB), teleporterMessage) + payload, err = teleporter.PackSendCrossChainMessageEvent(common.Hash(blockchainIDB), teleporterMessage) Expect(err).Should(BeNil()) data, err := teleporter.EVMTeleporterContractABI.Pack( From 0cca94acf64dbd31b655e079e0bdae5553a5eb82 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 20 Sep 2023 14:44:05 +0000 Subject: [PATCH 46/56] export UnpackMessageReceivedResult --- messages/teleporter/message.go | 2 +- messages/teleporter/message_manager.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/messages/teleporter/message.go b/messages/teleporter/message.go index 57ba1a01..328faaa4 100644 --- a/messages/teleporter/message.go +++ b/messages/teleporter/message.go @@ -73,7 +73,7 @@ func packMessageReceivedMessage(inputStruct MessageReceivedInput) ([]byte, error return EVMTeleporterContractABI.Pack("messageReceived", inputStruct.OriginChainID, inputStruct.MessageID) } -func unpackMessageReceivedResult(result []byte) (bool, error) { +func UnpackMessageReceivedResult(result []byte) (bool, error) { var success bool err := EVMTeleporterContractABI.UnpackIntoInterface(&success, "messageReceived", result) return success, err diff --git a/messages/teleporter/message_manager.go b/messages/teleporter/message_manager.go index 92479990..b76f9278 100644 --- a/messages/teleporter/message_manager.go +++ b/messages/teleporter/message_manager.go @@ -191,7 +191,7 @@ func (m *messageManager) messageDelivered( return false, err } // check the contract call result - delivered, err := unpackMessageReceivedResult(result) + delivered, err := UnpackMessageReceivedResult(result) if err != nil { m.logger.Error( "Failed unpacking messageReceived result.", From f30e222a506aa01e030e9c67e76b96cbca3655ce Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 20 Sep 2023 14:46:16 +0000 Subject: [PATCH 47/56] export all Teleporter packing functions --- messages/teleporter/message.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/messages/teleporter/message.go b/messages/teleporter/message.go index 328faaa4..6d9c8a43 100644 --- a/messages/teleporter/message.go +++ b/messages/teleporter/message.go @@ -65,11 +65,11 @@ func UnpackTeleporterMessage(messageBytes []byte) (*TeleporterMessage, error) { return &teleporterMessage.TeleporterMessage, nil } -func packReceiverMessage(inputStruct ReceiveCrossChainMessageInput) ([]byte, error) { +func PackReceiverMessage(inputStruct ReceiveCrossChainMessageInput) ([]byte, error) { return EVMTeleporterContractABI.Pack("receiveCrossChainMessage", inputStruct.RelayerRewardAddress) } -func packMessageReceivedMessage(inputStruct MessageReceivedInput) ([]byte, error) { +func PackMessageReceivedMessage(inputStruct MessageReceivedInput) ([]byte, error) { return EVMTeleporterContractABI.Pack("messageReceived", inputStruct.OriginChainID, inputStruct.MessageID) } From 34fb8976d19ee487fa1008073323f4cef049e562 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 20 Sep 2023 14:48:03 +0000 Subject: [PATCH 48/56] build fix --- messages/teleporter/message_manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/teleporter/message_manager.go b/messages/teleporter/message_manager.go index b76f9278..006d20a2 100644 --- a/messages/teleporter/message_manager.go +++ b/messages/teleporter/message_manager.go @@ -164,7 +164,7 @@ func (m *messageManager) messageDelivered( return false, errors.New("destination client is not an Ethereum client") } - data, err := packMessageReceivedMessage(MessageReceivedInput{ + data, err := PackMessageReceivedMessage(MessageReceivedInput{ OriginChainID: warpMessageInfo.WarpUnsignedMessage.SourceChainID, MessageID: teleporterMessage.MessageID, }) From b8571020bdaafe3ccbc249be47d1bce0a20ebd55 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 20 Sep 2023 14:52:22 +0000 Subject: [PATCH 49/56] build fix --- messages/teleporter/message_manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/teleporter/message_manager.go b/messages/teleporter/message_manager.go index 006d20a2..6f55abb9 100644 --- a/messages/teleporter/message_manager.go +++ b/messages/teleporter/message_manager.go @@ -253,7 +253,7 @@ func (m *messageManager) SendMessage(signedMessage *warp.Message, parsedVmPayloa return err } // Construct the transaction call data to call the receive cross chain message method of the receiver precompile. - callData, err := packReceiverMessage(ReceiveCrossChainMessageInput{ + callData, err := PackReceiverMessage(ReceiveCrossChainMessageInput{ RelayerRewardAddress: common.HexToAddress(m.messageConfig.RewardAddress), }) if err != nil { From 26addbd4010b856569780211b1a4eacd3e53697b Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 20 Sep 2023 17:03:38 +0000 Subject: [PATCH 50/56] clean up testing jobs --- .github/workflows/e2e.yml | 44 ++++++++++++++++++++++++++++++++++++++ .github/workflows/test.yml | 38 +------------------------------- 2 files changed, 45 insertions(+), 37 deletions(-) create mode 100644 .github/workflows/e2e.yml diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 00000000..c55b15f0 --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,44 @@ +# Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +# See the file LICENSE for licensing terms. + +name: E2E Tests + +on: + push: + branches: + - main + pull_request: + branches: + - "*" + +env: + GO_VERSION: "1.20.7" + +jobs: + e2e_tests: + name: e2e_tests + runs-on: ubuntu-20.04 + + steps: + - name: Checkout subnet-evm repository + uses: actions/checkout@v4 + with: + repository: ava-labs/subnet-evm + ref: v0.5.4 + + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install AvalancheGo Release + run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh + + - name: Build Subnet-EVM Plugin Binary + run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy + + - name: Checkout awm-relayer repository + uses: actions/checkout@v4 + + - name: Run E2E Tests + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 92cd9a83..bd173d87 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,10 +6,7 @@ name: Tests on: push: branches: - - main - pull_request: - branches: - - "*" + - '*' env: GO_VERSION: "1.20.7" @@ -28,38 +25,5 @@ jobs: - name: Checkout awm-relayer repository uses: actions/checkout@v4 - - name: Build Relayer - run: | - go mod tidy - ./scripts/build.sh - - name: Run Relayer Unit Tests run: ./scripts/test.sh - - e2e_tests: - runs-on: ubuntu-20.04 - name: e2e_tests - - steps: - - name: Checkout subnet-evm repository - uses: actions/checkout@v4 - with: - repository: ava-labs/subnet-evm - ref: v0.5.4 - - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: ${{ env.GO_VERSION }} - - - name: Install AvalancheGo Release - run: BASEDIR=/tmp/e2e-test AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego ./scripts/install_avalanchego_release.sh - - - name: Build Subnet-EVM Plugin Binary - run: ./scripts/build.sh /tmp/e2e-test/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy - - - name: Checkout awm-relayer repository - uses: actions/checkout@v4 - - - name: Run E2E Tests - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh From 051e4829d99637552afd1fc3e63176031401795a Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 20 Sep 2023 17:07:36 +0000 Subject: [PATCH 51/56] rename unit test job --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bd173d87..6c7069f5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,8 +12,8 @@ env: GO_VERSION: "1.20.7" jobs: - build-test-relayer: - name: Build + Unit tests + test_relayer: + name: Unit tests runs-on: ubuntu-20.04 steps: From 80ab00545b99d7e854e4e87e8e328b9f9972f377 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 20 Sep 2023 18:39:43 +0000 Subject: [PATCH 52/56] move subnet uri and teleporter deploy to BeforeSuite --- tests/e2e_test.go | 311 +++++++++++++++++++++------------------------- tests/utils.go | 40 ++++-- 2 files changed, 171 insertions(+), 180 deletions(-) diff --git a/tests/e2e_test.go b/tests/e2e_test.go index 7faca1f9..0ca7699d 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -27,13 +27,11 @@ import ( "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/ethclient" "github.com/ava-labs/subnet-evm/plugin/evm" - "github.com/ava-labs/subnet-evm/tests/utils" "github.com/ava-labs/subnet-evm/tests/utils/runner" predicateutils "github.com/ava-labs/subnet-evm/utils/predicate" warpPayload "github.com/ava-labs/subnet-evm/warp/payload" "github.com/ava-labs/subnet-evm/x/warp" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/onsi/ginkgo/v2" @@ -61,7 +59,16 @@ var ( Receipts: []teleporter.TeleporterMessageReceipt{}, Message: []byte{1, 2, 3, 4}, } - storageLocation = fmt.Sprintf("%s/.awm-relayer-storage", os.TempDir()) + storageLocation = fmt.Sprintf("%s/.awm-relayer-storage", os.TempDir()) + subnetIDs []ids.ID + subnetA, subnetB ids.ID + fundedKey *ecdsa.PrivateKey + chainBWSClient ethclient.Client + chainARPCClient, chainBRPCClient ethclient.Client + chainARPCURI, chainBRPCURI string + chainAIDInt, chainBIDInt *big.Int + blockchainIDA, blockchainIDB ids.ID + chainANodeURIs, chainBNodeURIs []string ) func TestE2E(t *testing.T) { @@ -132,22 +139,144 @@ var _ = ginkgo.BeforeSuite(func() { Expect(err).Should(BeNil()) // Issue transactions to activate the proposerVM fork on the receiving chain - fundedKey, err := crypto.HexToECDSA(fundedKeyStr) + fundedKey, err = crypto.HexToECDSA(fundedKeyStr) Expect(err).Should(BeNil()) - subnetB := manager.GetSubnets()[1] + setUpProposerVm(ctx, fundedKey, manager, 1) + + // Setup subnet URIs + subnetIDs = manager.GetSubnets() + Expect(len(subnetIDs)).Should(Equal(2)) + + subnetA = subnetIDs[0] + subnetADetails, ok := manager.GetSubnet(subnetA) + Expect(ok).Should(BeTrue()) + Expect(len(subnetADetails.ValidatorURIs)).Should(Equal(5)) + blockchainIDA = subnetADetails.BlockchainID + chainANodeURIs = append(chainANodeURIs, subnetADetails.ValidatorURIs...) + + subnetB = subnetIDs[1] subnetBDetails, ok := manager.GetSubnet(subnetB) Expect(ok).Should(BeTrue()) + Expect(len(subnetBDetails.ValidatorURIs)).Should(Equal(5)) + blockchainIDB = subnetBDetails.BlockchainID + chainBNodeURIs = append(chainBNodeURIs, subnetBDetails.ValidatorURIs...) - chainBID := subnetBDetails.BlockchainID - uri := httpToWebsocketURI(subnetBDetails.ValidatorURIs[0], chainBID.String()) + log.Info("Created URIs for both subnets", "ChainAURIs", chainANodeURIs, "ChainBURIs", chainBNodeURIs, "blockchainIDA", blockchainIDA, "blockchainIDB", blockchainIDB) + log.Info("subnet ID", "subnetA", subnetADetails.SubnetID, "subnetB", subnetBDetails.SubnetID) - client, err := ethclient.Dial(uri) + chainAWSURI := httpToWebsocketURI(chainANodeURIs[0], blockchainIDA.String()) + chainARPCURI = httpToRPCURI(chainANodeURIs[0], blockchainIDA.String()) + log.Info("Creating ethclient for blockchainA", "wsURI", chainAWSURI, "rpcURL, chainARPCURI") + chainARPCClient, err = ethclient.Dial(chainARPCURI) Expect(err).Should(BeNil()) - chainBIDInt, err := client.ChainID(ctx) + + chainAIDInt, err = chainARPCClient.ChainID(context.Background()) + Expect(err).Should(BeNil()) + + chainBWSURI := httpToWebsocketURI(chainBNodeURIs[0], blockchainIDB.String()) + chainBRPCURI = httpToRPCURI(chainBNodeURIs[0], blockchainIDB.String()) + log.Info("Creating ethclient for blockchainB", "wsURI", chainBWSURI) + chainBWSClient, err = ethclient.Dial(chainBWSURI) + Expect(err).Should(BeNil()) + chainBRPCClient, err = ethclient.Dial(chainBRPCURI) + Expect(err).Should(BeNil()) + + chainBIDInt, err = chainBRPCClient.ChainID(context.Background()) + Expect(err).Should(BeNil()) + log.Info("Finished setting up e2e test subnet variables") + + log.Info("Deploying Teleporter contract to subnets") + // Read in the Teleporter contract information + teleporterContractAddress = common.HexToAddress(readHexTextFile("./tests/UniversalTeleporterMessengerContractAddress.txt")) + teleporterDeployerAddress := common.HexToAddress(readHexTextFile("./tests/UniversalTeleporterDeployerAddress.txt")) + teleporterDeployerTransaction := readHexTextFile("./tests/UniversalTeleporterDeployerTransaction.txt") + + nonceA, err := chainARPCClient.NonceAt(ctx, fundedAddress, nil) + Expect(err).Should(BeNil()) + + nonceB, err := chainBRPCClient.NonceAt(ctx, fundedAddress, nil) + Expect(err).Should(BeNil()) + + gasTipCapA, err := chainARPCClient.SuggestGasTipCap(context.Background()) + Expect(err).Should(BeNil()) + gasTipCapB, err := chainBRPCClient.SuggestGasTipCap(context.Background()) + Expect(err).Should(BeNil()) + + baseFeeA, err := chainARPCClient.EstimateBaseFee(context.Background()) Expect(err).Should(BeNil()) + gasFeeCapA := baseFeeA.Mul(baseFeeA, big.NewInt(relayerEvm.BaseFeeFactor)) + gasFeeCapA.Add(gasFeeCapA, big.NewInt(relayerEvm.MaxPriorityFeePerGas)) - err = utils.IssueTxsToActivateProposerVMFork(ctx, chainBIDInt, fundedKey, client) + baseFeeB, err := chainBRPCClient.EstimateBaseFee(context.Background()) Expect(err).Should(BeNil()) + gasFeeCapB := baseFeeB.Mul(baseFeeB, big.NewInt(relayerEvm.BaseFeeFactor)) + gasFeeCapB.Add(gasFeeCapB, big.NewInt(relayerEvm.MaxPriorityFeePerGas)) + + // Fund the deployer address + { + value := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) // 10eth + txA := types.NewTx(&types.DynamicFeeTx{ + ChainID: chainAIDInt, + Nonce: nonceA, + To: &teleporterDeployerAddress, + Gas: defaultTeleporterMessageGas, + GasFeeCap: gasFeeCapA, + GasTipCap: gasTipCapA, + Value: value, + }) + txSignerA := types.LatestSignerForChainID(chainAIDInt) + triggerTxA, err := types.SignTx(txA, txSignerA, fundedKey) + Expect(err).Should(BeNil()) + err = chainARPCClient.SendTransaction(ctx, triggerTxA) + Expect(err).Should(BeNil()) + time.Sleep(5 * time.Second) + receipt, err := chainARPCClient.TransactionReceipt(ctx, triggerTxA.Hash()) + Expect(err).Should(BeNil()) + Expect(receipt.Status).Should(Equal(types.ReceiptStatusSuccessful)) + } + { + value := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) // 10eth + txB := types.NewTx(&types.DynamicFeeTx{ + ChainID: chainBIDInt, + Nonce: nonceB, + To: &teleporterDeployerAddress, + Gas: defaultTeleporterMessageGas, + GasFeeCap: gasFeeCapB, + GasTipCap: gasTipCapB, + Value: value, + }) + txSignerB := types.LatestSignerForChainID(chainBIDInt) + triggerTxB, err := types.SignTx(txB, txSignerB, fundedKey) + Expect(err).Should(BeNil()) + err = chainBRPCClient.SendTransaction(ctx, triggerTxB) + Expect(err).Should(BeNil()) + time.Sleep(5 * time.Second) + receipt, err := chainBRPCClient.TransactionReceipt(ctx, triggerTxB.Hash()) + Expect(err).Should(BeNil()) + Expect(receipt.Status).Should(Equal(types.ReceiptStatusSuccessful)) + } + // Deploy Teleporter on the two subnets + { + rpcClient, err := rpc.DialContext(ctx, chainARPCURI) + Expect(err).Should(BeNil()) + err = rpcClient.CallContext(ctx, nil, "eth_sendRawTransaction", teleporterDeployerTransaction) + Expect(err).Should(BeNil()) + time.Sleep(5 * time.Second) + teleporterCode, err := chainARPCClient.CodeAt(ctx, teleporterContractAddress, nil) + Expect(err).Should(BeNil()) + Expect(len(teleporterCode)).Should(BeNumerically(">", 2)) // 0x is an EOA, contract returns the bytecode + } + { + rpcClient, err := rpc.DialContext(ctx, chainBRPCURI) + Expect(err).Should(BeNil()) + err = rpcClient.CallContext(ctx, nil, "eth_sendRawTransaction", teleporterDeployerTransaction) + Expect(err).Should(BeNil()) + time.Sleep(5 * time.Second) + teleporterCode, err := chainBRPCClient.CodeAt(ctx, teleporterContractAddress, nil) + Expect(err).Should(BeNil()) + Expect(len(teleporterCode)).Should(BeNumerically(">", 2)) // 0x is an EOA, contract returns the bytecode + } + log.Info("Finished deploying Teleporter contracts") log.Info("Set up ginkgo before suite") }) @@ -168,166 +297,12 @@ var _ = ginkgo.AfterSuite(func() { // on the destination subnet and verify that the Warp message was received and unpacked correctly. var _ = ginkgo.Describe("[Relayer E2E]", ginkgo.Ordered, func() { var ( - subnetIDs []ids.ID - subnetA, subnetB ids.ID - blockchainIDA, blockchainIDB ids.ID - chainANodeURIs, chainBNodeURIs []string - fundedKey *ecdsa.PrivateKey - err error - receivedWarpMessage *avalancheWarp.Message - chainBWSClient ethclient.Client - chainARPCClient, chainBRPCClient ethclient.Client - chainARPCURI, chainBRPCURI string - chainAIDInt *big.Int - chainBIDInt *big.Int - payload []byte - relayerCmd *exec.Cmd - relayerCancel context.CancelFunc + receivedWarpMessage *avalancheWarp.Message + payload []byte + relayerCmd *exec.Cmd + relayerCancel context.CancelFunc ) - fundedKey, err = crypto.HexToECDSA(fundedKeyStr) - if err != nil { - panic(err) - } - - ginkgo.It("Setup subnet URIs", ginkgo.Label("Relayer", "Setup"), func() { - subnetIDs = manager.GetSubnets() - Expect(len(subnetIDs)).Should(Equal(2)) - - subnetA = subnetIDs[0] - subnetADetails, ok := manager.GetSubnet(subnetA) - Expect(ok).Should(BeTrue()) - Expect(len(subnetADetails.ValidatorURIs)).Should(Equal(5)) - blockchainIDA = subnetADetails.BlockchainID - chainANodeURIs = append(chainANodeURIs, subnetADetails.ValidatorURIs...) - - subnetB = subnetIDs[1] - subnetBDetails, ok := manager.GetSubnet(subnetB) - Expect(ok).Should(BeTrue()) - Expect(len(subnetBDetails.ValidatorURIs)).Should(Equal(5)) - blockchainIDB = subnetBDetails.BlockchainID - chainBNodeURIs = append(chainBNodeURIs, subnetBDetails.ValidatorURIs...) - - log.Info("Created URIs for both subnets", "ChainAURIs", chainANodeURIs, "ChainBURIs", chainBNodeURIs, "blockchainIDA", blockchainIDA, "blockchainIDB", blockchainIDB) - - chainAWSURI := httpToWebsocketURI(chainANodeURIs[0], blockchainIDA.String()) - chainARPCURI = httpToRPCURI(chainANodeURIs[0], blockchainIDA.String()) - log.Info("Creating ethclient for blockchainA", "wsURI", chainAWSURI, "rpcURL, chainARPCURI") - chainARPCClient, err = ethclient.Dial(chainARPCURI) - Expect(err).Should(BeNil()) - - chainAIDInt, err = chainARPCClient.ChainID(context.Background()) - Expect(err).Should(BeNil()) - - chainBWSURI := httpToWebsocketURI(chainBNodeURIs[0], blockchainIDB.String()) - chainBRPCURI = httpToRPCURI(chainBNodeURIs[0], blockchainIDB.String()) - log.Info("Creating ethclient for blockchainB", "wsURI", chainBWSURI) - chainBWSClient, err = ethclient.Dial(chainBWSURI) - Expect(err).Should(BeNil()) - chainBRPCClient, err = ethclient.Dial(chainBRPCURI) - Expect(err).Should(BeNil()) - - chainBIDInt, err = chainBRPCClient.ChainID(context.Background()) - Expect(err).Should(BeNil()) - - log.Info("Finished setting up e2e test subnet variables") - }) - - ginkgo.It("Deploy Teleporter Contract", ginkgo.Label("Relayer", "Deploy Teleporter"), func() { - ctx := context.Background() - - // Read in the Teleporter contract information - teleporterContractAddress = common.BytesToAddress(readHexTextFile("./tests/UniversalTeleporterMessengerContractAddress.txt")) - teleporterDeployerAddress := common.BytesToAddress(readHexTextFile("./tests/UniversalTeleporterDeployerAddress.txt")) - teleporterDeployerTransaction := readHexTextFile("./tests/UniversalTeleporterDeployerTransaction.txt") - - nonceA, err := chainARPCClient.NonceAt(ctx, fundedAddress, nil) - Expect(err).Should(BeNil()) - - nonceB, err := chainBRPCClient.NonceAt(ctx, fundedAddress, nil) - Expect(err).Should(BeNil()) - - gasTipCapA, err := chainARPCClient.SuggestGasTipCap(context.Background()) - Expect(err).Should(BeNil()) - gasTipCapB, err := chainBRPCClient.SuggestGasTipCap(context.Background()) - Expect(err).Should(BeNil()) - - baseFeeA, err := chainARPCClient.EstimateBaseFee(context.Background()) - Expect(err).Should(BeNil()) - gasFeeCapA := baseFeeA.Mul(baseFeeA, big.NewInt(relayerEvm.BaseFeeFactor)) - gasFeeCapA.Add(gasFeeCapA, big.NewInt(relayerEvm.MaxPriorityFeePerGas)) - - baseFeeB, err := chainBRPCClient.EstimateBaseFee(context.Background()) - Expect(err).Should(BeNil()) - gasFeeCapB := baseFeeB.Mul(baseFeeB, big.NewInt(relayerEvm.BaseFeeFactor)) - gasFeeCapB.Add(gasFeeCapB, big.NewInt(relayerEvm.MaxPriorityFeePerGas)) - - // Fund the deployer address - { - value := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) // 10eth - txA := types.NewTx(&types.DynamicFeeTx{ - ChainID: chainAIDInt, - Nonce: nonceA, - To: &teleporterDeployerAddress, - Gas: defaultTeleporterMessageGas, - GasFeeCap: gasFeeCapA, - GasTipCap: gasTipCapA, - Value: value, - }) - txSignerA := types.LatestSignerForChainID(chainAIDInt) - triggerTxA, err := types.SignTx(txA, txSignerA, fundedKey) - Expect(err).Should(BeNil()) - err = chainARPCClient.SendTransaction(ctx, triggerTxA) - Expect(err).Should(BeNil()) - time.Sleep(5 * time.Second) - receipt, err := chainARPCClient.TransactionReceipt(ctx, triggerTxA.Hash()) - Expect(err).Should(BeNil()) - Expect(receipt.Status).Should(Equal(types.ReceiptStatusSuccessful)) - } - { - value := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) // 10eth - txB := types.NewTx(&types.DynamicFeeTx{ - ChainID: chainBIDInt, - Nonce: nonceB, - To: &teleporterDeployerAddress, - Gas: defaultTeleporterMessageGas, - GasFeeCap: gasFeeCapB, - GasTipCap: gasTipCapB, - Value: value, - }) - txSignerB := types.LatestSignerForChainID(chainBIDInt) - triggerTxB, err := types.SignTx(txB, txSignerB, fundedKey) - Expect(err).Should(BeNil()) - err = chainBRPCClient.SendTransaction(ctx, triggerTxB) - Expect(err).Should(BeNil()) - time.Sleep(5 * time.Second) - receipt, err := chainBRPCClient.TransactionReceipt(ctx, triggerTxB.Hash()) - Expect(err).Should(BeNil()) - Expect(receipt.Status).Should(Equal(types.ReceiptStatusSuccessful)) - } - // Deploy Teleporter on the two subnets - { - rpcClient, err := rpc.DialContext(ctx, chainARPCURI) - Expect(err).Should(BeNil()) - err = rpcClient.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(teleporterDeployerTransaction)) - Expect(err).Should(BeNil()) - time.Sleep(5 * time.Second) - teleporterCode, err := chainARPCClient.CodeAt(ctx, teleporterContractAddress, nil) - Expect(err).Should(BeNil()) - Expect(len(teleporterCode)).Should(BeNumerically(">", 2)) // 0x is an EOA, contract returns the bytecode - } - { - rpcClient, err := rpc.DialContext(ctx, chainBRPCURI) - Expect(err).Should(BeNil()) - err = rpcClient.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(teleporterDeployerTransaction)) - Expect(err).Should(BeNil()) - time.Sleep(5 * time.Second) - teleporterCode, err := chainBRPCClient.CodeAt(ctx, teleporterContractAddress, nil) - Expect(err).Should(BeNil()) - Expect(len(teleporterCode)).Should(BeNumerically(">", 2)) // 0x is an EOA, contract returns the bytecode - } - }) - ginkgo.It("Set up relayer config", ginkgo.Label("Relayer", "Setup Relayer"), func() { hostA, portA, err := getURIHostAndPort(chainANodeURIs[0]) Expect(err).Should(BeNil()) diff --git a/tests/utils.go b/tests/utils.go index a576199c..cd60ab3b 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -6,7 +6,7 @@ package tests import ( "bufio" "context" - "encoding/hex" + "crypto/ecdsa" "fmt" "math/big" "os" @@ -15,12 +15,14 @@ import ( "strings" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/awm-relayer/utils" "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/ethclient" "github.com/ava-labs/subnet-evm/params" + "github.com/ava-labs/subnet-evm/tests/utils" + "github.com/ava-labs/subnet-evm/tests/utils/runner" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" - "github.com/onsi/gomega" + . "github.com/onsi/gomega" ) var ( @@ -58,7 +60,7 @@ func runRelayerExecutable(ctx context.Context) (*exec.Cmd, context.CancelFunc) { // Start the command err := relayerCmd.Start() - gomega.Expect(err).Should(gomega.BeNil()) + Expect(err).Should(BeNil()) // Start a goroutine to read and output the command's stdout go func() { @@ -81,7 +83,7 @@ func httpToRPCURI(uri string, blockchainID string) string { func getURIHostAndPort(uri string) (string, uint32, error) { // At a minimum uri should have http:// of 7 characters - gomega.Expect(len(uri)).Should(gomega.BeNumerically(">", 7)) + Expect(len(uri)).Should(BeNumerically(">", 7)) if uri[:7] == "http://" { uri = uri[7:] } else if uri[:8] == "https://" { @@ -92,7 +94,7 @@ func getURIHostAndPort(uri string) (string, uint32, error) { // Split the uri into host and port hostAndPort := strings.Split(uri, ":") - gomega.Expect(len(hostAndPort)).Should(gomega.Equal(2)) + Expect(len(hostAndPort)).Should(Equal(2)) // Parse the port port, err := strconv.ParseUint(hostAndPort[1], 10, 32) @@ -116,11 +118,25 @@ func newTestTeleporterMessage(chainIDInt *big.Int, teleporterAddress common.Addr }) } -func readHexTextFile(filename string) []byte { +func readHexTextFile(filename string) string { fileData, err := os.ReadFile(filename) - gomega.Expect(err).Should(gomega.BeNil()) - hexString := utils.SanitizeHexString(string(fileData)) - data, err := hex.DecodeString(hexString) - gomega.Expect(err).Should(gomega.BeNil()) - return data + Expect(err).Should(BeNil()) + return string(fileData) +} + +func setUpProposerVm(ctx context.Context, fundedKey *ecdsa.PrivateKey, manager *runner.NetworkManager, index int) { + subnet := manager.GetSubnets()[index] + subnetDetails, ok := manager.GetSubnet(subnet) + Expect(ok).Should(BeTrue()) + + chainID := subnetDetails.BlockchainID + uri := httpToWebsocketURI(subnetDetails.ValidatorURIs[0], chainID.String()) + + client, err := ethclient.Dial(uri) + Expect(err).Should(BeNil()) + chainIDInt, err := client.ChainID(ctx) + Expect(err).Should(BeNil()) + + err = utils.IssueTxsToActivateProposerVMFork(ctx, chainIDInt, fundedKey, client) + Expect(err).Should(BeNil()) } From cf97a397337027d5fcbe9cffb21a8e3a6bc7d1fb Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Wed, 20 Sep 2023 22:34:17 +0000 Subject: [PATCH 53/56] unify pack and unpacks, and add docs --- messages/teleporter/message.go | 18 +++++++++++++++--- messages/teleporter/message_manager.go | 4 ++-- messages/teleporter/utils.go | 8 -------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/messages/teleporter/message.go b/messages/teleporter/message.go index 6d9c8a43..5dd80151 100644 --- a/messages/teleporter/message.go +++ b/messages/teleporter/message.go @@ -24,6 +24,8 @@ type TeleporterMessage struct { Message []byte `json:"message"` } +// TeleporterMessageReceipt corresponds to the receipt of a Teleporter message ID +// and the relayer reward address for that message type TeleporterMessageReceipt struct { ReceivedMessageID *big.Int `json:"receivedMessageID"` RelayerRewardAddress common.Address `json:"relayerRewardAddress"` @@ -42,7 +44,7 @@ type MessageReceivedInput struct { MessageID *big.Int `json:"messageID"` } -// unpack Teleporter message bytes according to EVM ABI encoding rules +// UnpackTeleporterMessage unpacks message bytes according to EVM ABI encoding rules into a TeleporterMessage func UnpackTeleporterMessage(messageBytes []byte) (*TeleporterMessage, error) { args := abi.Arguments{ { @@ -65,16 +67,26 @@ func UnpackTeleporterMessage(messageBytes []byte) (*TeleporterMessage, error) { return &teleporterMessage.TeleporterMessage, nil } -func PackReceiverMessage(inputStruct ReceiveCrossChainMessageInput) ([]byte, error) { +// PackReceiveCrossChainMessage packs a ReceiveCrossChainMessageInput to form a call to the receiveCrossChainMessage function +func PackReceiveCrossChainMessage(inputStruct ReceiveCrossChainMessageInput) ([]byte, error) { return EVMTeleporterContractABI.Pack("receiveCrossChainMessage", inputStruct.RelayerRewardAddress) } -func PackMessageReceivedMessage(inputStruct MessageReceivedInput) ([]byte, error) { +// PackMessageReceived packs a MessageReceivedInput to form a call to the messageReceived function +func PackMessageReceived(inputStruct MessageReceivedInput) ([]byte, error) { return EVMTeleporterContractABI.Pack("messageReceived", inputStruct.OriginChainID, inputStruct.MessageID) } +// UnpackMessageReceivedResult attempts to unpack result bytes to a bool indicating whether the message was received func UnpackMessageReceivedResult(result []byte) (bool, error) { var success bool err := EVMTeleporterContractABI.UnpackIntoInterface(&success, "messageReceived", result) return success, err } + +// PackSendCrossChainMessageEvent packs the SendCrossChainMessage event type. PackEvent is documented as not supporting struct types, so this should be used +// with caution. Here, we only use it for testing purposes. In a real setting, the Teleporter contract should pack the event. +func PackSendCrossChainMessageEvent(destinationChainID common.Hash, message TeleporterMessage) ([]byte, error) { + _, hashes, err := EVMTeleporterContractABI.PackEvent("SendCrossChainMessage", destinationChainID, message.MessageID, message) + return hashes, err +} diff --git a/messages/teleporter/message_manager.go b/messages/teleporter/message_manager.go index 6f55abb9..506f23ea 100644 --- a/messages/teleporter/message_manager.go +++ b/messages/teleporter/message_manager.go @@ -164,7 +164,7 @@ func (m *messageManager) messageDelivered( return false, errors.New("destination client is not an Ethereum client") } - data, err := PackMessageReceivedMessage(MessageReceivedInput{ + data, err := PackMessageReceived(MessageReceivedInput{ OriginChainID: warpMessageInfo.WarpUnsignedMessage.SourceChainID, MessageID: teleporterMessage.MessageID, }) @@ -253,7 +253,7 @@ func (m *messageManager) SendMessage(signedMessage *warp.Message, parsedVmPayloa return err } // Construct the transaction call data to call the receive cross chain message method of the receiver precompile. - callData, err := PackReceiverMessage(ReceiveCrossChainMessageInput{ + callData, err := PackReceiveCrossChainMessage(ReceiveCrossChainMessageInput{ RelayerRewardAddress: common.HexToAddress(m.messageConfig.RewardAddress), }) if err != nil { diff --git a/messages/teleporter/utils.go b/messages/teleporter/utils.go index b3c8a5c1..5b66648f 100644 --- a/messages/teleporter/utils.go +++ b/messages/teleporter/utils.go @@ -9,7 +9,6 @@ import ( "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/awm-relayer/utils" - "github.com/ethereum/go-ethereum/common" ) const ( @@ -48,10 +47,3 @@ func CalculateReceiveMessageGasLimit(numSigners int, executionRequiredGasLimit * return res, nil } - -// Pack the SendCrossChainMessage event type. PackEvent is documented as not supporting struct types, so this should be used -// with caution. Here, we only use it for testing purposes. In a real setting, the Teleporter contract should pack the event. -func PackSendCrossChainMessageEvent(destinationChainID common.Hash, message TeleporterMessage) ([]byte, error) { - _, hashes, err := EVMTeleporterContractABI.PackEvent("SendCrossChainMessage", destinationChainID, message.MessageID, message) - return hashes, err -} From 53f3833521552bd515e304c7323ea456e440ec4f Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 21 Sep 2023 21:23:22 +0000 Subject: [PATCH 54/56] explicit warning comment --- messages/teleporter/message.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/messages/teleporter/message.go b/messages/teleporter/message.go index 5dd80151..2507e601 100644 --- a/messages/teleporter/message.go +++ b/messages/teleporter/message.go @@ -84,8 +84,9 @@ func UnpackMessageReceivedResult(result []byte) (bool, error) { return success, err } -// PackSendCrossChainMessageEvent packs the SendCrossChainMessage event type. PackEvent is documented as not supporting struct types, so this should be used -// with caution. Here, we only use it for testing purposes. In a real setting, the Teleporter contract should pack the event. +// CAUTION: PackEvent is documented as not supporting struct types, so this should only be used for testing puposes. +// In a real setting, the Teleporter contract should pack the event. +// PackSendCrossChainMessageEvent packs the SendCrossChainMessage event type. func PackSendCrossChainMessageEvent(destinationChainID common.Hash, message TeleporterMessage) ([]byte, error) { _, hashes, err := EVMTeleporterContractABI.PackEvent("SendCrossChainMessage", destinationChainID, message.MessageID, message) return hashes, err From 40be845c00f16d12aaa15757e134da3b1ccdae01 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Mon, 25 Sep 2023 14:59:44 +0000 Subject: [PATCH 55/56] capitalize versions.sh --- scripts/versions.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/versions.sh b/scripts/versions.sh index 30f63c90..7f82a43a 100755 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -3,8 +3,8 @@ # See the file LICENSE for licensing terms. # Set up the versions to be used -awm_relayer_version=${AWM_RELAYER_VERSION:-'v0.2.1'} -subnet_evm_version=${SUBNET_EVM_VERSION:-'v0.5.4'} +AWM_RELAYER_VERSION=${AWM_RELAYER_VERSION:-'v0.2.1'} +SUBNET_EVM_VERSION=${SUBNET_EVM_VERSION:-'v0.5.4'} # Don't export them as they're used in the context of other calls -avalanche_version=${AVALANCHE_VERSION:-'v1.10.9'} +AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.9'} GINKGO_VERSION=${GINKGO_VERSION:-'v2.2.0'} From f6b04e37f8595546dac45a1cf1c4626d44969d2b Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Mon, 25 Sep 2023 15:08:57 +0000 Subject: [PATCH 56/56] fix var --- scripts/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.sh b/scripts/build.sh index 4c03ade9..5687beb8 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -49,5 +49,5 @@ else fi # Build AWM Relayer, which is run as a standalone process -echo "Building AWM Relayer Version: $awm_relayer_version at $binary_path" +echo "Building AWM Relayer Version: $AWM_RELAYER_VERSION at $binary_path" go build -o "$binary_path" "main/"*.go