diff --git a/changelog.md b/changelog.md index 8507aa0b4e..18571a1469 100644 --- a/changelog.md +++ b/changelog.md @@ -23,6 +23,7 @@ ### Changes +- [#3306](https://github.com/ignite/cli/pull/3306) Move network command into a plugin - [#3305](https://github.com/ignite/cli/pull/3305) Bump Cosmos SDK version to `v0.46.7`. - [#3068](https://github.com/ignite/cli/pull/3068) Add configs to generated TS code for working with JS projects - [#3071](https://github.com/ignite/cli/pull/3071) Refactor `ignite/templates` package. diff --git a/go.mod b/go.mod index 44da3ba57d..01bdeacf54 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( github.com/99designs/keyring v1.2.1 github.com/AlecAivazis/survey/v2 v2.3.6 github.com/DATA-DOG/go-sqlmock v1.5.0 - github.com/aws/smithy-go v1.13.4 github.com/blang/semver/v4 v4.0.0 github.com/briandowns/spinner v1.20.0 github.com/buger/jsonparser v1.1.1 @@ -50,18 +49,17 @@ require ( github.com/pelletier/go-toml v1.9.5 github.com/pkg/errors v0.9.1 github.com/radovskyb/watcher v1.0.7 - github.com/rdegges/go-ipify v0.0.0-20150526035502-2d94a6a86c40 github.com/rs/cors v1.8.2 github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.6.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.1 github.com/tbruyelle/mdgofmt v0.1.2 - github.com/tendermint/spn v0.2.1-0.20221125172725-052fbf576cb2 github.com/tendermint/tendermint v0.34.24 github.com/tendermint/tm-db v0.6.7 github.com/vektra/mockery/v2 v2.16.0 go.etcd.io/bbolt v1.3.6 + golang.org/x/exp v0.0.0-20221212164502-fae10dda9338 golang.org/x/mod v0.7.0 golang.org/x/sync v0.1.0 golang.org/x/term v0.2.0 @@ -69,7 +67,6 @@ require ( golang.org/x/tools v0.3.0 golang.org/x/vuln v0.0.0-20221122171214-05fb7250142c google.golang.org/grpc v1.51.0 - google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 gopkg.in/yaml.v2 v2.4.0 mvdan.cc/gofumpt v0.4.0 ) @@ -372,12 +369,13 @@ require ( go.uber.org/zap v1.23.0 // indirect golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 // indirect golang.org/x/crypto v0.3.0 // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect golang.org/x/net v0.2.0 // indirect + golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 // indirect golang.org/x/sys v0.2.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1 // indirect + google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 601526164f..0fca7e1021 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,7 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= -cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= -cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= +cloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= @@ -46,7 +45,7 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= +cloud.google.com/go/storage v1.22.1 h1:F6IlQJZrZM++apn9V5/VfS3gbTUYg98PS3EMQAzqtfg= collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= @@ -217,8 +216,6 @@ github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7 github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= -github.com/aws/smithy-go v1.13.4 h1:/RN2z1txIJWeXeOkzX+Hk/4Uuvv7dWtCjbmVJcrskyk= -github.com/aws/smithy-go v1.13.4/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aymanbagabas/go-osc52 v1.0.3 h1:DTwqENW7X9arYimJrPeGZcV0ln14sGMt3pHZspWD+Mg= github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= @@ -914,11 +911,12 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= +github.com/googleapis/enterprise-certificate-proxy v0.1.0 h1:zO8WHNx/MYiAKJ3d5spxZXZE6KHmIQGQcAzwUzV7qQw= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= +github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI= github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg= @@ -1046,7 +1044,6 @@ github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHL github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ignite/modules v0.0.0-20220912090139-7c325cae763a h1:0P8qg4YS0hb8jomZedhbooEKE3JZhRNAewV8+8otr6k= github.com/ignite/web v0.4.3 h1:LHucUEXttzCf5JmxO5/xLKVx1Qz1o124HqF4Nii5uWQ= github.com/ignite/web v0.4.3/go.mod h1:WZWBaBYF8RazN7dE462BLpvXDY8ScacxcJ07BKwX/jY= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -1568,8 +1565,6 @@ github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Ung github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rdegges/go-ipify v0.0.0-20150526035502-2d94a6a86c40 h1:31Y7UZ1yTYBU4E79CE52I/1IRi3TqiuwquXGNtZDXWs= -github.com/rdegges/go-ipify v0.0.0-20150526035502-2d94a6a86c40/go.mod h1:j4c6zEU0eMG1oiZPUy+zD4ykX0NIpjZAEOEAviTWC18= github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzywPxOvwMdxcg= github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= @@ -1742,11 +1737,8 @@ github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= -github.com/tendermint/fundraising v0.3.1 h1:S4uOV/T7YNBqXhsCZnq/TUoHB0d2kM+6tKeTD4WhLN0= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/spn v0.2.1-0.20221125172725-052fbf576cb2 h1:3sf/j+p+XFSenqu1DNcjvW01dSPpvx06Xef3EiSvqhg= -github.com/tendermint/spn v0.2.1-0.20221125172725-052fbf576cb2/go.mod h1:GVDvxguSWgSsD5b0CQuWTLEOy41HR28OKXjAFpUNedQ= github.com/tendermint/tendermint v0.34.24 h1:879MKKJWYYPJEMMKME+DWUTY4V9f/FBpnZDI82ky+4k= github.com/tendermint/tendermint v0.34.24/go.mod h1:rXVrl4OYzmIa1I91av3iLv2HS0fGSiucyW9J4aMTpKI= github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= @@ -1942,8 +1934,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20221212164502-fae10dda9338 h1:OvjRkcNHnf6/W5FZXSxODbxwD+X7fspczG7Jn/xQVD4= +golang.org/x/exp v0.0.0-20221212164502-fae10dda9338/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 h1:Ic/qN6TEifvObMGQy72k0n1LlJr7DjWWEi+MOsDOiSk= golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= @@ -2057,7 +2049,8 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 h1:2o1E+E8TpNLklK9nHiPiK1uzIYrIHt+cQx3ynCwq9V8= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2364,7 +2357,7 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.102.0 h1:JxJl2qQ85fRMPNvlZY/enexbxpCjLwGhZUtgfGeQ51I= +google.golang.org/api v0.93.0 h1:T2xt9gi0gHdxdnRkVQhT8mIvPaXKNsDNWz+L696M66M= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= diff --git a/ignite/cmd/account.go b/ignite/cmd/account.go index 3b03267634..4b1d3987b4 100644 --- a/ignite/cmd/account.go +++ b/ignite/cmd/account.go @@ -17,7 +17,6 @@ const ( flagNonInteractive = "non-interactive" flagKeyringBackend = "keyring-backend" flagKeyringDir = "keyring-dir" - flagFrom = "from" ) func NewAccount() *cobra.Command { @@ -101,11 +100,6 @@ func getAddressPrefix(cmd *cobra.Command) string { return prefix } -func getFrom(cmd *cobra.Command) string { - prefix, _ := cmd.Flags().GetString(flagFrom) - return prefix -} - func flagSetAccountImport() *flag.FlagSet { fs := flag.NewFlagSet("", flag.ContinueOnError) fs.Bool(flagNonInteractive, false, "do not enter into interactive mode") diff --git a/ignite/cmd/cmd.go b/ignite/cmd/cmd.go index 5bf771e6b7..2792ddcdeb 100644 --- a/ignite/cmd/cmd.go +++ b/ignite/cmd/cmd.go @@ -17,7 +17,6 @@ import ( "github.com/ignite/cli/ignite/pkg/cliui" "github.com/ignite/cli/ignite/pkg/cliui/colors" uilog "github.com/ignite/cli/ignite/pkg/cliui/log" - "github.com/ignite/cli/ignite/pkg/cosmosaccount" "github.com/ignite/cli/ignite/pkg/cosmosver" "github.com/ignite/cli/ignite/pkg/gitpod" "github.com/ignite/cli/ignite/pkg/goenv" @@ -42,7 +41,9 @@ const ( ) // New creates a new root command for `Ignite CLI` with its sub commands. -func New() *cobra.Command { +// Returns the cobra.Command, a cleanUp function and an error. The cleanUp +// function must be invoked by the caller to clean eventual plugin instances. +func New(ctx context.Context) (*cobra.Command, func(), error) { cobra.EnableCommandSorting = false c := &cobra.Command{ @@ -72,7 +73,6 @@ To get started, create a blockchain: c.AddCommand(NewScaffold()) c.AddCommand(NewChain()) c.AddCommand(NewGenerate()) - c.AddCommand(NewNetwork()) c.AddCommand(NewNode()) c.AddCommand(NewAccount()) c.AddCommand(NewRelayer()) @@ -82,7 +82,11 @@ To get started, create a blockchain: c.AddCommand(NewPlugin()) c.AddCommand(deprecated()...) - return c + // Load plugins if any + if err := LoadPlugins(ctx, c); err != nil { + return nil, nil, fmt.Errorf("error while loading plugins: %w", err) + } + return c, UnloadPlugins, nil } func getVerbosity(cmd *cobra.Command) uilog.Verbosity { @@ -108,12 +112,6 @@ func flagSetHome() *flag.FlagSet { return fs } -func flagNetworkFrom() *flag.FlagSet { - fs := flag.NewFlagSet("", flag.ContinueOnError) - fs.String(flagFrom, cosmosaccount.DefaultAccount, "account name to use for sending transactions to SPN") - return fs -} - func getHome(cmd *cobra.Command) (home string) { home, _ = cmd.Flags().GetString(flagHome) return diff --git a/ignite/cmd/ignite/main.go b/ignite/cmd/ignite/main.go index 0b714fc601..bee86660da 100644 --- a/ignite/cmd/ignite/main.go +++ b/ignite/cmd/ignite/main.go @@ -26,16 +26,14 @@ func run() int { ) ctx := clictx.From(context.Background()) - cmd := ignitecmd.New() - - // Load plugins if any - if err := ignitecmd.LoadPlugins(ctx, cmd); err != nil { - fmt.Printf("Error while loading plugins: %v\n", err) + cmd, cleanUp, err := ignitecmd.New(ctx) + if err != nil { + fmt.Printf("%v\n", err) return exitCodeError } - defer ignitecmd.UnloadPlugins() + defer cleanUp() - err := cmd.ExecuteContext(ctx) + err = cmd.ExecuteContext(ctx) if errors.Is(ctx.Err(), context.Canceled) || errors.Is(err, context.Canceled) { fmt.Println("aborted") diff --git a/ignite/cmd/network.go b/ignite/cmd/network.go deleted file mode 100644 index b665f370cb..0000000000 --- a/ignite/cmd/network.go +++ /dev/null @@ -1,264 +0,0 @@ -package ignitecmd - -import ( - "github.com/pkg/errors" - "github.com/spf13/cobra" - flag "github.com/spf13/pflag" - - "github.com/ignite/cli/ignite/pkg/cosmosaccount" - "github.com/ignite/cli/ignite/pkg/cosmosclient" - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/pkg/gitpod" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networkchain" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -var ( - nightly bool - local bool -) - -const ( - flagNightly = "nightly" - flagLocal = "local" - - flagSPNNodeAddress = "spn-node-address" - flagSPNFaucetAddress = "spn-faucet-address" - - spnNodeAddressNightly = "https://rpc.devnet.ignite.com:443" - spnFaucetAddressNightly = "https://faucet.devnet.ignite.com:443" - - spnNodeAddressLocal = "http://0.0.0.0:26661" - spnFaucetAddressLocal = "http://0.0.0.0:4502" -) - -// NewNetwork creates a new network command that holds some other sub commands -// related to creating a new network collaboratively. -func NewNetwork() *cobra.Command { - c := &cobra.Command{ - Use: "network [command]", - Aliases: []string{"n"}, - Short: "Launch a blockchain in production", - Long: ` -Ignite Network commands allow to coordinate the launch of sovereign Cosmos blockchains. - -To launch a Cosmos blockchain you need someone to be a coordinator and others to -be validators. These are just roles, anyone can be a coordinator or a validator. -A coordinator publishes information about a chain to be launched on the Ignite -blockchain, approves validator requests and coordinates the launch. Validators -send requests to join a chain and start their nodes when a blockchain is ready -for launch. - -To publish the information about your chain as a coordinator run the following -command (the URL should point to a repository with a Cosmos SDK chain): - - ignite network chain publish github.com/ignite/example - -This command will return a launch identifier you will be using in the following -commands. Let's say this identifier is 42. - -Next, ask validators to initialize their nodes and request to join the network -as validators. For a testnet you can use the default values suggested by the -CLI. - - ignite network chain init 42 - - ignite network chain join 42 --amount 95000000stake - -As a coordinator list all validator requests: - - ignite network request list 42 - -Approve validator requests: - - ignite network request approve 42 1,2 - -Once you've approved all validators you need in the validator set, announce that -the chain is ready for launch: - - ignite network chain launch 42 - -Validators can now prepare their nodes for launch: - - ignite network chain prepare 42 - -The output of this command will show a command that a validator would use to -launch their node, for example “exampled --home ~/.example”. After enough -validators launch their nodes, a blockchain will be live. -`, - Args: cobra.ExactArgs(1), - } - - // configure flags. - c.PersistentFlags().BoolVar(&local, flagLocal, false, "Use local SPN network") - c.PersistentFlags().BoolVar(&nightly, flagNightly, false, "Use nightly SPN network") - // Includes Flags for Node and Faucet Address - c.PersistentFlags().AddFlagSet(flagSetSpnAddresses()) - - // add sub commands. - c.AddCommand( - NewNetworkChain(), - NewNetworkProject(), - NewNetworkRequest(), - NewNetworkReward(), - NewNetworkValidator(), - NewNetworkProfile(), - NewNetworkCoordinator(), - ) - - return c -} - -var cosmos *cosmosclient.Client - -type ( - NetworkBuilderOption func(builder *NetworkBuilder) - - NetworkBuilder struct { - AccountRegistry cosmosaccount.Registry - - ev events.Bus - cmd *cobra.Command - cc cosmosclient.Client - } - - NetworkAddresses struct { - NodeAddress string - FaucetAddress string - } -) - -func CollectEvents(ev events.Bus) NetworkBuilderOption { - return func(builder *NetworkBuilder) { - builder.ev = ev - } -} - -func flagSetSPNAccountPrefixes() *flag.FlagSet { - fs := flag.NewFlagSet("", flag.ContinueOnError) - fs.String(flagAddressPrefix, networktypes.SPN, "account address prefix") - return fs -} - -func newNetworkBuilder(cmd *cobra.Command, options ...NetworkBuilderOption) (NetworkBuilder, error) { - var ( - err error - n = NetworkBuilder{cmd: cmd} - ) - - if n.cc, err = getNetworkCosmosClient(cmd); err != nil { - return NetworkBuilder{}, err - } - - n.AccountRegistry = n.cc.AccountRegistry - - for _, apply := range options { - apply(&n) - } - return n, nil -} - -func (n NetworkBuilder) Chain(source networkchain.SourceOption, options ...networkchain.Option) (*networkchain.Chain, error) { - if home := getHome(n.cmd); home != "" { - options = append(options, networkchain.WithHome(home)) - } - - options = append(options, networkchain.CollectEvents(n.ev)) - - return networkchain.New(n.cmd.Context(), n.AccountRegistry, source, options...) -} - -func (n NetworkBuilder) Network(options ...network.Option) (network.Network, error) { - var ( - err error - from = getFrom(n.cmd) - account = cosmosaccount.Account{} - ) - if from != "" { - account, err = cosmos.AccountRegistry.GetByName(getFrom(n.cmd)) - if err != nil { - return network.Network{}, errors.Wrap(err, "make sure that this account exists, use 'ignite account -h' to manage accounts") - } - } - - options = append(options, network.CollectEvents(n.ev)) - - return network.New(*cosmos, account, options...), nil -} - -func getNetworkCosmosClient(cmd *cobra.Command) (cosmosclient.Client, error) { - spn, err := getSpnAddresses(cmd) - if err != nil { - return cosmosclient.Client{}, err - } - - cosmosOptions := []cosmosclient.Option{ - cosmosclient.WithHome(cosmosaccount.KeyringHome), - cosmosclient.WithNodeAddress(spn.NodeAddress), - cosmosclient.WithAddressPrefix(networktypes.SPN), - cosmosclient.WithUseFaucet(spn.FaucetAddress, networktypes.SPNDenom, 5), - cosmosclient.WithKeyringServiceName(cosmosaccount.KeyringServiceName), - cosmosclient.WithKeyringDir(getKeyringDir(cmd)), - cosmosclient.WithGas(cosmosclient.GasAuto), - } - - keyringBackend := getKeyringBackend(cmd) - // use test keyring backend on Gitpod in order to prevent prompting for keyring - // password. This happens because Gitpod uses containers. - // - // when not on Gitpod, OS keyring backend is used which only asks password once. - if gitpod.IsOnGitpod() { - keyringBackend = cosmosaccount.KeyringTest - } - if keyringBackend != "" { - cosmosOptions = append(cosmosOptions, cosmosclient.WithKeyringBackend(keyringBackend)) - } - - // init cosmos client only once on start in order to spnclient to - // reuse unlocked keyring in the following steps. - if cosmos == nil { - client, err := cosmosclient.New(cmd.Context(), cosmosOptions...) - if err != nil { - return cosmosclient.Client{}, err - } - cosmos = &client - } - - if err := cosmos.AccountRegistry.EnsureDefaultAccount(); err != nil { - return cosmosclient.Client{}, err - } - - return *cosmos, nil -} - -func flagSetSpnAddresses() *flag.FlagSet { - fs := flag.NewFlagSet("", flag.ContinueOnError) - fs.String(flagSPNNodeAddress, spnNodeAddressNightly, "SPN node address") - fs.String(flagSPNFaucetAddress, spnFaucetAddressNightly, "SPN faucet address") - return fs -} - -func getSpnAddresses(cmd *cobra.Command) (NetworkAddresses, error) { - // check preconfigured networks - if nightly && local { - return NetworkAddresses{}, errors.New("local and nightly networks can't both be specified in the same command, specify local or nightly") - } - if nightly { - return NetworkAddresses{spnNodeAddressNightly, spnFaucetAddressNightly}, nil - } - if local { - return NetworkAddresses{spnNodeAddressLocal, spnFaucetAddressLocal}, nil - } - - spnNodeAddress, err := cmd.Flags().GetString(flagSPNNodeAddress) - if err != nil { - return NetworkAddresses{}, err - } - - spnFaucetAddress, err := cmd.Flags().GetString(flagSPNFaucetAddress) - if err != nil { - return NetworkAddresses{}, err - } - return NetworkAddresses{spnNodeAddress, spnFaucetAddress}, nil -} diff --git a/ignite/cmd/network_chain.go b/ignite/cmd/network_chain.go deleted file mode 100644 index 0319395b32..0000000000 --- a/ignite/cmd/network_chain.go +++ /dev/null @@ -1,49 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" -) - -// NewNetworkChain creates a new chain command that holds some other -// sub commands related to launching a network for a chain. -func NewNetworkChain() *cobra.Command { - c := &cobra.Command{ - Use: "chain", - Short: "Publish a chain, join as a validator and prepare node for launch", - Long: `The "chain" namespace features the most commonly used commands for launching -blockchains with Ignite. - -As a coordinator you "publish" your blockchain to Ignite. When enough validators -are approved for the genesis and no changes are excepted to be made to the -genesis, a coordinator announces that the chain is ready for launch with the -"launch" command. In the case of an unsuccessful launch, the coordinator can revert it -using the "revert-launch" command. - -As a validator, you "init" your node and apply to become a validator for a -blockchain with the "join" command. After the launch of the chain is announced, -validators can generate the finalized genesis and download the list of peers with the -"prepare" command. - -The "install" command can be used to download, compile the source code and -install the chain's binary locally. The binary can be used, for example, to -initialize a validator node or to interact with the chain after it has been -launched. - -All chains published to Ignite can be listed by using the "list" command. -`, - } - - c.AddCommand( - NewNetworkChainList(), - NewNetworkChainPublish(), - NewNetworkChainInit(), - NewNetworkChainInstall(), - NewNetworkChainJoin(), - NewNetworkChainPrepare(), - NewNetworkChainShow(), - NewNetworkChainLaunch(), - NewNetworkChainRevertLaunch(), - ) - - return c -} diff --git a/ignite/cmd/network_chain_init.go b/ignite/cmd/network_chain_init.go deleted file mode 100644 index 182e72399d..0000000000 --- a/ignite/cmd/network_chain_init.go +++ /dev/null @@ -1,249 +0,0 @@ -package ignitecmd - -import ( - "errors" - "fmt" - - "github.com/manifoldco/promptui" - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/chaincmd" - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/cliquiz" - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/cosmosaccount" - cosmosgenesis "github.com/ignite/cli/ignite/pkg/cosmosutil/genesis" - "github.com/ignite/cli/ignite/services/chain" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networkchain" -) - -const ( - flagValidatorAccount = "validator-account" - flagValidatorWebsite = "validator-website" - flagValidatorDetails = "validator-details" - flagValidatorSecurityContact = "validator-security-contact" - flagValidatorMoniker = "validator-moniker" - flagValidatorIdentity = "validator-identity" - flagValidatorSelfDelegation = "validator-self-delegation" - flagValidatorGasPrice = "validator-gas-price" - - defaultSelfDelegation = "95000000stake" - defaultCommissionMax = "0.10" - defaultCommissionMaxRate = "0.20" - defaultCommissionMaxChangeRate = "0.01" -) - -// NewNetworkChainInit returns a new command to initialize a chain from a published chain ID. -func NewNetworkChainInit() *cobra.Command { - c := &cobra.Command{ - Use: "init [launch-id]", - Short: "Initialize a chain from a published chain ID", - Long: `Ignite network chain init is a command used by validators to initialize a -validator node for a blockchain from the information stored on the Ignite chain. - - ignite network chain init 42 - -This command fetches the information about a chain with launch ID 42. The source -code of the chain is cloned in a temporary directory, and the node's binary is -compiled from the source. The binary is then used to initialize the node. By -default, Ignite uses "~/spn/[launch-id]/" as the home directory for the blockchain. - -An important part of initializing a validator node is creation of the gentx (a -transaction that adds a validator at the genesis of the chain). - -The "init" command will prompt for values like self-delegation and commission. -These values will be used in the validator's gentx. You can use flags to provide -the values in non-interactive mode. - -Use the "--home" flag to choose a different path for the home directory of the -blockchain: - - ignite network chain init 42 --home ~/mychain - -The end result of the "init" command is a validator home directory with a -genesis validator transaction (gentx) file.`, - Args: cobra.ExactArgs(1), - RunE: networkChainInitHandler, - } - - flagSetClearCache(c) - c.Flags().String(flagValidatorAccount, cosmosaccount.DefaultAccount, "account for the chain validator") - c.Flags().String(flagValidatorWebsite, "", "associate a website with the validator") - c.Flags().String(flagValidatorDetails, "", "details about the validator") - c.Flags().String(flagValidatorSecurityContact, "", "validator security contact email") - c.Flags().String(flagValidatorMoniker, "", "custom validator moniker") - c.Flags().String(flagValidatorIdentity, "", "validator identity signature (ex. UPort or Keybase)") - c.Flags().String(flagValidatorSelfDelegation, "", "validator minimum self delegation") - c.Flags().String(flagValidatorGasPrice, "", "validator gas price") - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - c.Flags().AddFlagSet(flagSetYes()) - c.Flags().AddFlagSet(flagSetCheckDependencies()) - return c -} - -func networkChainInitHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - // check if the provided account for the validator exists. - validatorAccount, _ := cmd.Flags().GetString(flagValidatorAccount) - if _, err = nb.AccountRegistry.GetByName(validatorAccount); err != nil { - return err - } - - // if a chain has already been initialized with this launch ID, we ask for confirmation - // before erasing the directory. - chainHome, exist, err := networkchain.IsChainHomeExist(launchID) - if err != nil { - return err - } - - if !getYes(cmd) && exist { - question := fmt.Sprintf( - "The chain has already been initialized under: %s. Would you like to overwrite the home directory", - chainHome, - ) - if err := session.AskConfirm(question); err != nil { - if errors.Is(err, promptui.ErrAbort) { - return nil - } - - return err - } - } - - cacheStorage, err := newCache(cmd) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - chainLaunch, err := n.ChainLaunch(cmd.Context(), launchID) - if err != nil { - return err - } - - networkOptions := []networkchain.Option{ - networkchain.WithKeyringBackend(chaincmd.KeyringBackendTest), - } - - if flagGetCheckDependencies(cmd) { - networkOptions = append(networkOptions, networkchain.CheckDependencies()) - } - - c, err := nb.Chain(networkchain.SourceLaunch(chainLaunch), networkOptions...) - if err != nil { - return err - } - - if err := c.Init(cmd.Context(), cacheStorage); err != nil { - return err - } - - genesisPath, err := c.GenesisPath() - if err != nil { - return err - } - - genesis, err := cosmosgenesis.FromPath(genesisPath) - if err != nil { - return err - } - stakeDenom, err := genesis.StakeDenom() - if err != nil { - return err - } - - // ask validator information. - defaultSelfDel := chainLaunch.AccountBalance.String() - if defaultSelfDel == "" { - defaultSelfDel = defaultSelfDelegation - } - v, err := askValidatorInfo(cmd, session, stakeDenom, defaultSelfDel) - if err != nil { - return err - } - session.StartSpinner("Generating your Gentx") - - gentxPath, err := c.InitAccount(cmd.Context(), v, validatorAccount) - if err != nil { - return err - } - - return session.Printf("%s Gentx generated: %s\n", icons.Bullet, gentxPath) -} - -// askValidatorInfo prompts to the user questions to query validator information. -func askValidatorInfo( - cmd *cobra.Command, - session *cliui.Session, - stakeDenom, - defaultSelfDel string, -) (chain.Validator, error) { - var ( - account, _ = cmd.Flags().GetString(flagValidatorAccount) - website, _ = cmd.Flags().GetString(flagValidatorWebsite) - details, _ = cmd.Flags().GetString(flagValidatorDetails) - securityContact, _ = cmd.Flags().GetString(flagValidatorSecurityContact) - moniker, _ = cmd.Flags().GetString(flagValidatorMoniker) - identity, _ = cmd.Flags().GetString(flagValidatorIdentity) - selfDelegation, _ = cmd.Flags().GetString(flagValidatorSelfDelegation) - gasPrice, _ = cmd.Flags().GetString(flagValidatorGasPrice) - ) - if gasPrice == "" { - gasPrice = "0" + stakeDenom - } - v := chain.Validator{ - Name: account, - Website: website, - Details: details, - Moniker: moniker, - Identity: identity, - SecurityContact: securityContact, - MinSelfDelegation: selfDelegation, - GasPrices: gasPrice, - } - - questions := append([]cliquiz.Question{}, - cliquiz.NewQuestion("Staking amount", - &v.StakingAmount, - cliquiz.DefaultAnswer(defaultSelfDel), - cliquiz.Required(), - ), - cliquiz.NewQuestion("Commission rate", - &v.CommissionRate, - cliquiz.DefaultAnswer(defaultCommissionMax), - cliquiz.Required(), - ), - cliquiz.NewQuestion("Commission max rate", - &v.CommissionMaxRate, - cliquiz.DefaultAnswer(defaultCommissionMaxRate), - cliquiz.Required(), - ), - cliquiz.NewQuestion("Commission max change rate", - &v.CommissionMaxChangeRate, - cliquiz.DefaultAnswer(defaultCommissionMaxChangeRate), - cliquiz.Required(), - ), - ) - return v, session.Ask(questions...) -} diff --git a/ignite/cmd/network_chain_install.go b/ignite/cmd/network_chain_install.go deleted file mode 100644 index 89564d2830..0000000000 --- a/ignite/cmd/network_chain_install.go +++ /dev/null @@ -1,83 +0,0 @@ -package ignitecmd - -import ( - "path/filepath" - - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/colors" - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/goenv" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networkchain" -) - -// NewNetworkChainInstall returns a new command to install a chain's binary by the launch id. -func NewNetworkChainInstall() *cobra.Command { - c := &cobra.Command{ - Use: "install [launch-id]", - Short: "Install chain binary for a launch", - Args: cobra.ExactArgs(1), - RunE: networkChainInstallHandler, - } - - flagSetClearCache(c) - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetCheckDependencies()) - return c -} - -func networkChainInstallHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - cacheStorage, err := newCache(cmd) - if err != nil { - return err - } - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - chainLaunch, err := n.ChainLaunch(cmd.Context(), launchID) - if err != nil { - return err - } - - var networkOptions []networkchain.Option - - if flagGetCheckDependencies(cmd) { - networkOptions = append(networkOptions, networkchain.CheckDependencies()) - } - - c, err := nb.Chain(networkchain.SourceLaunch(chainLaunch), networkOptions...) - if err != nil { - return err - } - - binaryName, err := c.Build(cmd.Context(), cacheStorage) - if err != nil { - return err - } - binaryPath := filepath.Join(goenv.Bin(), binaryName) - - session.Printf("%s Binary installed\n", icons.OK) - session.Printf("%s Binary's name: %s\n", icons.Info, colors.Info(binaryName)) - session.Printf("%s Binary's path: %s\n", icons.Info, colors.Info(binaryPath)) - - return nil -} diff --git a/ignite/cmd/network_chain_join.go b/ignite/cmd/network_chain_join.go deleted file mode 100644 index 8266bc2590..0000000000 --- a/ignite/cmd/network_chain_join.go +++ /dev/null @@ -1,229 +0,0 @@ -package ignitecmd - -import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/manifoldco/promptui" - - "github.com/ignite/cli/ignite/pkg/cliui/icons" - - "github.com/pkg/errors" - "github.com/rdegges/go-ipify" - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/cliquiz" - "github.com/ignite/cli/ignite/pkg/gitpod" - "github.com/ignite/cli/ignite/pkg/xchisel" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networkchain" -) - -const ( - flagGentx = "gentx" - flagAmount = "amount" - flagNoAccount = "no-account" - flagPeerAddress = "peer-address" -) - -// NewNetworkChainJoin creates a new chain join command to join -// to a network as a validator. -func NewNetworkChainJoin() *cobra.Command { - c := &cobra.Command{ - Use: "join [launch-id]", - Short: "Request to join a network as a validator", - Long: `The "join" command is used by validators to send a request to join a blockchain. -The required argument is a launch ID of a blockchain. The "join" command expects -that the validator has already setup a home directory for the blockchain and has -a gentx either by running "ignite network chain init" or initializing the data -directory manually with the chain's binary. - -By default the "join" command just sends the request to join as a validator. -However, often a validator also needs to request an genesis account with a token -balance to afford self-delegation. - -The following command will send a request to join blockchain with launch ID 42 -as a validator and request to be added as an account with a token balance of -95000000 STAKE. - - ignite network chain join 42 --amount 95000000stake - -A request to join as a validator contains a gentx file. Ignite looks for gentx -in a home directory used by "ignite network chain init" by default. To use a -different directory, use the "--home" flag or pass a gentx file directly with -the "--gentx" flag. - -Since "join" broadcasts a transaction to the Ignite blockchain, you will need an -account on the Ignite blockchain. During the testnet phase, however, Ignite -automatically requests tokens from a faucet.`, - Args: cobra.ExactArgs(1), - RunE: networkChainJoinHandler, - } - - c.Flags().String(flagGentx, "", "path to a gentx json file") - c.Flags().String(flagAmount, "", "amount of coins for account request (ignored if coordinator has fixed the account balances or if --no-acount flag is set)") - c.Flags().String(flagPeerAddress, "", "peer's address") - c.Flags().Bool(flagNoAccount, false, "prevent sending a request for a genesis account") - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - c.Flags().AddFlagSet(flagSetYes()) - c.Flags().AddFlagSet(flagSetCheckDependencies()) - - return c -} - -func networkChainJoinHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - var ( - joinOptions []network.JoinOption - gentxPath, _ = cmd.Flags().GetString(flagGentx) - amount, _ = cmd.Flags().GetString(flagAmount) - noAccount, _ = cmd.Flags().GetBool(flagNoAccount) - ) - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID. - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - // if there is no custom gentx, we need to detect the public address. - if gentxPath == "" { - // get the peer public address for the validator. - publicAddr, err := askPublicAddress(cmd, session) - if err != nil { - return err - } - - joinOptions = append(joinOptions, network.WithPublicAddress(publicAddr)) - } - - cacheStorage, err := newCache(cmd) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - chainLaunch, err := n.ChainLaunch(cmd.Context(), launchID) - if err != nil { - return err - } - - var networkOptions []networkchain.Option - - if flagGetCheckDependencies(cmd) { - networkOptions = append(networkOptions, networkchain.CheckDependencies()) - } - - c, err := nb.Chain(networkchain.SourceLaunch(chainLaunch), networkOptions...) - if err != nil { - return err - } - - // use the default gentx path from chain home if not provided - if gentxPath == "" { - gentxPath, err = c.DefaultGentxPath() - if err != nil { - return err - } - } else { - // if a custom gentx is provided, we initialize the chain home in order to check accounts - if err := c.Init(cmd.Context(), cacheStorage); err != nil { - return err - } - } - - // genesis account request - if !noAccount { - switch { - case c.IsAccountBalanceFixed(): - // fixed account balance - joinOptions = append(joinOptions, network.WithAccountRequest(c.AccountBalance())) - case amount != "": - // account balance set by user - amountCoins, err := sdk.ParseCoinsNormalized(amount) - if err != nil { - return errors.Wrap(err, "error parsing amount") - } - joinOptions = append(joinOptions, network.WithAccountRequest(amountCoins)) - default: - // fixed balance and no amount entered by the user, we ask if they want to skip account request - if !getYes(cmd) { - question := fmt.Sprintf( - "You haven't set the --%s flag and therefore an account request won't be submitted. Do you confirm", - flagAmount, - ) - if err := session.AskConfirm(question); err != nil { - if errors.Is(err, promptui.ErrAbort) { - return nil - } - - return err - } - } - - session.Printf("%s %s\n", icons.Info, "Account request won't be submitted") - } - } - - // create the message to add the validator. - return n.Join(cmd.Context(), c, launchID, gentxPath, joinOptions...) -} - -// askPublicAddress prepare questions to interactively ask for a publicAddress -// when peer isn't provided and not running through chisel proxy. -func askPublicAddress(cmd *cobra.Command, session *cliui.Session) (publicAddress string, err error) { - ctx := cmd.Context() - - if gitpod.IsOnGitpod() { - publicAddress, err = gitpod.URLForPort(ctx, xchisel.DefaultServerPort) - if err != nil { - return "", errors.Wrap(err, "cannot read public Gitpod address of the node") - } - return publicAddress, nil - } - - peerAddress, _ := cmd.Flags().GetString(flagPeerAddress) - - // The `--peer-address` flag is required when "--yes" is present - if getYes(cmd) && peerAddress == "" { - return "", errors.New("a peer address is required") - } - - // Don't prompt for an address when it is available as a flag value - if peerAddress != "" { - return peerAddress, nil - } - - // Try to guess the current peer address. This address is used - // as default when prompting user for the right peer address. - if ip, err := ipify.GetIp(); err == nil { - peerAddress = fmt.Sprintf("%s:26656", ip) - } - - options := []cliquiz.Option{cliquiz.Required()} - if peerAddress != "" { - options = append(options, cliquiz.DefaultAnswer(peerAddress)) - } - - questions := []cliquiz.Question{cliquiz.NewQuestion( - "Peer's address", - &publicAddress, - options..., - )} - return publicAddress, session.Ask(questions...) -} diff --git a/ignite/cmd/network_chain_launch.go b/ignite/cmd/network_chain_launch.go deleted file mode 100644 index 32480e5075..0000000000 --- a/ignite/cmd/network_chain_launch.go +++ /dev/null @@ -1,97 +0,0 @@ -package ignitecmd - -import ( - "time" - - timeparser "github.com/aws/smithy-go/time" - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/services/network" -) - -const ( - flagLauchTime = "launch-time" -) - -// NewNetworkChainLaunch creates a new chain launch command to launch -// the network as a coordinator. -func NewNetworkChainLaunch() *cobra.Command { - c := &cobra.Command{ - Use: "launch [launch-id]", - Short: "Trigger the launch of a chain", - Long: `The launch command communicates to the world that the chain is ready to be -launched. - -Only the coordinator of the chain can execute the launch command. - - ignite network chain launch 42 - -After the launch command is executed no changes to the genesis are accepted. For -example, validators will no longer be able to successfully execute the "ignite -network chain join" command to apply as a validator. - -The launch command sets the date and time after which the chain will start. By -default, the current time is set. To give validators more time to prepare for -the launch, set the time with the "--launch-time" flag: - - ignite network chain launch 42 --launch-time 2023-01-01T00:00:00Z - -After the launch command is executed, validators can generate the finalized -genesis and prepare their nodes for the launch. For example, validators can run -"ignite network chain prepare" to generate the genesis and populate the peer -list. - -If you want to change the launch time or open up the genesis file for changes -you can use "ignite network chain revert-launch" to make it possible, for -example, to accept new validators and add accounts. -`, - Args: cobra.ExactArgs(1), - RunE: networkChainLaunchHandler, - } - - c.Flags().String( - flagLauchTime, - "", - "timestamp the chain is effectively launched (example \"2022-01-01T00:00:00Z\")", - ) - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - - return c -} - -func networkChainLaunchHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - // parse launch time - var launchTime time.Time - launchTimeStr, _ := cmd.Flags().GetString(flagLauchTime) - - if launchTimeStr != "" { - launchTime, err = timeparser.ParseDateTime(launchTimeStr) - if err != nil { - return err - } - } - - n, err := nb.Network() - if err != nil { - return err - } - - return n.TriggerLaunch(cmd.Context(), launchID, launchTime) -} diff --git a/ignite/cmd/network_chain_list.go b/ignite/cmd/network_chain_list.go deleted file mode 100644 index 083fa21c39..0000000000 --- a/ignite/cmd/network_chain_list.go +++ /dev/null @@ -1,132 +0,0 @@ -package ignitecmd - -import ( - "errors" - "fmt" - "time" - - "github.com/cosmos/cosmos-sdk/types/query" - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/entrywriter" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -var LaunchSummaryHeader = []string{ - "launch ID", - "chain ID", - "source", - "phase", -} - -var LaunchSummaryAdvancedHeader = []string{ - "project ID", - "network", - "reward", -} - -// NewNetworkChainList returns a new command to list all published chains on Ignite. -func NewNetworkChainList() *cobra.Command { - c := &cobra.Command{ - Use: "list", - Short: "List published chains", - Args: cobra.NoArgs, - RunE: networkChainListHandler, - } - c.Flags().Bool(flagAdvanced, false, "show advanced information about the chains") - c.Flags().Uint64(flagLimit, 100, "limit of results per page") - c.Flags().Uint64(flagPage, 1, "page for chain list result") - - return c -} - -func networkChainListHandler(cmd *cobra.Command, _ []string) error { - var ( - advanced, _ = cmd.Flags().GetBool(flagAdvanced) - limit, _ = cmd.Flags().GetUint64(flagLimit) - page, _ = cmd.Flags().GetUint64(flagPage) - ) - - session := cliui.New(cliui.StartSpinner()) - - defer session.End() - - if page == 0 { - return errors.New("invalid page value") - } - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - n, err := nb.Network(network.CollectEvents(session.EventBus())) - if err != nil { - return err - } - chainLaunches, err := n.ChainLaunchesWithReward(cmd.Context(), &query.PageRequest{ - Offset: limit * (page - 1), - Limit: limit, - }) - if err != nil { - return err - } - - return renderLaunchSummaries(chainLaunches, session, advanced) -} - -// renderLaunchSummaries writes into the provided out, the list of summarized launches. -func renderLaunchSummaries(chainLaunches []networktypes.ChainLaunch, session *cliui.Session, advanced bool) error { - header := LaunchSummaryHeader - if advanced { - // advanced information show the project ID, type of network and rewards for incentivized testnet - header = append(header, LaunchSummaryAdvancedHeader...) - } - - var launchEntries [][]string - - // iterate and fetch summary for chains - for _, c := range chainLaunches { - - // get the current phase of the chain - var phase string - switch { - case !c.LaunchTriggered: - phase = "coordinating" - case time.Now().Before(c.LaunchTime): - phase = "launching" - default: - phase = "launched" - } - - entry := []string{ - fmt.Sprintf("%d", c.ID), - c.ChainID, - c.SourceURL, - phase, - } - - // add advanced information - if advanced { - project := "no project" - if c.ProjectID > 0 { - project = fmt.Sprintf("%d", c.ProjectID) - } - - reward := entrywriter.None - if len(c.Reward) > 0 { - reward = c.Reward - } - - entry = append(entry, - project, - c.Network.String(), - reward) - } - - launchEntries = append(launchEntries, entry) - } - - return session.PrintTable(header, launchEntries...) -} diff --git a/ignite/cmd/network_chain_prepare.go b/ignite/cmd/network_chain_prepare.go deleted file mode 100644 index 9c6c7d884d..0000000000 --- a/ignite/cmd/network_chain_prepare.go +++ /dev/null @@ -1,195 +0,0 @@ -package ignitecmd - -import ( - "fmt" - "path/filepath" - - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cache" - "github.com/ignite/cli/ignite/pkg/chaincmd" - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/colors" - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/gitpod" - "github.com/ignite/cli/ignite/pkg/goenv" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networkchain" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -const ( - flagForce = "force" -) - -// NewNetworkChainPrepare returns a new command to prepare the chain for launch. -func NewNetworkChainPrepare() *cobra.Command { - c := &cobra.Command{ - Use: "prepare [launch-id]", - Short: "Prepare the chain for launch", - Long: `The prepare command prepares a validator node for the chain launch by generating -the final genesis and adding IP addresses of peers to the validator's -configuration file. - - ignite network chain prepare 42 - -By default, Ignite uses "$HOME/spn/LAUNCH_ID" as the data directory. If you used -a different data directory when initializing the node, use the "--home" flag and -set the correct path to the data directory. - -Ignite generates the genesis file in "config/genesis.json" and adds peer IPs by -modifying "config/config.toml". - -The prepare command should be executed after the coordinator has triggered the -chain launch and finalized the genesis with "ignite network chain launch". You -can force Ignite to run the prepare command without checking if the launch has -been triggered with the "--force" flag (this is not recommended). - -After the prepare command is executed the node is ready to be started. -`, - Args: cobra.ExactArgs(1), - RunE: networkChainPrepareHandler, - } - - flagSetClearCache(c) - c.Flags().BoolP(flagForce, "f", false, "force the prepare command to run even if the chain is not launched") - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetCheckDependencies()) - - return c -} - -func networkChainPrepareHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - force, _ := cmd.Flags().GetBool(flagForce) - - cacheStorage, err := newCache(cmd) - if err != nil { - return err - } - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - // fetch chain information - chainLaunch, err := n.ChainLaunch(cmd.Context(), launchID) - if err != nil { - return err - } - - if !force && !chainLaunch.LaunchTriggered { - return fmt.Errorf("chain %d launch has not been triggered yet. use --force to prepare anyway", launchID) - } - - networkOptions := []networkchain.Option{ - networkchain.WithKeyringBackend(chaincmd.KeyringBackendTest), - } - - if flagGetCheckDependencies(cmd) { - networkOptions = append(networkOptions, networkchain.CheckDependencies()) - } - - c, err := nb.Chain(networkchain.SourceLaunch(chainLaunch), networkOptions...) - if err != nil { - return err - } - - if err := prepareFromGenesisInformation( - cmd, - cacheStorage, - launchID, - n, - c, - chainLaunch, - ); err != nil { - return err - } - - chainHome, err := c.Home() - if err != nil { - return err - } - binaryName, err := c.BinaryName() - if err != nil { - return err - } - binaryDir := filepath.Dir(filepath.Join(goenv.Bin(), binaryName)) - - session.Printf("%s Chain is prepared for launch\n", icons.OK) - session.Println("\nYou can start your node by running the following command:") - startCmd := "start" - if gitpod.IsOnGitpod() { - startCmd = "start-with-http-tunneling" - } - commandStr := fmt.Sprintf("%s %s --home %s", binaryName, startCmd, chainHome) - session.Printf("\t%s/%s\n", binaryDir, colors.Info(commandStr)) - - return nil -} - -// prepareFromGenesisInformation prepares the genesis of the chain from the queried genesis information from the launch ID of the chain. -func prepareFromGenesisInformation( - cmd *cobra.Command, - cacheStorage cache.Storage, - launchID uint64, - n network.Network, - c *networkchain.Chain, - chainLaunch networktypes.ChainLaunch, -) error { - var ( - rewardsInfo networktypes.Reward - lastBlockHeight int64 - consumerUnbondingTime int64 - ) - - // fetch the information to construct genesis - genesisInformation, err := n.GenesisInformation(cmd.Context(), launchID) - if err != nil { - return err - } - - // fetch the info for rewards if the consumer revision height is defined - if chainLaunch.ConsumerRevisionHeight > 0 { - rewardsInfo, lastBlockHeight, consumerUnbondingTime, err = n.RewardsInfo( - cmd.Context(), - launchID, - chainLaunch.ConsumerRevisionHeight, - ) - if err != nil { - return err - } - } - - spnChainID, err := n.ChainID(cmd.Context()) - if err != nil { - return err - } - - return c.Prepare( - cmd.Context(), - cacheStorage, - genesisInformation, - rewardsInfo, - spnChainID, - lastBlockHeight, - consumerUnbondingTime, - ) -} diff --git a/ignite/cmd/network_chain_publish.go b/ignite/cmd/network_chain_publish.go deleted file mode 100644 index 3f95357984..0000000000 --- a/ignite/cmd/network_chain_publish.go +++ /dev/null @@ -1,342 +0,0 @@ -package ignitecmd - -import ( - "fmt" - "os" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "github.com/tendermint/spn/pkg/chainid" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/xurl" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networkchain" -) - -const ( - flagTag = "tag" - flagBranch = "branch" - flagHash = "hash" - flagGenesisURL = "genesis-url" - flagGenesisConfig = "genesis-config" - flagProject = "project" - flagShares = "shares" - flagNoCheck = "no-check" - flagChainID = "chain-id" - flagMainnet = "mainnet" - flagAccountBalance = "account-balance" - flagRewardCoins = "reward.coins" - flagRewardHeight = "reward.height" -) - -// NewNetworkChainPublish returns a new command to publish a new chain to start a new network. -func NewNetworkChainPublish() *cobra.Command { - c := &cobra.Command{ - Use: "publish [source-url]", - Short: "Publish a new chain to start a new network", - Long: `To begin the process of launching a blockchain with Ignite, a coordinator needs -to publish the information about a blockchain. The only required bit of -information is the URL of the source code of the blockchain. - -The following command publishes the information about an example blockchain: - - ignite network chain publish github.com/ignite/example - -This command fetches the source code of the blockchain, compiles the binary, -verifies that a blockchain can be started with the binary, and publishes the -information about the blockchain to Ignite. Currently, only public repositories -are supported. The command returns an integer number that acts as an identifier -of the chain on Ignite. - -By publishing a blockchain on Ignite you become the "coordinator" of this -blockchain. A coordinator is an account that has the authority to approve and -reject validator requests, set parameters of the blockchain and trigger the -launch of the chain. - -The default Git branch is used when publishing a chain. If you want to use a -specific branch, tag or a commit hash, use "--branch", "--tag", or "--hash" -flags respectively. - -The repository name is used as the default chain ID. Ignite does not ensure that -chain IDs are unique, but they have to have a valid format: [string]-[integer]. -To set a custom chain ID use the "--chain-id" flag. - - ignite network chain publish github.com/ignite/example --chain-id foo-1 - -Once the chain is published users can request accounts with coin balances to be -added to the chain's genesis. By default, users are free to request any number -of tokens. If you want all users requesting tokens to get the same amount, use -the "--account-balance" flag with a list of coins. - - ignite network chain publish github.com/ignite/example --account-balance 2000foocoin -`, - Args: cobra.ExactArgs(1), - RunE: networkChainPublishHandler, - } - - flagSetClearCache(c) - c.Flags().String(flagBranch, "", "Git branch to use for the repo") - c.Flags().String(flagTag, "", "Git tag to use for the repo") - c.Flags().String(flagHash, "", "Git hash to use for the repo") - c.Flags().String(flagGenesisURL, "", "URL to a custom Genesis") - c.Flags().String(flagGenesisConfig, "", "name of an Ignite config file in the repo for custom Genesis") - c.Flags().String(flagChainID, "", "chain ID to use for this network") - c.Flags().Uint64(flagProject, 0, "project ID to use for this network") - c.Flags().Bool(flagNoCheck, false, "skip verifying chain's integrity") - c.Flags().String(flagProjectMetadata, "", "add a project metadata") - c.Flags().String(flagProjectTotalSupply, "", "add a total of the mainnet of a project") - c.Flags().String(flagShares, "", "add shares for the project") - c.Flags().Bool(flagMainnet, false, "initialize a mainnet project") - c.Flags().String(flagAccountBalance, "", "balance for each approved genesis account for the chain") - c.Flags().String(flagRewardCoins, "", "reward coins") - c.Flags().Int64(flagRewardHeight, 0, "last reward height") - c.Flags().String(flagAmount, "", "amount of coins for account request") - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetYes()) - c.Flags().AddFlagSet(flagSetCheckDependencies()) - - return c -} - -func networkChainPublishHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - var ( - tag, _ = cmd.Flags().GetString(flagTag) - branch, _ = cmd.Flags().GetString(flagBranch) - hash, _ = cmd.Flags().GetString(flagHash) - genesisURL, _ = cmd.Flags().GetString(flagGenesisURL) - genesisConfig, _ = cmd.Flags().GetString(flagGenesisConfig) - chainID, _ = cmd.Flags().GetString(flagChainID) - project, _ = cmd.Flags().GetUint64(flagProject) - noCheck, _ = cmd.Flags().GetBool(flagNoCheck) - projectMetadata, _ = cmd.Flags().GetString(flagProjectMetadata) - projectTotalSupplyStr, _ = cmd.Flags().GetString(flagProjectTotalSupply) - sharesStr, _ = cmd.Flags().GetString(flagShares) - isMainnet, _ = cmd.Flags().GetBool(flagMainnet) - accountBalance, _ = cmd.Flags().GetString(flagAccountBalance) - rewardCoinsStr, _ = cmd.Flags().GetString(flagRewardCoins) - rewardDuration, _ = cmd.Flags().GetInt64(flagRewardHeight) - amount, _ = cmd.Flags().GetString(flagAmount) - ) - - // parse the amount. - amountCoins, err := sdk.ParseCoinsNormalized(amount) - if err != nil { - return errors.Wrap(err, "error parsing amount") - } - - accountBalanceCoins, err := sdk.ParseCoinsNormalized(accountBalance) - if err != nil { - return errors.Wrap(err, "error parsing account balance") - } - - source, err := xurl.MightHTTPS(args[0]) - if err != nil { - return fmt.Errorf("invalid source url format: %w", err) - } - - cacheStorage, err := newCache(cmd) - if err != nil { - return err - } - - if project != 0 && projectTotalSupplyStr != "" { - return fmt.Errorf("%s and %s flags cannot be set together", flagProject, flagProjectTotalSupply) - } - if isMainnet { - if project == 0 && projectTotalSupplyStr == "" { - return fmt.Errorf( - "%s flag requires one of the %s or %s flags to be set", - flagMainnet, - flagProject, - flagProjectTotalSupply, - ) - } - if chainID == "" { - return fmt.Errorf("%s flag requires the %s flag", flagMainnet, flagChainID) - } - } - - if chainID != "" { - chainName, _, err := chainid.ParseGenesisChainID(chainID) - if err != nil { - return errors.Wrapf(err, "invalid chain id: %s", chainID) - } - if err := chainid.CheckChainName(chainName); err != nil { - return errors.Wrapf(err, "invalid chain id name: %s", chainName) - } - } - - totalSupply, err := sdk.ParseCoinsNormalized(projectTotalSupplyStr) - if err != nil { - return err - } - - rewardCoins, err := sdk.ParseCoinsNormalized(rewardCoinsStr) - if err != nil { - return err - } - - if (!rewardCoins.Empty() && rewardDuration == 0) || - (rewardCoins.Empty() && rewardDuration > 0) { - return fmt.Errorf("%s and %s flags must be provided together", flagRewardCoins, flagRewardHeight) - } - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // use source from chosen target. - var sourceOption networkchain.SourceOption - - switch { - case tag != "": - sourceOption = networkchain.SourceRemoteTag(source, tag) - case branch != "": - sourceOption = networkchain.SourceRemoteBranch(source, branch) - case hash != "": - sourceOption = networkchain.SourceRemoteHash(source, hash) - default: - sourceOption = networkchain.SourceRemote(source) - } - - var initOptions []networkchain.Option - - // cannot use both genesisURL and genesisConfig - if genesisURL != "" && genesisConfig != "" { - return errors.New("cannot use both genesis-url and genesis-config for initial genesis." + - "Please use only one of the options.") - } - - // use custom genesis from url if given. - if genesisURL != "" { - initOptions = append(initOptions, networkchain.WithGenesisFromURL(genesisURL)) - } - - // use custom genesis config if given - if genesisConfig != "" { - initOptions = append(initOptions, networkchain.WithGenesisFromConfig(genesisConfig)) - } - - // init in a temp dir. - homeDir, err := os.MkdirTemp("", "") - if err != nil { - return err - } - defer os.RemoveAll(homeDir) - - initOptions = append(initOptions, networkchain.WithHome(homeDir)) - - // prepare publish options - publishOptions := []network.PublishOption{network.WithMetadata(projectMetadata)} - - switch { - case genesisURL != "": - publishOptions = append(publishOptions, network.WithCustomGenesisURL(genesisURL)) - case genesisConfig != "": - publishOptions = append(publishOptions, network.WithCustomGenesisConfig(genesisConfig)) - - } - - if project != 0 { - publishOptions = append(publishOptions, network.WithProject(project)) - } else if projectTotalSupplyStr != "" { - totalSupply, err := sdk.ParseCoinsNormalized(projectTotalSupplyStr) - if err != nil { - return err - } - if !totalSupply.Empty() { - publishOptions = append(publishOptions, network.WithTotalSupply(totalSupply)) - } - } - - // use custom chain id if given. - if chainID != "" { - publishOptions = append(publishOptions, network.WithChainID(chainID)) - } - - if !accountBalanceCoins.IsZero() { - publishOptions = append(publishOptions, network.WithAccountBalance(accountBalanceCoins)) - } - - if isMainnet { - publishOptions = append(publishOptions, network.Mainnet()) - } - - if !totalSupply.Empty() { - publishOptions = append(publishOptions, network.WithTotalSupply(totalSupply)) - } - - if sharesStr != "" { - sharePercentages, err := network.ParseSharePercents(sharesStr) - if err != nil { - return err - } - - publishOptions = append(publishOptions, network.WithPercentageShares(sharePercentages)) - } - - // TODO: Issue an error or warning when this flag is used with "no-check"? - // The "check-dependencies" flag is ignored when the "no-check" one is present. - if flagGetCheckDependencies(cmd) { - initOptions = append(initOptions, networkchain.CheckDependencies()) - } - - // init the chain. - c, err := nb.Chain(sourceOption, initOptions...) - if err != nil { - return err - } - - if !noCheck { - if err := c.Init(cmd.Context(), cacheStorage); err != nil { - // initialize the chain for checking. - return fmt.Errorf("blockchain init failed: %w", err) - } - } - - session.StartSpinner("Publishing...") - - n, err := nb.Network() - if err != nil { - return err - } - - launchID, projectID, err := n.Publish(cmd.Context(), c, publishOptions...) - if err != nil { - return err - } - - if !rewardCoins.IsZero() && rewardDuration > 0 { - if err := n.SetReward(cmd.Context(), launchID, rewardDuration, rewardCoins); err != nil { - return err - } - } - - if !amountCoins.IsZero() { - if err := n.SendAccountRequestForCoordinator(cmd.Context(), launchID, amountCoins); err != nil { - return err - } - } - - session.Printf("%s Network published \n", icons.OK) - if isMainnet { - session.Printf("%s Mainnet ID: %d \n", icons.Bullet, launchID) - } else { - session.Printf("%s Launch ID: %d \n", icons.Bullet, launchID) - } - if projectID != 0 { - session.Printf("%s Project ID: %d \n", icons.Bullet, projectID) - } - - return nil -} diff --git a/ignite/cmd/network_chain_revert_launch.go b/ignite/cmd/network_chain_revert_launch.go deleted file mode 100644 index 3b1213b1a3..0000000000 --- a/ignite/cmd/network_chain_revert_launch.go +++ /dev/null @@ -1,59 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networkchain" -) - -// NewNetworkChainRevertLaunch creates a new chain revert launch command -// to revert a launched chain. -func NewNetworkChainRevertLaunch() *cobra.Command { - c := &cobra.Command{ - Use: "revert-launch [launch-id]", - Short: "Revert launch of a network", - Args: cobra.ExactArgs(1), - RunE: networkChainRevertLaunchHandler, - } - - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - - return c -} - -func networkChainRevertLaunchHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - chainLaunch, err := n.ChainLaunch(cmd.Context(), launchID) - if err != nil { - return err - } - - c, err := nb.Chain(networkchain.SourceLaunch(chainLaunch)) - if err != nil { - return err - } - - return n.RevertLaunch(cmd.Context(), launchID, c) -} diff --git a/ignite/cmd/network_chain_show.go b/ignite/cmd/network_chain_show.go deleted file mode 100644 index 68146ce5cd..0000000000 --- a/ignite/cmd/network_chain_show.go +++ /dev/null @@ -1,40 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/services/network" -) - -const flagOut = "out" - -// NewNetworkChainShow creates a new chain show -// command to show a chain details on SPN. -func NewNetworkChainShow() *cobra.Command { - c := &cobra.Command{ - Use: "show", - Short: "Show details of a chain", - } - c.AddCommand( - newNetworkChainShowInfo(), - newNetworkChainShowGenesis(), - newNetworkChainShowAccounts(), - newNetworkChainShowValidators(), - newNetworkChainShowPeers(), - ) - return c -} - -func networkChainLaunch(cmd *cobra.Command, args []string, session *cliui.Session) (NetworkBuilder, uint64, error) { - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return nb, 0, err - } - // parse launch ID. - launchID, err := network.ParseID(args[0]) - if err != nil { - return nb, launchID, err - } - return nb, launchID, err -} diff --git a/ignite/cmd/network_chain_show_accounts.go b/ignite/cmd/network_chain_show_accounts.go deleted file mode 100644 index 1cced44549..0000000000 --- a/ignite/cmd/network_chain_show_accounts.go +++ /dev/null @@ -1,94 +0,0 @@ -package ignitecmd - -import ( - "strconv" - - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/cosmosutil" -) - -var ( - chainGenesisAccSummaryHeader = []string{"Genesis Account", "Coins"} - chainVestingAccSummaryHeader = []string{"Vesting Account", "Total Balance", "Vesting", "EndTime"} -) - -func newNetworkChainShowAccounts() *cobra.Command { - c := &cobra.Command{ - Use: "accounts [launch-id]", - Short: "Show all vesting and genesis accounts of the chain", - Args: cobra.ExactArgs(1), - RunE: networkChainShowAccountsHandler, - } - - c.Flags().AddFlagSet(flagSetSPNAccountPrefixes()) - - return c -} - -func networkChainShowAccountsHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - addressPrefix := getAddressPrefix(cmd) - - nb, launchID, err := networkChainLaunch(cmd, args, session) - if err != nil { - return err - } - n, err := nb.Network() - if err != nil { - return err - } - - genesisAccs, err := n.GenesisAccounts(cmd.Context(), launchID) - if err != nil { - return err - } - vestingAccs, err := n.VestingAccounts(cmd.Context(), launchID) - if err != nil { - return err - } - if len(genesisAccs)+len(vestingAccs) == 0 { - return session.Printf("%s %s\n", icons.Info, "empty chain account list") - } - - genesisAccEntries := make([][]string, 0) - for _, acc := range genesisAccs { - address, err := cosmosutil.ChangeAddressPrefix(acc.Address, addressPrefix) - if err != nil { - return err - } - - genesisAccEntries = append(genesisAccEntries, []string{address, acc.Coins.String()}) - } - genesisVestingAccEntries := make([][]string, 0) - for _, acc := range vestingAccs { - address, err := cosmosutil.ChangeAddressPrefix(acc.Address, addressPrefix) - if err != nil { - return err - } - - genesisVestingAccEntries = append(genesisVestingAccEntries, []string{ - address, - acc.TotalBalance.String(), - acc.Vesting.String(), - strconv.FormatInt(acc.EndTime, 10), - }) - } - - if len(genesisAccEntries) > 0 { - if err = session.PrintTable(chainGenesisAccSummaryHeader, genesisAccEntries...); err != nil { - return err - } - } - if len(genesisVestingAccEntries) > 0 { - if err = session.PrintTable(chainVestingAccSummaryHeader, genesisVestingAccEntries...); err != nil { - return err - } - } - - return nil -} diff --git a/ignite/cmd/network_chain_show_genesis.go b/ignite/cmd/network_chain_show_genesis.go deleted file mode 100644 index 39241d06c2..0000000000 --- a/ignite/cmd/network_chain_show_genesis.go +++ /dev/null @@ -1,99 +0,0 @@ -package ignitecmd - -import ( - "os" - "path/filepath" - - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/chaincmd" - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/xos" - "github.com/ignite/cli/ignite/services/network/networkchain" -) - -func newNetworkChainShowGenesis() *cobra.Command { - c := &cobra.Command{ - Use: "genesis [launch-id]", - Short: "Show the chain genesis file", - Args: cobra.ExactArgs(1), - RunE: networkChainShowGenesisHandler, - } - - flagSetClearCache(c) - c.Flags().String(flagOut, "./genesis.json", "path to output Genesis file") - - return c -} - -func networkChainShowGenesisHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - out, _ := cmd.Flags().GetString(flagOut) - - cacheStorage, err := newCache(cmd) - if err != nil { - return err - } - - nb, launchID, err := networkChainLaunch(cmd, args, session) - if err != nil { - return err - } - n, err := nb.Network() - if err != nil { - return err - } - - chainLaunch, err := n.ChainLaunch(cmd.Context(), launchID) - if err != nil { - return err - } - - networkOptions := []networkchain.Option{ - networkchain.WithKeyringBackend(chaincmd.KeyringBackendTest), - } - - c, err := nb.Chain(networkchain.SourceLaunch(chainLaunch), networkOptions...) - if err != nil { - return err - } - - // generate the genesis in a temp dir - tmpHome, err := os.MkdirTemp("", "*-spn") - if err != nil { - return err - } - defer os.RemoveAll(tmpHome) - - c.SetHome(tmpHome) - - if err := prepareFromGenesisInformation( - cmd, - cacheStorage, - launchID, - n, - c, - chainLaunch, - ); err != nil { - return err - } - - // get the new genesis path - genesisPath, err := c.GenesisPath() - if err != nil { - return err - } - - if err := os.MkdirAll(filepath.Dir(out), 0o744); err != nil { - return err - } - - if err := xos.Rename(genesisPath, out); err != nil { - return err - } - - return session.Printf("%s Genesis generated: %s\n", icons.Bullet, out) -} diff --git a/ignite/cmd/network_chain_show_info.go b/ignite/cmd/network_chain_show_info.go deleted file mode 100644 index 6f08458262..0000000000 --- a/ignite/cmd/network_chain_show_info.go +++ /dev/null @@ -1,53 +0,0 @@ -package ignitecmd - -import ( - "errors" - - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/yaml" - "github.com/ignite/cli/ignite/services/network" -) - -func newNetworkChainShowInfo() *cobra.Command { - c := &cobra.Command{ - Use: "info [launch-id]", - Short: "Show info details of the chain", - Args: cobra.ExactArgs(1), - RunE: networkChainShowInfoHandler, - } - return c -} - -func networkChainShowInfoHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, launchID, err := networkChainLaunch(cmd, args, session) - if err != nil { - return err - } - n, err := nb.Network() - if err != nil { - return err - } - - chainLaunch, err := n.ChainLaunch(cmd.Context(), launchID) - if err != nil { - return err - } - - reward, err := n.ChainReward(cmd.Context(), launchID) - if err != nil && !errors.Is(err, network.ErrObjectNotFound) { - return err - } - chainLaunch.Reward = reward.RemainingCoins.String() - - info, err := yaml.Marshal(cmd.Context(), chainLaunch) - if err != nil { - return err - } - - return session.Print(info) -} diff --git a/ignite/cmd/network_chain_show_peers.go b/ignite/cmd/network_chain_show_peers.go deleted file mode 100644 index 28f312ef5f..0000000000 --- a/ignite/cmd/network_chain_show_peers.go +++ /dev/null @@ -1,77 +0,0 @@ -package ignitecmd - -import ( - "bytes" - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/services/network" -) - -func newNetworkChainShowPeers() *cobra.Command { - c := &cobra.Command{ - Use: "peers [launch-id]", - Short: "Show peers list of the chain", - Args: cobra.ExactArgs(1), - RunE: networkChainShowPeersHandler, - } - - c.Flags().String(flagOut, "./peers.txt", "path to output peers list") - - return c -} - -func networkChainShowPeersHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - out, _ := cmd.Flags().GetString(flagOut) - - nb, launchID, err := networkChainLaunch(cmd, args, session) - if err != nil { - return err - } - n, err := nb.Network() - if err != nil { - return err - } - - genVals, err := n.GenesisValidators(cmd.Context(), launchID) - if err != nil { - return err - } - - peers := make([]string, 0) - for _, acc := range genVals { - peer, err := network.PeerAddress(acc.Peer) - if err != nil { - return err - } - peers = append(peers, peer) - } - - if len(peers) == 0 { - session.Printf("%s %s\n", icons.Info, "no peers found") - return nil - - } - - if err := os.MkdirAll(filepath.Dir(out), 0o744); err != nil { - return err - } - - b := &bytes.Buffer{} - peerList := strings.Join(peers, ",") - fmt.Fprintln(b, peerList) - if err := os.WriteFile(out, b.Bytes(), 0o644); err != nil { - return err - } - - return session.Printf("%s Peer list generated: %s\n", icons.Bullet, out) -} diff --git a/ignite/cmd/network_chain_show_validators.go b/ignite/cmd/network_chain_show_validators.go deleted file mode 100644 index bc3e0cf5d5..0000000000 --- a/ignite/cmd/network_chain_show_validators.go +++ /dev/null @@ -1,69 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/cosmosutil" - "github.com/ignite/cli/ignite/services/network" -) - -var chainGenesisValSummaryHeader = []string{"Genesis Validator", "Self Delegation", "Peer"} - -func newNetworkChainShowValidators() *cobra.Command { - c := &cobra.Command{ - Use: "validators [launch-id]", - Short: "Show all validators of the chain", - Args: cobra.ExactArgs(1), - RunE: networkChainShowValidatorsHandler, - } - - c.Flags().AddFlagSet(flagSetSPNAccountPrefixes()) - - return c -} - -func networkChainShowValidatorsHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - addressPrefix := getAddressPrefix(cmd) - - nb, launchID, err := networkChainLaunch(cmd, args, session) - if err != nil { - return err - } - n, err := nb.Network() - if err != nil { - return err - } - - validators, err := n.GenesisValidators(cmd.Context(), launchID) - if err != nil { - return err - } - validatorEntries := make([][]string, 0) - for _, acc := range validators { - peer, err := network.PeerAddress(acc.Peer) - if err != nil { - return err - } - - address, err := cosmosutil.ChangeAddressPrefix(acc.Address, addressPrefix) - if err != nil { - return err - } - - validatorEntries = append(validatorEntries, []string{ - address, - acc.SelfDelegation.String(), - peer, - }) - } - if len(validatorEntries) == 0 { - return session.Printf("%s %s\n", icons.Info, "no account found") - } - - return session.PrintTable(chainGenesisValSummaryHeader, validatorEntries...) -} diff --git a/ignite/cmd/network_coordinator.go b/ignite/cmd/network_coordinator.go deleted file mode 100644 index 0c825fee0d..0000000000 --- a/ignite/cmd/network_coordinator.go +++ /dev/null @@ -1,17 +0,0 @@ -package ignitecmd - -import "github.com/spf13/cobra" - -// NewNetworkCoordinator creates a new coordinator command -// it contains sub commands to manage coordinator profile. -func NewNetworkCoordinator() *cobra.Command { - c := &cobra.Command{ - Use: "coordinator", - Short: "Show and update a coordinator profile", - } - c.AddCommand( - NewNetworkCoordinatorShow(), - NewNetworkCoordinatorSet(), - ) - return c -} diff --git a/ignite/cmd/network_coordinator_set.go b/ignite/cmd/network_coordinator_set.go deleted file mode 100644 index a75b708b6c..0000000000 --- a/ignite/cmd/network_coordinator_set.go +++ /dev/null @@ -1,66 +0,0 @@ -package ignitecmd - -import ( - "errors" - - "github.com/spf13/cobra" - profiletypes "github.com/tendermint/spn/x/profile/types" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" -) - -// NewNetworkCoordinatorSet creates a command to set an information in a coordinator profile. -func NewNetworkCoordinatorSet() *cobra.Command { - c := &cobra.Command{ - Use: "set details|identity|website [value]", - Short: "Set an information in a coordinator profile", - Long: `Coordinators on Ignite can set a profile containing a description for the coordinator. -The coordinator set command allows to set information for the coordinator. -The following information can be set: -- details: general information about the coordinator. -- identity: a piece of information to verify the identity of the coordinator with a system like Keybase or Veramo. -- website: website of the coordinator. -`, - RunE: networkCoordinatorSetHandler, - Args: cobra.ExactArgs(2), - } - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - return c -} - -func networkCoordinatorSetHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - var description profiletypes.CoordinatorDescription - switch args[0] { - case "details": - description.Details = args[1] - case "identity": - description.Identity = args[1] - case "website": - description.Website = args[1] - default: - return errors.New("invalid attribute, must provide details, identity, website or security") - } - - if err := n.SetCoordinatorDescription(cmd.Context(), description); err != nil { - return err - } - - return session.Printf("%s Coordinator updated \n", icons.OK) -} diff --git a/ignite/cmd/network_coordinator_show.go b/ignite/cmd/network_coordinator_show.go deleted file mode 100644 index e8090e6373..0000000000 --- a/ignite/cmd/network_coordinator_show.go +++ /dev/null @@ -1,56 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/yaml" -) - -// NewNetworkCoordinatorShow creates a command to show coordinator information. -func NewNetworkCoordinatorShow() *cobra.Command { - c := &cobra.Command{ - Use: "show [address]", - Short: "Show a coordinator profile", - RunE: networkCoordinatorShowHandler, - Args: cobra.ExactArgs(1), - } - return c -} - -func networkCoordinatorShowHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - coordinator, err := n.Coordinator(cmd.Context(), args[0]) - if err != nil { - return err - } - - // convert the request object to YAML to be more readable - // and convert the byte array fields to string. - coordinatorYaml, err := yaml.Marshal(cmd.Context(), struct { - Identity string - Details string - Website string - }{ - coordinator.Identity, - coordinator.Details, - coordinator.Website, - }) - if err != nil { - return err - } - - return session.Println(coordinatorYaml) -} diff --git a/ignite/cmd/network_profile.go b/ignite/cmd/network_profile.go deleted file mode 100644 index 8888660f19..0000000000 --- a/ignite/cmd/network_profile.go +++ /dev/null @@ -1,58 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/yaml" - "github.com/ignite/cli/ignite/services/network" -) - -// NewNetworkProfile returns a new command to show the address profile info on Starport Network. -func NewNetworkProfile() *cobra.Command { - c := &cobra.Command{ - Use: "profile [project-id]", - Short: "Show the address profile info", - Args: cobra.RangeArgs(0, 1), - RunE: networkProfileHandler, - Hidden: true, - } - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetHome()) - return c -} - -func networkProfileHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - var projectID uint64 - if len(args) > 0 { - projectID, err = network.ParseID(args[0]) - if err != nil { - return err - } - } - - profile, err := n.Profile(cmd.Context(), projectID) - if err != nil { - return err - } - - profileInfo, err := yaml.Marshal(cmd.Context(), profile) - if err != nil { - return err - } - return session.Println(profileInfo) -} diff --git a/ignite/cmd/network_project.go b/ignite/cmd/network_project.go deleted file mode 100644 index 8d84a8fda2..0000000000 --- a/ignite/cmd/network_project.go +++ /dev/null @@ -1,23 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" -) - -// NewNetworkProject creates a new project command that holds other -// subcommands related to launching a network for a project. -func NewNetworkProject() *cobra.Command { - c := &cobra.Command{ - Use: "project", - Short: "Handle projects", - Hidden: true, - } - c.AddCommand( - NewNetworkProjectPublish(), - NewNetworkProjectList(), - NewNetworkProjectShow(), - NewNetworkProjectUpdate(), - NewNetworkProjectAccount(), - ) - return c -} diff --git a/ignite/cmd/network_project_account.go b/ignite/cmd/network_project_account.go deleted file mode 100644 index 98197c5384..0000000000 --- a/ignite/cmd/network_project_account.go +++ /dev/null @@ -1,71 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" -) - -var projectMainnetsAccSummaryHeader = []string{"Mainnet Account", "Shares"} - -// NewNetworkProjectAccount creates a new project account command that holds some other -// sub commands related to account for a project. -func NewNetworkProjectAccount() *cobra.Command { - c := &cobra.Command{ - Use: "account", - Short: "Handle project accounts", - } - c.AddCommand( - newNetworkProjectAccountList(), - ) - return c -} - -func newNetworkProjectAccountList() *cobra.Command { - c := &cobra.Command{ - Use: "list [project-id]", - Short: "Show all mainnet and mainnet vesting of the project", - Args: cobra.ExactArgs(1), - RunE: newNetworkProjectAccountListHandler, - } - return c -} - -func newNetworkProjectAccountListHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, projectID, err := networkChainLaunch(cmd, args, session) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - // get all project accounts - mainnetAccs, err := n.MainnetAccounts(cmd.Context(), projectID) - if err != nil { - return err - } - - if len(mainnetAccs) == 0 { - return session.Printf("%s no project account found\n", icons.Info) - } - - mainnetAccEntries := make([][]string, 0) - for _, acc := range mainnetAccs { - mainnetAccEntries = append(mainnetAccEntries, []string{acc.Address, acc.Shares.String()}) - } - - if len(mainnetAccEntries) > 0 { - if err = session.PrintTable(projectMainnetsAccSummaryHeader, mainnetAccEntries...); err != nil { - return err - } - } - - return nil -} diff --git a/ignite/cmd/network_project_list.go b/ignite/cmd/network_project_list.go deleted file mode 100644 index 528617ac61..0000000000 --- a/ignite/cmd/network_project_list.go +++ /dev/null @@ -1,72 +0,0 @@ -package ignitecmd - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/entrywriter" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -var ProjectSummaryHeader = []string{ - "id", - "name", - "coordinator id", - "mainnet id", -} - -// NewNetworkProjectList returns a new command to list all published Projects on Ignite. -func NewNetworkProjectList() *cobra.Command { - c := &cobra.Command{ - Use: "list", - Short: "List published projects", - Args: cobra.NoArgs, - RunE: networkProjectListHandler, - } - return c -} - -func networkProjectListHandler(cmd *cobra.Command, _ []string) error { - session := cliui.New(cliui.StartSpinner()) - - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - projects, err := n.Projects(cmd.Context()) - if err != nil { - return err - } - - return renderProjectSummaries(projects, session) -} - -// renderProjectSummaries writes into the provided out, the list of summarized projects. -func renderProjectSummaries(projects []networktypes.Project, session *cliui.Session) error { - var projectEntries [][]string - - for _, c := range projects { - mainnetID := entrywriter.None - if c.MainnetInitialized { - mainnetID = fmt.Sprintf("%d", c.MainnetID) - } - - projectEntries = append(projectEntries, []string{ - fmt.Sprintf("%d", c.ID), - c.Name, - fmt.Sprintf("%d", c.CoordinatorID), - mainnetID, - }) - } - - return session.PrintTable(ProjectSummaryHeader, projectEntries...) -} diff --git a/ignite/cmd/network_project_publish.go b/ignite/cmd/network_project_publish.go deleted file mode 100644 index 776cee2092..0000000000 --- a/ignite/cmd/network_project_publish.go +++ /dev/null @@ -1,57 +0,0 @@ -package ignitecmd - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" -) - -const ( - flagMetadata = "metadata" -) - -// NewNetworkProjectPublish returns a new command to publish a new projects on Ignite. -func NewNetworkProjectPublish() *cobra.Command { - c := &cobra.Command{ - Use: "create [name] [total-supply]", - Short: "Create a project", - Args: cobra.ExactArgs(2), - RunE: networkProjectPublishHandler, - } - c.Flags().String(flagMetadata, "", "Add a metadata to the chain") - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - c.Flags().AddFlagSet(flagSetHome()) - return c -} - -func networkProjectPublishHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - totalSupply, err := sdk.ParseCoinsNormalized(args[1]) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - metadata, _ := cmd.Flags().GetString(flagMetadata) - projectID, err := n.CreateProject(cmd.Context(), args[0], metadata, totalSupply) - if err != nil { - return err - } - - return session.Printf("%s Project ID: %d \n", icons.Bullet, projectID) -} diff --git a/ignite/cmd/network_project_show.go b/ignite/cmd/network_project_show.go deleted file mode 100644 index 2b82099d6b..0000000000 --- a/ignite/cmd/network_project_show.go +++ /dev/null @@ -1,53 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/yaml" - "github.com/ignite/cli/ignite/services/network" -) - -// NewNetworkProjectShow returns a new command to show published project on Ignite. -func NewNetworkProjectShow() *cobra.Command { - c := &cobra.Command{ - Use: "show [project-id]", - Short: "Show published project", - Args: cobra.ExactArgs(1), - RunE: networkProjectShowHandler, - } - return c -} - -func networkProjectShowHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - // parse project ID - projectID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - project, err := n.Project(cmd.Context(), projectID) - if err != nil { - return err - } - - info, err := yaml.Marshal(cmd.Context(), project) - if err != nil { - return err - } - - return session.Println(info) -} diff --git a/ignite/cmd/network_project_update.go b/ignite/cmd/network_project_update.go deleted file mode 100644 index 404ecf1e3e..0000000000 --- a/ignite/cmd/network_project_update.go +++ /dev/null @@ -1,106 +0,0 @@ -package ignitecmd - -import ( - "fmt" - "strings" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/yaml" - "github.com/ignite/cli/ignite/services/network" -) - -const ( - flagProjectName = "name" - flagProjectMetadata = "metadata" - flagProjectTotalSupply = "total-supply" -) - -func NewNetworkProjectUpdate() *cobra.Command { - c := &cobra.Command{ - Use: "update [project-id]", - Short: "Update details fo the project of the project", - Args: cobra.ExactArgs(1), - RunE: networkProjectUpdateHandler, - } - c.Flags().String(flagProjectName, "", "update the project name") - c.Flags().String(flagProjectMetadata, "", "update the project metadata") - c.Flags().String(flagProjectTotalSupply, "", "update the total of the mainnet of a project") - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - return c -} - -func networkProjectUpdateHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - var ( - projectName, _ = cmd.Flags().GetString(flagProjectName) - metadata, _ = cmd.Flags().GetString(flagProjectMetadata) - projectTotalSupply, _ = cmd.Flags().GetString(flagProjectTotalSupply) - ) - - totalSupply, err := sdk.ParseCoinsNormalized(projectTotalSupply) - if err != nil { - return err - } - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse project ID - projectID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - if projectName == "" && metadata == "" && totalSupply.Empty() { - return fmt.Errorf("at least one of the flags %s must be provided", - strings.Join([]string{ - flagProjectName, - flagProjectMetadata, - flagProjectTotalSupply, - }, ", "), - ) - } - - n, err := nb.Network() - if err != nil { - return err - } - - var proposals []network.Prop - - if projectName != "" { - proposals = append(proposals, network.WithProjectName(projectName)) - } - if metadata != "" { - proposals = append(proposals, network.WithProjectMetadata(metadata)) - } - if !totalSupply.Empty() { - proposals = append(proposals, network.WithProjectTotalSupply(totalSupply)) - } - - if err = n.UpdateProject(cmd.Context(), projectID, proposals...); err != nil { - return err - } - - project, err := n.Project(cmd.Context(), projectID) - if err != nil { - return err - } - session.Println() - - info, err := yaml.Marshal(cmd.Context(), project) - if err != nil { - return err - } - - return session.Print(info) -} diff --git a/ignite/cmd/network_request.go b/ignite/cmd/network_request.go deleted file mode 100644 index 234e686a29..0000000000 --- a/ignite/cmd/network_request.go +++ /dev/null @@ -1,40 +0,0 @@ -package ignitecmd - -import "github.com/spf13/cobra" - -// NewNetworkRequest creates a new approval request command that holds some other -// sub commands related to handle request for a chain. -func NewNetworkRequest() *cobra.Command { - c := &cobra.Command{ - Use: "request", - Short: "Create, show, reject and approve requests", - Long: `The "request" namespace contains commands for creating, showing, approving, and -rejecting requests. - -A request is mechanism in Ignite that allows changes to be made to the genesis -file like adding accounts with token balances and validators. Anyone can submit -a request, but only the coordinator of a chain can approve or reject a request. - -Each request has a status: - -* Pending: waiting for the approval of the coordinator -* Approved: approved by the coordinator, its content has been applied to the - launch information -* Rejected: rejected by the coordinator or the request creator -`, - } - - c.AddCommand( - NewNetworkRequestShow(), - NewNetworkRequestList(), - NewNetworkRequestApprove(), - NewNetworkRequestReject(), - NewNetworkRequestVerify(), - NewNetworkRequestAddAccount(), - NewNetworkRequestRemoveAccount(), - NewNetworkRequestRemoveValidator(), - NewNetworkRequestChangeParam(), - ) - - return c -} diff --git a/ignite/cmd/network_request_add_account.go b/ignite/cmd/network_request_add_account.go deleted file mode 100644 index 6a99951a91..0000000000 --- a/ignite/cmd/network_request_add_account.go +++ /dev/null @@ -1,108 +0,0 @@ -package ignitecmd - -import ( - "errors" - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cosmosutil" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networkchain" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// NewNetworkRequestAddAccount creates a new command to send add account request. -func NewNetworkRequestAddAccount() *cobra.Command { - c := &cobra.Command{ - Use: "add-account [launch-id] [address] [coins]", - Short: "Send request to add account", - Long: `The "add account" command creates a new request to add an account with a given -address and a specified coin balance to the genesis of the chain. - -The request automatically fails to be applied if a genesis account or a vesting -account with an identical address is already specified in the launch -information. - -If a coordinator has specified that all genesis accounts on a chain should have -the same balance (useful for testnets, for example), the "add account" expects -only an address as an argument. Attempt to provide a token balance will result -in an error. -`, - RunE: networkRequestAddAccountHandler, - Args: cobra.RangeArgs(2, 3), - } - - flagSetClearCache(c) - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - return c -} - -func networkRequestAddAccountHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - // get the address for the account and change the prefix for Ignite Chain - address, err := cosmosutil.ChangeAddressPrefix(args[1], networktypes.SPN) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - chainLaunch, err := n.ChainLaunch(cmd.Context(), launchID) - if err != nil { - return err - } - - c, err := nb.Chain(networkchain.SourceLaunch(chainLaunch)) - if err != nil { - return err - } - - var balance sdk.Coins - if c.IsAccountBalanceFixed() { - balance = c.AccountBalance() - if len(args) == 3 { - return fmt.Errorf( - "balance can't be provided, balance has been set by coordinator to %s", - balance.String(), - ) - } - } else { - if len(args) < 3 { - return errors.New("account balance expected") - } - balanceStr := args[2] - balance, err = sdk.ParseCoinsNormalized(balanceStr) - if err != nil { - return err - } - } - - return n.SendAccountRequest( - cmd.Context(), - launchID, - address, - balance, - ) -} diff --git a/ignite/cmd/network_request_approve.go b/ignite/cmd/network_request_approve.go deleted file mode 100644 index da98d98bb2..0000000000 --- a/ignite/cmd/network_request_approve.go +++ /dev/null @@ -1,110 +0,0 @@ -package ignitecmd - -import ( - "github.com/pkg/errors" - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/numbers" - "github.com/ignite/cli/ignite/services/network" -) - -const ( - flagNoVerification = "no-verification" -) - -// NewNetworkRequestApprove creates a new request approve -// command to approve requests for a chain. -func NewNetworkRequestApprove() *cobra.Command { - c := &cobra.Command{ - Use: "approve [launch-id] [number<,...>]", - Aliases: []string{"accept"}, - Short: "Approve requests", - Long: `The "approve" command is used by a chain's coordinator to approve requests. -Multiple requests can be approved using a comma-separated list and/or using a -dash syntax. - - ignite network request approve 42 1,2,3-6,7,8 - -The command above approves requests with IDs from 1 to 8 included on a chain -with a launch ID 42. - -When requests are approved Ignite applies the requested changes and simulates -initializing and launching the chain locally. If the chain starts successfully, -requests are considered to be "verified" and are approved. If one or more -requested changes stop the chain from launching locally, the verification -process fails and the approval of all requests is canceled. To skip the -verification process use the "--no-verification" flag. - -Note that Ignite will try to approve requests in the same order as request IDs -are submitted to the "approve" command.`, - RunE: networkRequestApproveHandler, - Args: cobra.ExactArgs(2), - } - - flagSetClearCache(c) - c.Flags().Bool(flagNoVerification, false, "approve the requests without verifying them") - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - return c -} - -func networkRequestApproveHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - // Get the list of request ids - ids, err := numbers.ParseList(args[1]) - if err != nil { - return err - } - - // Verify the requests are valid - noVerification, err := cmd.Flags().GetBool(flagNoVerification) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - cacheStorage, err := newCache(cmd) - if err != nil { - return err - } - - // if requests must be verified, we simulate the chain in a temporary directory with the requests - if !noVerification { - if err := verifyRequest(cmd.Context(), cacheStorage, nb, launchID, ids...); err != nil { - return errors.Wrap(err, "request(s) not valid") - } - session.Printf("%s Request(s) %s verified\n", icons.OK, numbers.List(ids, "#")) - } - - // Submit the approved requests - reviewals := make([]network.Reviewal, 0) - for _, id := range ids { - reviewals = append(reviewals, network.ApproveRequest(id)) - } - if err := n.SubmitRequest(cmd.Context(), launchID, reviewals...); err != nil { - return err - } - - return session.Printf("%s Request(s) %s approved\n", icons.OK, numbers.List(ids, "#")) -} diff --git a/ignite/cmd/network_request_change_param.go b/ignite/cmd/network_request_change_param.go deleted file mode 100644 index 8e508d3fdb..0000000000 --- a/ignite/cmd/network_request_change_param.go +++ /dev/null @@ -1,81 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networkchain" -) - -// NewNetworkRequestChangeParam creates a new command to send param change request. -func NewNetworkRequestChangeParam() *cobra.Command { - c := &cobra.Command{ - Use: "change-param [launch-id] [module-name] [param-name] [value (json, string, number)]", - Short: "Send request to change a module param", - RunE: networkRequestChangeParamHandler, - Args: cobra.ExactArgs(4), - } - - flagSetClearCache(c) - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - return c -} - -func networkRequestChangeParamHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - module := args[1] - param := args[2] - value := []byte(args[3]) - - n, err := nb.Network() - if err != nil { - return err - } - - // fetch chain information - chainLaunch, err := n.ChainLaunch(cmd.Context(), launchID) - if err != nil { - return err - } - - c, err := nb.Chain(networkchain.SourceLaunch(chainLaunch)) - if err != nil { - return err - } - - // check validity of request - err = c.CheckRequestChangeParam( - cmd.Context(), - module, - param, - value, - ) - if err != nil { - return err - } - - return n.SendParamChangeRequest( - cmd.Context(), - launchID, - module, - param, - value, - ) -} diff --git a/ignite/cmd/network_request_list.go b/ignite/cmd/network_request_list.go deleted file mode 100644 index f80a3c4614..0000000000 --- a/ignite/cmd/network_request_list.go +++ /dev/null @@ -1,176 +0,0 @@ -package ignitecmd - -import ( - "fmt" - - "github.com/spf13/cobra" - launchtypes "github.com/tendermint/spn/x/launch/types" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cosmosutil" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -var requestSummaryHeader = []string{"ID", "Status", "Type", "Content"} - -// NewNetworkRequestList creates a new request list command to list -// requests for a chain. -func NewNetworkRequestList() *cobra.Command { - c := &cobra.Command{ - Use: "list [launch-id]", - Short: "List all requests for a chain", - RunE: networkRequestListHandler, - Args: cobra.ExactArgs(1), - } - - c.Flags().AddFlagSet(flagSetSPNAccountPrefixes()) - - return c -} - -func networkRequestListHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - addressPrefix := getAddressPrefix(cmd) - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - requests, err := n.Requests(cmd.Context(), launchID) - if err != nil { - return err - } - - return renderRequestSummaries(requests, session, addressPrefix) -} - -// renderRequestSummaries writes into the provided out, the list of summarized requests. -func renderRequestSummaries( - requests []networktypes.Request, - session *cliui.Session, - addressPrefix string, -) error { - requestEntries := make([][]string, 0) - for _, request := range requests { - var ( - id = fmt.Sprintf("%d", request.RequestID) - requestType = "Unknown" - content = "" - ) - switch req := request.Content.Content.(type) { - case *launchtypes.RequestContent_GenesisAccount: - requestType = "Add Genesis Account" - - address, err := cosmosutil.ChangeAddressPrefix( - req.GenesisAccount.Address, - addressPrefix, - ) - if err != nil { - return err - } - - content = fmt.Sprintf("%s, %s", - address, - req.GenesisAccount.Coins.String()) - case *launchtypes.RequestContent_GenesisValidator: - requestType = "Add Genesis Validator" - peer, err := network.PeerAddress(req.GenesisValidator.Peer) - if err != nil { - return err - } - - address, err := cosmosutil.ChangeAddressPrefix( - req.GenesisValidator.Address, - addressPrefix, - ) - if err != nil { - return err - } - - content = fmt.Sprintf("%s, %s, %s", - peer, - address, - req.GenesisValidator.SelfDelegation.String()) - case *launchtypes.RequestContent_VestingAccount: - requestType = "Add Vesting Account" - - // parse vesting options - var vestingCoins string - dv := req.VestingAccount.VestingOptions.GetDelayedVesting() - if dv == nil { - vestingCoins = "unrecognized vesting option" - } else { - vestingCoins = fmt.Sprintf("%s (vesting: %s)", dv.TotalBalance, dv.Vesting) - } - - address, err := cosmosutil.ChangeAddressPrefix( - req.VestingAccount.Address, - addressPrefix, - ) - if err != nil { - return err - } - - content = fmt.Sprintf("%s, %s", - address, - vestingCoins, - ) - case *launchtypes.RequestContent_ValidatorRemoval: - requestType = "Remove Validator" - - address, err := cosmosutil.ChangeAddressPrefix( - req.ValidatorRemoval.ValAddress, - addressPrefix, - ) - if err != nil { - return err - } - - content = address - case *launchtypes.RequestContent_AccountRemoval: - requestType = "Remove Account" - - address, err := cosmosutil.ChangeAddressPrefix( - req.AccountRemoval.Address, - addressPrefix, - ) - if err != nil { - return err - } - - content = address - - case *launchtypes.RequestContent_ParamChange: - requestType = "Change Param" - content = fmt.Sprintf( - "module: %s param: %s, value: %s", - req.ParamChange.Module, - req.ParamChange.Param, - string(req.ParamChange.Value), - ) - } - - requestEntries = append(requestEntries, []string{ - id, - request.Status, - requestType, - content, - }) - } - return session.PrintTable(requestSummaryHeader, requestEntries...) -} diff --git a/ignite/cmd/network_request_reject.go b/ignite/cmd/network_request_reject.go deleted file mode 100644 index 57912b6894..0000000000 --- a/ignite/cmd/network_request_reject.go +++ /dev/null @@ -1,71 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/numbers" - "github.com/ignite/cli/ignite/services/network" -) - -// NewNetworkRequestReject creates a new request reject -// command to reject requests for a chain. -func NewNetworkRequestReject() *cobra.Command { - c := &cobra.Command{ - Use: "reject [launch-id] [number<,...>]", - Aliases: []string{"accept"}, - Short: "Reject requests", - Long: `The "reject" command is used by a chain's coordinator to reject requests. - - ignite network request reject 42 1,2,3-6,7,8 - -The syntax of the "reject" command is similar to that of the "approve" command. -`, - RunE: networkRequestRejectHandler, - Args: cobra.ExactArgs(2), - } - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - return c -} - -func networkRequestRejectHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - // Get the list of request ids - ids, err := numbers.ParseList(args[1]) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - // Submit the rejected requests - reviewals := make([]network.Reviewal, 0) - for _, id := range ids { - reviewals = append(reviewals, network.RejectRequest(id)) - } - if err := n.SubmitRequest(cmd.Context(), launchID, reviewals...); err != nil { - return err - } - - return session.Printf("%s Request(s) %s rejected\n", icons.OK, numbers.List(ids, "#")) -} diff --git a/ignite/cmd/network_request_remove_account.go b/ignite/cmd/network_request_remove_account.go deleted file mode 100644 index fb9bc8d031..0000000000 --- a/ignite/cmd/network_request_remove_account.go +++ /dev/null @@ -1,60 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cosmosutil" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// NewNetworkRequestRemoveAccount creates a new command to send remove account request. -func NewNetworkRequestRemoveAccount() *cobra.Command { - c := &cobra.Command{ - Use: "remove-account [launch-id] [address]", - Short: "Send request to remove a genesis account", - RunE: networkRequestRemoveAccountHandler, - Args: cobra.ExactArgs(2), - } - - flagSetClearCache(c) - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - return c -} - -func networkRequestRemoveAccountHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - // get the address for the account and change the prefix for Ignite Chain - address, err := cosmosutil.ChangeAddressPrefix(args[1], networktypes.SPN) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - return n.SendAccountRemoveRequest( - cmd.Context(), - launchID, - address, - ) -} diff --git a/ignite/cmd/network_request_remove_validator.go b/ignite/cmd/network_request_remove_validator.go deleted file mode 100644 index dd2a258dce..0000000000 --- a/ignite/cmd/network_request_remove_validator.go +++ /dev/null @@ -1,60 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cosmosutil" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// NewNetworkRequestRemoveValidator creates a new command to send remove validator request. -func NewNetworkRequestRemoveValidator() *cobra.Command { - c := &cobra.Command{ - Use: "remove-validator [launch-id] [address]", - Short: "Send request to remove a validator", - RunE: networkRequestRemoveValidatorHandler, - Args: cobra.ExactArgs(2), - } - - flagSetClearCache(c) - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - return c -} - -func networkRequestRemoveValidatorHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - // get the address for the account and change the prefix for Ignite Chain - address, err := cosmosutil.ChangeAddressPrefix(args[1], networktypes.SPN) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - return n.SendValidatorRemoveRequest( - cmd.Context(), - launchID, - address, - ) -} diff --git a/ignite/cmd/network_request_show.go b/ignite/cmd/network_request_show.go deleted file mode 100644 index 9a76b3f3f4..0000000000 --- a/ignite/cmd/network_request_show.go +++ /dev/null @@ -1,69 +0,0 @@ -package ignitecmd - -import ( - "strconv" - - "github.com/pkg/errors" - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/yaml" - "github.com/ignite/cli/ignite/services/network" -) - -// NewNetworkRequestShow creates a new request show command to show -// requests details for a chain. -func NewNetworkRequestShow() *cobra.Command { - c := &cobra.Command{ - Use: "show [launch-id] [request-id]", - Short: "Show detailed information about a request", - RunE: networkRequestShowHandler, - Args: cobra.ExactArgs(2), - } - return c -} - -func networkRequestShowHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - // parse request ID - requestID, err := strconv.ParseUint(args[1], 10, 64) - if err != nil { - return errors.Wrap(err, "error parsing requestID") - } - - n, err := nb.Network() - if err != nil { - return err - } - - request, err := n.Request(cmd.Context(), launchID, requestID) - if err != nil { - return err - } - - // convert the request object to YAML to be more readable - // and convert the byte array fields to string. - requestYaml, err := yaml.Marshal(cmd.Context(), request, - "$.Content.content.genesisValidator.genTx", - "$.Content.content.genesisValidator.consPubKey", - "$.Content.content.paramChange.value", - ) - if err != nil { - return err - } - - return session.Println(requestYaml) -} diff --git a/ignite/cmd/network_request_verify.go b/ignite/cmd/network_request_verify.go deleted file mode 100644 index 0cf51b2198..0000000000 --- a/ignite/cmd/network_request_verify.go +++ /dev/null @@ -1,128 +0,0 @@ -package ignitecmd - -import ( - "context" - "os" - - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cache" - "github.com/ignite/cli/ignite/pkg/chaincmd" - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/numbers" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networkchain" -) - -// NewNetworkRequestVerify verify the request and simulate the chain. -func NewNetworkRequestVerify() *cobra.Command { - c := &cobra.Command{ - Use: "verify [launch-id] [number<,...>]", - Short: "Verify the request and simulate the chain genesis from them", - Long: `The "verify" command applies selected requests to the genesis of a chain locally -to verify that approving these requests will result in a valid genesis that -allows a chain to launch without issues. This command does not approve requests, -only checks them. -`, - RunE: networkRequestVerifyHandler, - Args: cobra.ExactArgs(2), - } - - flagSetClearCache(c) - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - return c -} - -func networkRequestVerifyHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - // get the list of request ids - ids, err := numbers.ParseList(args[1]) - if err != nil { - return err - } - - cacheStorage, err := newCache(cmd) - if err != nil { - return err - } - - // verify the requests - - if err := verifyRequest(cmd.Context(), cacheStorage, nb, launchID, ids...); err != nil { - session.Printf("%s Request(s) %s not valid\n", icons.NotOK, numbers.List(ids, "#")) - return err - } - - return session.Printf("%s Request(s) %s verified\n", icons.OK, numbers.List(ids, "#")) -} - -// verifyRequest initialize the chain from the launch ID in a temporary directory -// and simulate the launch of the chain from genesis with the request IDs. -func verifyRequest( - ctx context.Context, - cacheStorage cache.Storage, - nb NetworkBuilder, - launchID uint64, - requestIDs ...uint64, -) error { - n, err := nb.Network() - if err != nil { - return err - } - - // initialize the chain with a temporary dir - chainLaunch, err := n.ChainLaunch(ctx, launchID) - if err != nil { - return err - } - - homeDir, err := os.MkdirTemp("", "") - if err != nil { - return err - } - defer os.RemoveAll(homeDir) - - c, err := nb.Chain( - networkchain.SourceLaunch(chainLaunch), - networkchain.WithHome(homeDir), - networkchain.WithKeyringBackend(chaincmd.KeyringBackendTest), - ) - if err != nil { - return err - } - - // fetch the current genesis information and the requests for the chain for simulation - genesisInformation, err := n.GenesisInformation(ctx, launchID) - if err != nil { - return err - } - - requests, err := n.RequestFromIDs(ctx, launchID, requestIDs...) - if err != nil { - return err - } - - return c.SimulateRequests( - ctx, - cacheStorage, - genesisInformation, - requests, - ) -} diff --git a/ignite/cmd/network_reward.go b/ignite/cmd/network_reward.go deleted file mode 100644 index eb5d4cab57..0000000000 --- a/ignite/cmd/network_reward.go +++ /dev/null @@ -1,19 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" -) - -// NewNetworkReward creates a new chain reward command. -func NewNetworkReward() *cobra.Command { - c := &cobra.Command{ - Use: "reward", - Short: "Manage network rewards", - Hidden: true, - } - c.AddCommand( - NewNetworkRewardSet(), - NewNetworkRewardRelease(), - ) - return c -} diff --git a/ignite/cmd/network_reward_release.go b/ignite/cmd/network_reward_release.go deleted file mode 100644 index 9e33bd9d3e..0000000000 --- a/ignite/cmd/network_reward_release.go +++ /dev/null @@ -1,317 +0,0 @@ -package ignitecmd - -import ( - "bytes" - "errors" - "fmt" - "text/tabwriter" - - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/cosmosaccount" - "github.com/ignite/cli/ignite/pkg/cosmosclient" - "github.com/ignite/cli/ignite/pkg/relayer" - relayerconf "github.com/ignite/cli/ignite/pkg/relayer/config" - "github.com/ignite/cli/ignite/pkg/xurl" - "github.com/ignite/cli/ignite/services/network" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -const ( - flagTestnetFaucet = "testnet-faucet" - flagTestnetAddressPrefix = "testnet-prefix" - flagTestnetAccount = "testnet-account" - flagTestnetGasPrice = "testnet-gasprice" - flagTestnetGasLimit = "testnet-gaslimit" - flagSPNGasPrice = "spn-gasprice" - flagSPNGasLimit = "spn-gaslimit" - flagCreateClientOnly = "create-client-only" - - defaultTestnetGasPrice = "0.0000025stake" - defaultSPNGasPrice = "0.0000025" + networktypes.SPNDenom - defaultGasLimit = 400000 -) - -// NewNetworkRewardRelease connects the monitoring modules of launched -// chains with SPN and distribute rewards with chain Relayer. -func NewNetworkRewardRelease() *cobra.Command { - c := &cobra.Command{ - Use: "release [launch-id] [chain-rpc]", - Short: "Connect the monitoring modules of launched chains with SPN", - Args: cobra.ExactArgs(2), - RunE: networkRewardRelease, - } - - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().String(flagSPNGasPrice, defaultSPNGasPrice, "gas price used for transactions on SPN") - c.Flags().String(flagTestnetGasPrice, defaultTestnetGasPrice, "gas price used for transactions on testnet chain") - c.Flags().Int64(flagSPNGasLimit, defaultGasLimit, "gas limit used for transactions on SPN") - c.Flags().Int64(flagTestnetGasLimit, defaultGasLimit, "gas limit used for transactions on testnet chain") - c.Flags().String(flagTestnetAddressPrefix, cosmosaccount.AccountPrefixCosmos, "address prefix of the testnet chain") - c.Flags().String(flagTestnetAccount, cosmosaccount.DefaultAccount, "testnet chain account") - c.Flags().String(flagTestnetFaucet, "", "faucet address of the testnet chain") - c.Flags().Bool(flagCreateClientOnly, false, "only create the network client id") - - return c -} - -func networkRewardRelease(cmd *cobra.Command, args []string) (err error) { - defer func() { - err = handleRelayerAccountErr(err) - }() - - session := cliui.New(cliui.StartSpinnerWithText("Setting up chains...")) - defer session.End() - - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - chainRPC := xurl.HTTPEnsurePort(args[1]) - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - n, err := nb.Network() - if err != nil { - return err - } - spnChainID, err := n.ChainID(cmd.Context()) - if err != nil { - return err - } - - ca, err := cosmosaccount.New( - cosmosaccount.WithKeyringBackend(getKeyringBackend(cmd)), - ) - if err != nil { - return err - } - - if err := ca.EnsureDefaultAccount(); err != nil { - return err - } - - var ( - createClientOnly, _ = cmd.Flags().GetBool(flagCreateClientOnly) - spnGasPrice, _ = cmd.Flags().GetString(flagSPNGasPrice) - testnetGasPrice, _ = cmd.Flags().GetString(flagTestnetGasPrice) - spnGasLimit, _ = cmd.Flags().GetInt64(flagSPNGasLimit) - testnetGasLimit, _ = cmd.Flags().GetInt64(flagTestnetGasLimit) - // TODO fetch from genesis - testnetAddressPrefix, _ = cmd.Flags().GetString(flagTestnetAddressPrefix) - testnetAccount, _ = cmd.Flags().GetString(flagTestnetAccount) - testnetFaucet, _ = cmd.Flags().GetString(flagTestnetFaucet) - ) - - session.StartSpinner("Creating network relayer client ID...") - chain, spn, err := createClient(cmd, n, session, launchID, chainRPC, spnChainID) - if err != nil { - return err - } - if createClientOnly { - return nil - } - - session.StartSpinner("Fetching chain info...") - session.Println() - - spnAddresses, err := getSpnAddresses(cmd) - if err != nil { - return err - } - - r := relayer.New(ca) - // initialize the chains - spnChain, err := initChain( - cmd, - r, - session, - relayerSource, - getFrom(cmd), - spnAddresses.NodeAddress, - spnAddresses.FaucetAddress, - spnGasPrice, - spnGasLimit, - networktypes.SPN, - spn.ClientID, - ) - if err != nil { - return err - } - spnChain.ID = spn.ChainID - - testnetChain, err := initChain( - cmd, - r, - session, - relayerTarget, - testnetAccount, - chainRPC, - testnetFaucet, - testnetGasPrice, - testnetGasLimit, - testnetAddressPrefix, - chain.ClientID, - ) - if err != nil { - return err - } - testnetChain.ID = chain.ChainID - - session.StartSpinner("Creating links between chains...") - - pathID, cfg, err := spnRelayerConfig(*spnChain, *testnetChain, spn, chain) - if err != nil { - return err - } - if spn.ChannelID == "" { - cfg, err = r.Link(cmd.Context(), cfg, pathID) - if err != nil { - return err - } - } - - if err := printSection(session, "Paths"); err != nil { - return err - } - - session.StartSpinner("Loading...") - - path, err := cfg.PathByID(pathID) - if err != nil { - return err - } - - var buf bytes.Buffer - w := tabwriter.NewWriter(&buf, 0, 0, 1, ' ', tabwriter.TabIndent) - fmt.Fprintf(w, "%s:\n", path.ID) - fmt.Fprintf(w, " \t%s\t>\t(port: %s)\t(channel: %s)\n", path.Src.ChainID, path.Src.PortID, path.Src.ChannelID) - fmt.Fprintf(w, " \t%s\t>\t(port: %s)\t(channel: %s)\n", path.Dst.ChainID, path.Dst.PortID, path.Dst.ChannelID) - fmt.Fprintln(w) - w.Flush() - session.Print(buf.String()) - - if err := printSection(session, "Listening and relaying packets between chains..."); err != nil { - return err - } - - return r.Start(cmd.Context(), cfg, pathID, nil) -} - -func createClient( - cmd *cobra.Command, - n network.Network, - session *cliui.Session, - launchID uint64, - nodeAPI, - spnChainID string, -) (networktypes.RewardIBCInfo, networktypes.RewardIBCInfo, error) { - nodeClient, err := cosmosclient.New(cmd.Context(), cosmosclient.WithNodeAddress(nodeAPI)) - if err != nil { - return networktypes.RewardIBCInfo{}, networktypes.RewardIBCInfo{}, err - } - node := network.NewNode(nodeClient) - - chainRelayer, err := node.RewardIBCInfo(cmd.Context()) - if err != nil { - return networktypes.RewardIBCInfo{}, networktypes.RewardIBCInfo{}, err - } - - rewardsInfo, chainID, unboundingTime, err := node.RewardsInfo(cmd.Context()) - if err != nil { - return networktypes.RewardIBCInfo{}, networktypes.RewardIBCInfo{}, err - } - - spnRelayer, err := n.RewardIBCInfo(cmd.Context(), launchID) - if errors.Is(err, network.ErrObjectNotFound) { - spnRelayer.ClientID, err = n.CreateClient(cmd.Context(), launchID, unboundingTime, rewardsInfo) - } - if err != nil { - return networktypes.RewardIBCInfo{}, networktypes.RewardIBCInfo{}, err - } - - chainRelayer.ChainID = chainID - spnRelayer.ChainID = spnChainID - - session.Printf( - "%s Network client: %s\n", - icons.Info, - spnRelayer.ClientID, - ) - printRelayerOptions(session, spnRelayer.ConnectionID, spnRelayer.ChainID, "connection") - printRelayerOptions(session, spnRelayer.ChannelID, spnRelayer.ChainID, "channel") - - session.Printf( - "%s Testnet chain %s client: %s\n", - icons.Info, - chainRelayer.ChainID, - chainRelayer.ClientID, - ) - printRelayerOptions(session, chainRelayer.ConnectionID, chainRelayer.ChainID, "connection") - printRelayerOptions(session, chainRelayer.ChannelID, chainRelayer.ChainID, "channel") - return chainRelayer, spnRelayer, err -} - -func printRelayerOptions(session *cliui.Session, obj, chainID, option string) { - if obj != "" { - session.Printf("%s The chain %s already have a %s: %s\n", - icons.Bullet, - chainID, - option, - obj, - ) - } -} - -func spnRelayerConfig( - srcChain, - dstChain relayer.Chain, - srcChannel, - dstChannel networktypes.RewardIBCInfo, -) (string, relayerconf.Config, error) { - var ( - pathID = relayer.PathID(srcChain.ID, dstChain.ID) - conf = relayerconf.Config{ - Version: relayerconf.SupportVersion, - Chains: []relayerconf.Chain{srcChain.Config(), dstChain.Config()}, - Paths: []relayerconf.Path{ - { - ID: pathID, - Ordering: relayer.OrderingOrdered, - Src: relayerconf.PathEnd{ - ChainID: srcChain.ID, - PortID: networktypes.SPNPortID, - Version: networktypes.SPNVersion, - ConnectionID: srcChannel.ConnectionID, - ChannelID: srcChannel.ChannelID, - }, - Dst: relayerconf.PathEnd{ - ChainID: dstChain.ID, - PortID: networktypes.ChainPortID, - Version: networktypes.SPNVersion, - ConnectionID: dstChannel.ConnectionID, - ChannelID: dstChannel.ChannelID, - }, - }, - }, - } - ) - switch { - case srcChannel.ConnectionID != "" && - srcChannel.ChannelID != "" && - dstChannel.ConnectionID != "" && - dstChannel.ChannelID != "": - return pathID, conf, nil - case srcChannel.ConnectionID == "" && - srcChannel.ChannelID == "" && - dstChannel.ConnectionID == "" && - dstChannel.ChannelID == "": - return pathID, conf, nil - } - return pathID, conf, errors.New("connection was already established and is missing in one of the chains") -} diff --git a/ignite/cmd/network_reward_set.go b/ignite/cmd/network_reward_set.go deleted file mode 100644 index 02a7e07b62..0000000000 --- a/ignite/cmd/network_reward_set.go +++ /dev/null @@ -1,62 +0,0 @@ -package ignitecmd - -import ( - "fmt" - "strconv" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/services/network" -) - -// NewNetworkRewardSet creates a new chain reward set command to -// add the chain reward to the network as a coordinator. -func NewNetworkRewardSet() *cobra.Command { - c := &cobra.Command{ - Use: "set [launch-id] [last-reward-height] [coins]", - Short: "set a network chain reward", - Args: cobra.ExactArgs(3), - RunE: networkChainRewardSetHandler, - } - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetHome()) - return c -} - -func networkChainRewardSetHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - // parse launch ID - launchID, err := network.ParseID(args[0]) - if err != nil { - return err - } - - // parse the last reward height - lastRewardHeight, err := strconv.ParseInt(args[1], 10, 64) - if err != nil { - return err - } - - coins, err := sdk.ParseCoinsNormalized(args[2]) - if err != nil { - return fmt.Errorf("failed to parse coins: %w", err) - } - - n, err := nb.Network() - if err != nil { - return err - } - - return n.SetReward(cmd.Context(), launchID, lastRewardHeight, coins) -} diff --git a/ignite/cmd/network_validator.go b/ignite/cmd/network_validator.go deleted file mode 100644 index 7e0a288287..0000000000 --- a/ignite/cmd/network_validator.go +++ /dev/null @@ -1,17 +0,0 @@ -package ignitecmd - -import "github.com/spf13/cobra" - -// NewNetworkValidator creates a new validator command -// it contains sub commands to manage validator profile. -func NewNetworkValidator() *cobra.Command { - c := &cobra.Command{ - Use: "validator", - Short: "Show and update a validator profile", - } - c.AddCommand( - NewNetworkValidatorShow(), - NewNetworkValidatorSet(), - ) - return c -} diff --git a/ignite/cmd/network_validator_set.go b/ignite/cmd/network_validator_set.go deleted file mode 100644 index 635837282f..0000000000 --- a/ignite/cmd/network_validator_set.go +++ /dev/null @@ -1,69 +0,0 @@ -package ignitecmd - -import ( - "errors" - - "github.com/spf13/cobra" - profiletypes "github.com/tendermint/spn/x/profile/types" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/cliui/icons" -) - -// NewNetworkValidatorSet creates a command to set an information in a validator profile. -func NewNetworkValidatorSet() *cobra.Command { - c := &cobra.Command{ - Use: "set details|identity|website|security [value]", - Short: "Set an information in a validator profile", - Long: `Validators on Ignite can set a profile containing a description for the validator. -The validator set command allows to set information for the validator. -The following information can be set: -- details: general information about the validator. -- identity: piece of information to verify identity of the validator with a system like Keybase of Veramo. -- website: website of the validator. -- security: security contact for the validator. -`, - RunE: networkValidatorSetHandler, - Args: cobra.ExactArgs(2), - } - c.Flags().AddFlagSet(flagNetworkFrom()) - c.Flags().AddFlagSet(flagSetHome()) - c.Flags().AddFlagSet(flagSetKeyringBackend()) - c.Flags().AddFlagSet(flagSetKeyringDir()) - return c -} - -func networkValidatorSetHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - var validator profiletypes.Validator - switch args[0] { - case "details": - validator.Description.Details = args[1] - case "identity": - validator.Description.Identity = args[1] - case "website": - validator.Description.Website = args[1] - case "security": - validator.Description.SecurityContact = args[1] - default: - return errors.New("invalid attribute, must provide details, identity, website or security") - } - - if err := n.SetValidatorDescription(cmd.Context(), validator); err != nil { - return err - } - - return session.Printf("%s Validator updated \n", icons.OK) -} diff --git a/ignite/cmd/network_validator_show.go b/ignite/cmd/network_validator_show.go deleted file mode 100644 index 4c7b8bc1cf..0000000000 --- a/ignite/cmd/network_validator_show.go +++ /dev/null @@ -1,58 +0,0 @@ -package ignitecmd - -import ( - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cliui" - "github.com/ignite/cli/ignite/pkg/yaml" -) - -// NewNetworkValidatorShow creates a command to show validator information. -func NewNetworkValidatorShow() *cobra.Command { - c := &cobra.Command{ - Use: "show [address]", - Short: "Show a validator profile", - RunE: networkValidatorShowHandler, - Args: cobra.ExactArgs(1), - } - return c -} - -func networkValidatorShowHandler(cmd *cobra.Command, args []string) error { - session := cliui.New(cliui.StartSpinner()) - defer session.End() - - nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) - if err != nil { - return err - } - - n, err := nb.Network() - if err != nil { - return err - } - - validator, err := n.Validator(cmd.Context(), args[0]) - if err != nil { - return err - } - - // convert the request object to YAML to be more readable - // and convert the byte array fields to string. - validatorYaml, err := yaml.Marshal(cmd.Context(), struct { - Identity string - Details string - Website string - Security string - }{ - validator.Identity, - validator.Details, - validator.Website, - validator.SecurityContact, - }) - if err != nil { - return err - } - - return session.Println(validatorYaml) -} diff --git a/ignite/cmd/plugin.go b/ignite/cmd/plugin.go index f50882e090..a6adca70a3 100644 --- a/ignite/cmd/plugin.go +++ b/ignite/cmd/plugin.go @@ -31,9 +31,11 @@ var plugins []*plugin.Plugin // LoadPlugins tries to load all the plugins found in configurations. // If no configurations found, it returns w/o error. -func LoadPlugins(ctx context.Context, rootCmd *cobra.Command) error { - pluginsConfigs := make([]pluginsconfig.Plugin, 0) - +func LoadPlugins(ctx context.Context, cmd *cobra.Command) error { + var ( + rootCmd = cmd.Root() + pluginsConfigs []pluginsconfig.Plugin + ) localCfg, err := parseLocalPlugins(rootCmd) if err != nil && !errors.As(err, &cosmosanalysis.ErrPathNotChain{}) { return err @@ -45,6 +47,7 @@ func LoadPlugins(ctx context.Context, rootCmd *cobra.Command) error { if err == nil { pluginsConfigs = append(pluginsConfigs, globalCfg.Plugins...) } + ensureDefaultPlugins(cmd, globalCfg) if len(pluginsConfigs) == 0 { return nil @@ -103,10 +106,10 @@ func parseGlobalPlugins() (cfg *pluginsconfig.Config, err error) { func linkPlugins(rootCmd *cobra.Command, plugins []*plugin.Plugin) error { // Link plugins to related commands - var loadErrors []string + var linkErrors []*plugin.Plugin for _, p := range plugins { if p.Error != nil { - loadErrors = append(loadErrors, p.Path) + linkErrors = append(linkErrors, p) continue } manifest, err := p.Interface.Manifest() @@ -116,16 +119,16 @@ func linkPlugins(rootCmd *cobra.Command, plugins []*plugin.Plugin) error { } linkPluginHooks(rootCmd, p, manifest.Hooks) if p.Error != nil { - loadErrors = append(loadErrors, p.Path) + linkErrors = append(linkErrors, p) continue } linkPluginCmds(rootCmd, p, manifest.Commands) if p.Error != nil { - loadErrors = append(loadErrors, p.Path) + linkErrors = append(linkErrors, p) continue } } - if len(loadErrors) > 0 { + if len(linkErrors) > 0 { // unload any plugin that could have been loaded defer UnloadPlugins() if err := printPlugins(cliui.New(cliui.WithStdout(os.Stdout))); err != nil { @@ -133,7 +136,11 @@ func linkPlugins(rootCmd *cobra.Command, plugins []*plugin.Plugin) error { // return here, just print the error. fmt.Printf("fail to print: %v\n", err) } - return errors.Errorf("fail to load: %v", strings.Join(loadErrors, ",")) + var s strings.Builder + for _, p := range linkErrors { + fmt.Fprintf(&s, "%s: %v", p.Path, p.Error) + } + return errors.Errorf("fail to link: %v", s.String()) } return nil } @@ -157,22 +164,11 @@ func linkPluginHooks(rootCmd *cobra.Command, p *plugin.Plugin, hooks []plugin.Ho func linkPluginHook(rootCmd *cobra.Command, p *plugin.Plugin, hook plugin.Hook) { cmdPath := hook.PlaceHookOn - - if !strings.HasPrefix(cmdPath, "ignite") { - // cmdPath must start with `ignite ` before comparison with - // cmd.CommandPath() - cmdPath = igniteCmdPrefix + cmdPath - } - - cmdPath = strings.TrimSpace(cmdPath) - cmd := findCommandByPath(rootCmd, cmdPath) - if cmd == nil { p.Error = errors.Errorf("unable to find commandPath %q for plugin hook %q", cmdPath, hook.Name) return } - if !cmd.Runnable() { p.Error = errors.Errorf("can't attach plugin hook %q to non executable command %q", hook.Name, hook.PlaceHookOn) return @@ -182,13 +178,14 @@ func linkPluginHook(rootCmd *cobra.Command, p *plugin.Plugin, hook plugin.Hook) execHook := plugin.ExecutedHook{ Hook: hook, ExecutedCommand: plugin.ExecutedCommand{ - Use: cmd.Use, - Path: cmd.CommandPath(), - Args: args, - With: p.With, + Use: cmd.Use, + Path: cmd.CommandPath(), + Args: args, + OSArgs: os.Args, + With: p.With, }, } - execHook.ExecutedCommand.SetFlags(cmd.Flags()) + execHook.ExecutedCommand.SetFlags(cmd) return execHook } @@ -269,13 +266,6 @@ func linkPluginCmds(rootCmd *cobra.Command, p *plugin.Plugin, pluginCmds []plugi func linkPluginCmd(rootCmd *cobra.Command, p *plugin.Plugin, pluginCmd plugin.Command) { cmdPath := pluginCmd.PlaceCommandUnder - if !strings.HasPrefix(cmdPath, "ignite") { - // cmdPath must start with `ignite ` before comparison with - // cmd.CommandPath() - cmdPath = igniteCmdPrefix + cmdPath - } - cmdPath = strings.TrimSpace(cmdPath) - cmd := findCommandByPath(rootCmd, cmdPath) if cmd == nil { p.Error = errors.Errorf("unable to find commandPath %q for plugin %q", cmdPath, p.Path) @@ -285,36 +275,43 @@ func linkPluginCmd(rootCmd *cobra.Command, p *plugin.Plugin, pluginCmd plugin.Co p.Error = errors.Errorf("can't attach plugin command %q to runnable command %q", pluginCmd.Use, cmd.CommandPath()) return } + + // Check for existing commands + // pluginCmd.Use can be like `command [args]` so we need to remove those + // extra args if any. + pluginCmdName := strings.Split(pluginCmd.Use, " ")[0] for _, cmd := range cmd.Commands() { - if cmd.Name() == pluginCmd.Use { - p.Error = errors.Errorf("plugin command %q already exists in ignite's commands", pluginCmd.Use) + if cmd.Name() == pluginCmdName { + p.Error = errors.Errorf("plugin command %q already exists in ignite's commands", pluginCmdName) return } } - newCmd := &cobra.Command{ - Use: pluginCmd.Use, - Short: pluginCmd.Short, - Long: pluginCmd.Long, - } - for _, f := range pluginCmd.Flags { - err := f.FeedFlagSet(newCmd.Flags()) - if err != nil { - p.Error = err - return - } + + newCmd, err := pluginCmd.ToCobraCommand() + if err != nil { + p.Error = err + return } cmd.AddCommand(newCmd) + + // NOTE(tb) we could probably simplify by removing this condition and call the + // plugin even if the invoked command isn't runnable. If we do so, the plugin + // will be responsible for outputing the standard cobra output, which implies + // it must use cobra too. This is how cli-plugin-network works, but to make + // it for all, we need to change the `plugin scaffold` output (so it outputs + // something similar than the cli-plugin-network) and update the docs. if len(pluginCmd.Commands) == 0 { // pluginCmd has no sub commands, so it's runnable newCmd.RunE = func(cmd *cobra.Command, args []string) error { return clictx.Do(cmd.Context(), func() error { execCmd := plugin.ExecutedCommand{ - Use: cmd.Use, - Path: cmd.CommandPath(), - Args: args, - With: p.With, + Use: cmd.Use, + Path: cmd.CommandPath(), + Args: args, + OSArgs: os.Args, + With: p.With, } - execCmd.SetFlags(cmd.Flags()) + execCmd.SetFlags(cmd) // Call the plugin Execute err := p.Interface.Execute(execCmd) // NOTE(tb): This pause gives enough time for go-plugin to sync the @@ -336,6 +333,13 @@ func linkPluginCmd(rootCmd *cobra.Command, p *plugin.Plugin, pluginCmd plugin.Co } func findCommandByPath(cmd *cobra.Command, cmdPath string) *cobra.Command { + if !strings.HasPrefix(cmdPath, "ignite") { + // cmdPath must start with `ignite ` before comparison with + // cmd.CommandPath() + cmdPath = igniteCmdPrefix + cmdPath + } + cmdPath = strings.TrimSpace(cmdPath) + if cmd.CommandPath() == cmdPath { return cmd } @@ -472,6 +476,8 @@ Example: if err != nil { return err } + defer plugins[0].KillClient() + if plugins[0].Error != nil { return fmt.Errorf("error while loading plugin %q: %w", args[0], plugins[0].Error) } diff --git a/ignite/cmd/plugin_default.go b/ignite/cmd/plugin_default.go new file mode 100644 index 0000000000..0ed7ab1178 --- /dev/null +++ b/ignite/cmd/plugin_default.go @@ -0,0 +1,108 @@ +package ignitecmd + +import ( + "fmt" + + "github.com/spf13/cobra" + + pluginsconfig "github.com/ignite/cli/ignite/config/plugins" + "github.com/ignite/cli/ignite/pkg/cliui" + "github.com/ignite/cli/ignite/services/plugin" +) + +type defaultPlugin struct { + use string + short string + aliases []string + path string +} + +const ( + PluginNetworkVersion = "main" + PluginNetworkPath = "github.com/ignite/cli-plugin-network@" + PluginNetworkVersion +) + +// defaultPlugins holds the plugin that are considered trustable and for which +// a command will added if the plugin is not already installed. +// When the user executes that command, the plugin is automatically installed. +var defaultPlugins = []defaultPlugin{ + { + use: "network", + short: "Launch a blockchain in production", + aliases: []string{"n"}, + path: PluginNetworkPath, + }, +} + +// ensureDefaultPlugins ensures that all defaultPlugins are wether registered +// in cfg OR have an install command added to rootCmd. +func ensureDefaultPlugins(rootCmd *cobra.Command, cfg *pluginsconfig.Config) { + for _, dp := range defaultPlugins { + // Check if plugin is declared in global config + if cfg.HasPlugin(dp.path) { + // plugin found nothing to do + continue + } + // plugin not found in config, add a proxy install command + rootCmd.AddCommand(newPluginInstallCmd(dp)) + } +} + +// newPluginInstallCmd mimics the plugin command but acts as proxy to first: +// - register the config in the global config +// - load the plugin +// - execute the command thanks to the loaded plugin. +func newPluginInstallCmd(dp defaultPlugin) *cobra.Command { + return &cobra.Command{ + Use: dp.use, + Short: dp.short, + Aliases: dp.aliases, + DisableFlagParsing: true, // Avoid -h to skip command run + RunE: func(cmd *cobra.Command, _ []string) error { + cfg, err := parseGlobalPlugins() + if err != nil { + return err + } + if cfg.HasPlugin(dp.path) { + // plugin already declared in global plugins, this shouldn't happen + // because this is actually why this command has been added, so let's + // break violently + panic(fmt.Sprintf("plugin %q unexpected in global config", dp.path)) + } + + // add plugin to config + pluginCfg := pluginsconfig.Plugin{ + Path: dp.path, + } + cfg.Plugins = append(cfg.Plugins, pluginCfg) + if err := cfg.Save(); err != nil { + return err + } + + session := cliui.New() + defer session.End() + + // load and link the plugin + plugins, err := plugin.Load( + cmd.Context(), + []pluginsconfig.Plugin{pluginCfg}, + plugin.CollectEvents(session.EventBus()), + ) + if err != nil { + return err + } + defer plugins[0].KillClient() + + // Keep reference of the root command before removal + rootCmd := cmd.Root() + // Remove this command before call to linkPlugins because a plugin is + // usually not allowed to override an existing command. + rootCmd.RemoveCommand(cmd) + if err := linkPlugins(rootCmd, plugins); err != nil { + return err + } + // Execute the command + return rootCmd.Execute() + }, + } +} diff --git a/ignite/cmd/plugin_default_test.go b/ignite/cmd/plugin_default_test.go new file mode 100644 index 0000000000..cf498eb0a2 --- /dev/null +++ b/ignite/cmd/plugin_default_test.go @@ -0,0 +1,46 @@ +package ignitecmd + +import ( + "testing" + + "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" + + pluginsconfig "github.com/ignite/cli/ignite/config/plugins" +) + +func TestEnsureDefaultPlugins(t *testing.T) { + tests := []struct { + name string + cfg *pluginsconfig.Config + expectAddedInCommand bool + }{ + { + name: "empty config", + cfg: &pluginsconfig.Config{}, + expectAddedInCommand: true, + }, + { + name: "config with default plugin", + cfg: &pluginsconfig.Config{ + Plugins: []pluginsconfig.Plugin{{ + Path: "github.com/ignite/cli-plugin-network@v42", + }}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := &cobra.Command{Use: "ignite"} + + ensureDefaultPlugins(cmd, tt.cfg) + + expectedCmd := findCommandByPath(cmd, "network") + if tt.expectAddedInCommand { + assert.NotNil(t, expectedCmd) + } else { + assert.Nil(t, expectedCmd) + } + }) + } +} diff --git a/ignite/cmd/plugin_test.go b/ignite/cmd/plugin_test.go index ee5f458b29..6fe44382a2 100644 --- a/ignite/cmd/plugin_test.go +++ b/ignite/cmd/plugin_test.go @@ -200,6 +200,21 @@ ignite }, expectedError: `plugin command "scaffold" already exists in ignite's commands`, }, + { + name: "fail: plugin name with args exists in legacy commands", + setup: func(t *testing.T, p *mocks.PluginInterface) { + p.EXPECT().Manifest().Return(plugin.Manifest{ + Commands: []plugin.Command{ + { + Use: "scaffold [args]", + }, + }, + }, + nil, + ) + }, + expectedError: `plugin command "scaffold" already exists in ignite's commands`, + }, { name: "fail: plugin name exists in legacy sub commands", setup: func(t *testing.T, p *mocks.PluginInterface) { diff --git a/ignite/cmd/relayer_configure.go b/ignite/cmd/relayer_configure.go index c89fd59bbc..5613834fec 100644 --- a/ignite/cmd/relayer_configure.go +++ b/ignite/cmd/relayer_configure.go @@ -38,8 +38,8 @@ const ( flagSourceClientID = "source-client-id" flagTargetClientID = "target-client-id" - relayerSource = "source" - relayerTarget = "target" + RelayerSource = "source" + RelayerTarget = "target" defaultSourceRPCAddress = "http://localhost:26657" defaultTargetRPCAddress = "https://rpc.cosmos.network:443" @@ -387,11 +387,11 @@ func relayerConfigureHandler(cmd *cobra.Command, _ []string) (err error) { r := relayer.New(ca) // initialize the chains - sourceChain, err := initChain( + sourceChain, err := InitChain( cmd, r, session, - relayerSource, + RelayerSource, sourceAccount, sourceRPCAddress, sourceFaucetAddress, @@ -408,11 +408,11 @@ func relayerConfigureHandler(cmd *cobra.Command, _ []string) (err error) { return err } - targetChain, err := initChain( + targetChain, err := InitChain( cmd, r, session, - relayerTarget, + RelayerTarget, targetAccount, targetRPCAddress, targetFaucetAddress, @@ -455,8 +455,8 @@ func relayerConfigureHandler(cmd *cobra.Command, _ []string) (err error) { return session.Printf("⛓ Configured chains: %s\n\n", color.Green.Sprint(id)) } -// initChain initializes chain information for the relayer connection. -func initChain( +// InitChain initializes chain information for the relayer connection. +func InitChain( cmd *cobra.Command, r relayer.Relayer, session *cliui.Session, diff --git a/ignite/config/plugins/config.go b/ignite/config/plugins/config.go index e8fab5168b..e2740eeb84 100644 --- a/ignite/config/plugins/config.go +++ b/ignite/config/plugins/config.go @@ -6,7 +6,10 @@ import ( "os" "strings" + "golang.org/x/exp/slices" "gopkg.in/yaml.v2" + + "github.com/ignite/cli/ignite/pkg/gomodule" ) type Config struct { @@ -71,6 +74,16 @@ func RemoveDuplicates(plugins []Plugin) (unique []Plugin) { return unique } +// IsGlobal returns whether the plugin is installed globally or locally for a chain. +func (p Plugin) IsGlobal() bool { + return p.Global +} + +// IsLocalPath returns true if the plugin path is a local directory. +func (p Plugin) IsLocalPath() bool { + return strings.HasPrefix(p.Path, "/") +} + // HasPath verifies if a plugin has the given path regardless of version. // Example: // github.com/foo/bar@v1 and github.com/foo/bar@v2 have the same path so "true" @@ -116,3 +129,24 @@ func (c *Config) Save() error { } return nil } + +// HasPlugin returns true if c contains a plugin with given path. +// Returns also true if there's a local plugin with the module name equal to +// that path. +func (c Config) HasPlugin(path string) bool { + return slices.ContainsFunc(c.Plugins, func(cp Plugin) bool { + if cp.HasPath(path) { + return true + } + if cp.IsLocalPath() { + // check local plugin go.mod to see if module name match plugin path + gm, err := gomodule.ParseAt(cp.Path) + if err != nil { + // Skip if we can't parse gomod + return false + } + return Plugin{Path: gm.Module.Mod.Path}.HasPath(path) + } + return false + }) +} diff --git a/ignite/config/plugins/config_test.go b/ignite/config/plugins/config_test.go index 231d202248..b560b6f770 100644 --- a/ignite/config/plugins/config_test.go +++ b/ignite/config/plugins/config_test.go @@ -5,11 +5,23 @@ import ( "path" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" pluginsconfig "github.com/ignite/cli/ignite/config/plugins" ) +func TestPluginIsGlobal(t *testing.T) { + assert.False(t, pluginsconfig.Plugin{}.IsGlobal()) + assert.True(t, pluginsconfig.Plugin{Global: true}.IsGlobal()) +} + +func TestPluginIsLocalPath(t *testing.T) { + assert.False(t, pluginsconfig.Plugin{}.IsLocalPath()) + assert.False(t, pluginsconfig.Plugin{Path: "github.com/ignite/example"}.IsLocalPath()) + assert.True(t, pluginsconfig.Plugin{Path: "/home/bob/example"}.IsLocalPath()) +} + func TestPluginHasPath(t *testing.T) { tests := []struct { name string @@ -58,6 +70,7 @@ func TestPluginHasPath(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { res := tt.plugin.HasPath(tt.path) + require.Equal(t, tt.expectedRes, res) }) } @@ -309,3 +322,54 @@ func TestConfigSave(t *testing.T) { }) } } + +func TestConfigHasPlugin(t *testing.T) { + wd, err := os.Getwd() + require.NoError(t, err) + tests := []struct { + name string + cfg pluginsconfig.Config + expectedFound bool + }{ + { + name: "empty config", + expectedFound: false, + }, + { + name: "not found in config", + cfg: pluginsconfig.Config{ + Plugins: []pluginsconfig.Plugin{ + {Path: "github.com/ignite/example2"}, + }, + }, + expectedFound: false, + }, + { + name: "found in config", + cfg: pluginsconfig.Config{ + Plugins: []pluginsconfig.Plugin{ + {Path: "github.com/ignite/example2"}, + {Path: "github.com/ignite/example@master"}, + }, + }, + expectedFound: true, + }, + { + name: "found in config but from a local plugin", + cfg: pluginsconfig.Config{ + Plugins: []pluginsconfig.Plugin{ + {Path: "github.com/ignite/example2"}, + {Path: path.Join(wd, "testdata", "localplugin", "example")}, + }, + }, + expectedFound: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + found := tt.cfg.HasPlugin("github.com/ignite/example@v42") + + assert.Equal(t, tt.expectedFound, found) + }) + } +} diff --git a/ignite/config/plugins/testdata/localplugin/example/go.mod b/ignite/config/plugins/testdata/localplugin/example/go.mod new file mode 100644 index 0000000000..3728f00223 --- /dev/null +++ b/ignite/config/plugins/testdata/localplugin/example/go.mod @@ -0,0 +1,3 @@ +module github.com/ignite/example + +go 1.19 diff --git a/ignite/internal/tools/gen-cli-docs/main.go b/ignite/internal/tools/gen-cli-docs/main.go index ca36c714b2..20f4924229 100644 --- a/ignite/internal/tools/gen-cli-docs/main.go +++ b/ignite/internal/tools/gen-cli-docs/main.go @@ -5,6 +5,7 @@ package main import ( "bufio" "bytes" + "context" "flag" "fmt" "io" @@ -17,6 +18,9 @@ import ( "github.com/spf13/cobra/doc" ignitecmd "github.com/ignite/cli/ignite/cmd" + pluginsconfig "github.com/ignite/cli/ignite/config/plugins" + "github.com/ignite/cli/ignite/pkg/env" + "github.com/ignite/cli/ignite/services/plugin" ) const head = `--- @@ -32,13 +36,47 @@ Documentation for Ignite CLI. func main() { outPath := flag.String("out", ".", ".md file path to place Ignite CLI docs inside") flag.Parse() + if err := run(*outPath); err != nil { + log.Fatal(err) + } +} - // Run ExecuteC so cobra adds the completion command. - cmd, _ := ignitecmd.New().ExecuteC() +func run(outPath string) error { + // We want to have documentation for commands that are implemented in plugins. + // To do that, we need to add the related plugins in the config. + // To avoid conflicts with user config, set an alternate config dir in tmp. + dir, err := os.MkdirTemp("", ".ignite") + if err != nil { + return err + } + defer os.RemoveAll(dir) + env.SetConfigDir(dir) + pluginDir, err := plugin.PluginsPath() + if err != nil { + return err + } + cfg, err := pluginsconfig.ParseDir(pluginDir) + if err != nil { + return err + } + cfg.Plugins = append(cfg.Plugins, pluginsconfig.Plugin{ + // Add network plugin + Path: ignitecmd.PluginNetworkPath, + }) + if err := cfg.Save(); err != nil { + return err + } - if err := generate(cmd, *outPath); err != nil { - log.Fatal(err) + cmd, cleanUp, err := ignitecmd.New(context.Background()) + if err != nil { + return err } + defer cleanUp() + + // Run ExecuteC so cobra adds the completion command. + cmd, _ = cmd.ExecuteC() + + return generate(cmd, outPath) } func generate(cmd *cobra.Command, outPath string) error { diff --git a/ignite/pkg/cosmoscmd/proxy.go b/ignite/pkg/cosmoscmd/proxy.go deleted file mode 100644 index 7cac40f5d8..0000000000 --- a/ignite/pkg/cosmoscmd/proxy.go +++ /dev/null @@ -1,82 +0,0 @@ -package cosmoscmd - -import ( - "path/filepath" - "time" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/server" - "github.com/spf13/cobra" - - "github.com/ignite/cli/ignite/pkg/cosmosutil" - "github.com/ignite/cli/ignite/pkg/ctxticker" - "github.com/ignite/cli/ignite/pkg/gitpod" - "github.com/ignite/cli/ignite/pkg/xchisel" - "github.com/ignite/cli/ignite/services/network/networkchain" -) - -const TunnelRerunDelay = 5 * time.Second - -// startProxyForTunneledPeers hooks the `appd start` command to start an HTTP proxy server and HTTP proxy clients -// for each node that needs HTTP tunneling. -// HTTP tunneling is activated ** ONLY** if your app's `$APP_HOME/config` dir has an `spn.yml` file -// and only if this file has `tunneled_peers` field inside with a list of tunneled peers/nodes. -// -// If you're using SPN as coordinator and do not want to allow HTTP tunneling feature at all, -// you can prevent `spn.yml` file to being generated by not approving validator requests -// that has HTTP tunneling enabled instead of plain TCP connections. -func startProxyForTunneledPeers(clientCtx client.Context, cmd *cobra.Command) { - if cmd.Name() != "start" { - return - } - serverCtx := server.GetServerContextFromCmd(cmd) - ctx := cmd.Context() - - spnConfigPath := filepath.Join(clientCtx.HomeDir, cosmosutil.ChainConfigDir, networkchain.SPNConfigFile) - spnConfig, err := networkchain.GetSPNConfig(spnConfigPath) - if err != nil { - serverCtx.Logger.Error("Failed to open spn config file", "reason", err.Error()) - return - } - // exit if there aren't tunneled validators in the network - if len(spnConfig.TunneledPeers) == 0 { - return - } - - for _, peer := range spnConfig.TunneledPeers { - if peer.Name == networkchain.HTTPTunnelChisel { - peer := peer - go func() { - ctxticker.DoNow(ctx, TunnelRerunDelay, func() error { - serverCtx.Logger.Info("Starting chisel client", "tunnelAddress", peer.Address, "localPort", peer.LocalPort) - err := xchisel.StartClient(ctx, peer.Address, peer.LocalPort, "26656") - if err != nil { - serverCtx.Logger.Error("Failed to start chisel client", - "tunnelAddress", peer.Address, - "localPort", peer.LocalPort, - "reason", err.Error(), - ) - } - return nil - }) - }() - } - } - - if gitpod.IsOnGitpod() { - go func() { - ctxticker.DoNow(ctx, TunnelRerunDelay, func() error { - serverCtx.Logger.Info("Starting chisel server", "port", xchisel.DefaultServerPort) - err := xchisel.StartServer(ctx, xchisel.DefaultServerPort) - if err != nil { - serverCtx.Logger.Error( - "Failed to start chisel server", - "port", xchisel.DefaultServerPort, - "reason", err.Error(), - ) - } - return nil - }) - }() - } -} diff --git a/ignite/pkg/cosmoscmd/root.go b/ignite/pkg/cosmoscmd/root.go index b3e881f606..e2afc74bc6 100644 --- a/ignite/pkg/cosmoscmd/root.go +++ b/ignite/pkg/cosmoscmd/root.go @@ -170,7 +170,7 @@ func NewRootCmd( return err } - startProxyForTunneledPeers(initClientCtx, cmd) + // startProxyForTunneledPeers(initClientCtx, cmd) return nil }, diff --git a/ignite/pkg/cosmosutil/peer.go b/ignite/pkg/cosmosutil/peer.go deleted file mode 100644 index 838b287732..0000000000 --- a/ignite/pkg/cosmosutil/peer.go +++ /dev/null @@ -1,28 +0,0 @@ -package cosmosutil - -import ( - "strings" - - launchtypes "github.com/tendermint/spn/x/launch/types" - - "github.com/ignite/cli/ignite/pkg/xurl" -) - -// VerifyPeerFormat checks if the peer address format is valid. -func VerifyPeerFormat(peer launchtypes.Peer) bool { - // Check the format of the peer - switch conn := peer.Connection.(type) { - case *launchtypes.Peer_TcpAddress: - nodeHost := strings.Split(conn.TcpAddress, ":") - if len(nodeHost) != 2 || - len(nodeHost[0]) == 0 || - len(nodeHost[1]) == 0 { - return false - } - return true - case *launchtypes.Peer_HttpTunnel: - return xurl.IsHTTP(conn.HttpTunnel.Address) - default: - return false - } -} diff --git a/ignite/pkg/cosmosutil/peer_test.go b/ignite/pkg/cosmosutil/peer_test.go deleted file mode 100644 index a3bbbdd189..0000000000 --- a/ignite/pkg/cosmosutil/peer_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package cosmosutil - -import ( - "testing" - - "github.com/stretchr/testify/require" - launchtypes "github.com/tendermint/spn/x/launch/types" -) - -func TestVerifyPeerFormat(t *testing.T) { - tests := []struct { - name string - peer launchtypes.Peer - want bool - }{ - { - name: "valid peer connection", - peer: launchtypes.NewPeerConn("node", "peer:port"), - want: true, - }, - { - name: "peer connection without port", - peer: launchtypes.NewPeerConn("node", "peer"), - want: false, - }, - { - name: "peer connection without the node address", - peer: launchtypes.NewPeerConn("node", ":port"), - want: false, - }, - { - name: "peer connection without the separator", - peer: launchtypes.NewPeerConn("node", "peerport"), - want: false, - }, - { - name: "invalid peer tunnel", - peer: launchtypes.NewPeerTunnel("", "", ""), - want: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := VerifyPeerFormat(tt.peer) - require.Equal(t, tt.want, got) - }) - } -} diff --git a/ignite/pkg/gocmd/gocmd.go b/ignite/pkg/gocmd/gocmd.go index 6ef97bfde2..a24ed82e11 100644 --- a/ignite/pkg/gocmd/gocmd.go +++ b/ignite/pkg/gocmd/gocmd.go @@ -100,15 +100,14 @@ func BuildPath(ctx context.Context, output, binary, path string, flags []string, return exec.Exec(ctx, command, append(options, exec.StepOption(step.Workdir(path)))...) } -// BuildAll runs go build ./... on path with options. -func BuildAll(ctx context.Context, out, path string, flags []string, options ...exec.Option) error { +// Build runs go build on path with options. +func Build(ctx context.Context, out, path string, flags []string, options ...exec.Option) error { command := []string{ Name(), CommandBuild, FlagOut, out, } command = append(command, flags...) - command = append(command, "./...") return exec.Exec(ctx, command, append(options, exec.StepOption(step.Workdir(path)))...) } diff --git a/ignite/services/chain/chain.go b/ignite/services/chain/chain.go index d2a75625a3..7edf809b70 100644 --- a/ignite/services/chain/chain.go +++ b/ignite/services/chain/chain.go @@ -7,7 +7,6 @@ import ( "path/filepath" "github.com/go-git/go-git/v5" - "github.com/tendermint/spn/pkg/chainid" chainconfig "github.com/ignite/cli/ignite/config/chain" chainconfigv1 "github.com/ignite/cli/ignite/config/chain/v1" @@ -241,11 +240,6 @@ func (c *Chain) ID() (string, error) { return c.app.N(), nil } -// ChainID returns the default network chain's id. -func (c *Chain) ChainID() (string, error) { - return chainid.NewGenesisChainID(c.Name(), 1), nil -} - // Name returns the chain's name. func (c *Chain) Name() string { return c.app.N() diff --git a/ignite/services/network/client.go b/ignite/services/network/client.go deleted file mode 100644 index 7cc5d4e022..0000000000 --- a/ignite/services/network/client.go +++ /dev/null @@ -1,100 +0,0 @@ -package network - -import ( - "context" - "errors" - - monitoringctypes "github.com/tendermint/spn/x/monitoringc/types" - - "github.com/ignite/cli/ignite/pkg/cosmoserror" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// CreateClient send create client message to SPN. -func (n Network) CreateClient( - ctx context.Context, - launchID uint64, - unbondingTime int64, - rewardsInfo networktypes.Reward, -) (string, error) { - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return "", err - } - - msgCreateClient := monitoringctypes.NewMsgCreateClient( - addr, - launchID, - rewardsInfo.ConsensusState, - rewardsInfo.ValidatorSet, - unbondingTime, - rewardsInfo.RevisionHeight, - ) - - res, err := n.cosmos.BroadcastTx(ctx, n.account, msgCreateClient) - if err != nil { - return "", err - } - - var createClientRes monitoringctypes.MsgCreateClientResponse - if err := res.Decode(&createClientRes); err != nil { - return "", err - } - return createClientRes.ClientID, nil -} - -// verifiedClientIDs fetches the verified client ids from SPN by launch id. -func (n Network) verifiedClientIDs(ctx context.Context, launchID uint64) ([]string, error) { - res, err := n.monitoringConsumerQuery. - VerifiedClientIds(ctx, - &monitoringctypes.QueryGetVerifiedClientIdsRequest{ - LaunchID: launchID, - }, - ) - - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return nil, ErrObjectNotFound - } else if err != nil { - return nil, err - } - return res.ClientIds, nil -} - -// RewardIBCInfo returns IBC info to relay packets for a chain to claim rewards. -func (n Network) RewardIBCInfo(ctx context.Context, launchID uint64) (networktypes.RewardIBCInfo, error) { - clientStates, err := n.verifiedClientIDs(ctx, launchID) - if err != nil { - return networktypes.RewardIBCInfo{}, err - } - if len(clientStates) == 0 { - return networktypes.RewardIBCInfo{}, ErrObjectNotFound - } - - clientID := clientStates[0] - - connections, err := n.node.clientConnections(ctx, clientID) - if err != nil && !errors.Is(err, ErrObjectNotFound) { - return networktypes.RewardIBCInfo{}, err - } - if errors.Is(err, ErrObjectNotFound) || len(connections) == 0 { - return networktypes.RewardIBCInfo{}, nil - } - - connectionID := connections[0] - - channels, err := n.node.connectionChannels(ctx, connectionID) - if err != nil && !errors.Is(err, ErrObjectNotFound) { - return networktypes.RewardIBCInfo{}, err - } - if errors.Is(err, ErrObjectNotFound) || len(connections) == 0 { - return networktypes.RewardIBCInfo{}, nil - } - - info := networktypes.RewardIBCInfo{ - ClientID: clientID, - ConnectionID: connectionID, - ChannelID: channels[0], - } - - return info, nil -} diff --git a/ignite/services/network/join.go b/ignite/services/network/join.go deleted file mode 100644 index e96d175e7e..0000000000 --- a/ignite/services/network/join.go +++ /dev/null @@ -1,101 +0,0 @@ -package network - -import ( - "context" - - sdk "github.com/cosmos/cosmos-sdk/types" - launchtypes "github.com/tendermint/spn/x/launch/types" - - "github.com/ignite/cli/ignite/pkg/cosmosutil" - "github.com/ignite/cli/ignite/pkg/xurl" - "github.com/ignite/cli/ignite/services/network/networkchain" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -type joinOptions struct { - accountAmount sdk.Coins - publicAddress string -} - -type JoinOption func(*joinOptions) - -// WithAccountRequest allows to join the chain by requesting a genesis account with the specified amount of tokens. -func WithAccountRequest(amount sdk.Coins) JoinOption { - return func(o *joinOptions) { - o.accountAmount = amount - } -} - -// WithPublicAddress allows to specify a peer public address for the node. -func WithPublicAddress(addr string) JoinOption { - return func(o *joinOptions) { - o.publicAddress = addr - } -} - -// Join to the network. -func (n Network) Join( - ctx context.Context, - c Chain, - launchID uint64, - gentxPath string, - options ...JoinOption, -) error { - o := joinOptions{} - for _, apply := range options { - apply(&o) - } - - var ( - nodeID string - peer launchtypes.Peer - err error - ) - - // parse the gentx content - gentxInfo, gentx, err := cosmosutil.GentxFromPath(gentxPath) - if err != nil { - return err - } - - // get the peer address - if o.publicAddress != "" { - if nodeID, err = c.NodeID(ctx); err != nil { - return err - } - - if xurl.IsHTTP(o.publicAddress) { - peer = launchtypes.NewPeerTunnel(nodeID, networkchain.HTTPTunnelChisel, o.publicAddress) - } else { - peer = launchtypes.NewPeerConn(nodeID, o.publicAddress) - } - } else { - // if the peer address is not specified, we parse it from the gentx memo - if peer, err = ParsePeerAddress(gentxInfo.Memo); err != nil { - return err - } - } - - // change the chain address prefix to spn - accountAddress, err := cosmosutil.ChangeAddressPrefix(gentxInfo.DelegatorAddress, networktypes.SPN) - if err != nil { - return err - } - - if !o.accountAmount.IsZero() { - if err := n.SendAccountRequest(ctx, launchID, accountAddress, o.accountAmount); err != nil { - return err - } - } - - return n.SendValidatorRequest(ctx, launchID, peer, accountAddress, gentx, gentxInfo) -} - -func (n Network) SendAccountRequestForCoordinator(ctx context.Context, launchID uint64, amount sdk.Coins) error { - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - return n.SendAccountRequest(ctx, launchID, addr, amount) -} diff --git a/ignite/services/network/join_test.go b/ignite/services/network/join_test.go deleted file mode 100644 index b54aceaf81..0000000000 --- a/ignite/services/network/join_test.go +++ /dev/null @@ -1,312 +0,0 @@ -package network - -import ( - "context" - "errors" - "testing" - - sdkmath "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - launchtypes "github.com/tendermint/spn/x/launch/types" - - "github.com/ignite/cli/ignite/services/network/networktypes" - "github.com/ignite/cli/ignite/services/network/testutil" -) - -const ( - TestDenom = "stake" - TestAmountString = "95000000" - TestAmountInt = int64(95000000) - TestAccountRequestID = uint64(1) - TestGenesisValidatorRequestID = uint64(2) -) - -func TestJoin(t *testing.T) { - t.Run("successfully send join request", func(t *testing.T) { - account := testutil.NewTestAccount(t, testutil.TestAccountName) - tmp := t.TempDir() - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - gentx := testutil.NewGentx( - addr, - TestDenom, - TestAmountString, - "", - testutil.PeerAddress, - ) - gentxPath := gentx.SaveTo(t, tmp) - suite, network := newSuite(account) - - suite.ChainMock.On("NodeID", context.Background()).Return(testutil.NodeID, nil).Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - launchtypes.NewMsgSendRequest( - addr, - testutil.LaunchID, - launchtypes.NewGenesisValidator( - testutil.LaunchID, - addr, - gentx.JSON(t), - []byte{}, - sdk.NewCoin(TestDenom, sdkmath.NewInt(TestAmountInt)), - launchtypes.Peer{ - Id: testutil.NodeID, - Connection: &launchtypes.Peer_TcpAddress{ - TcpAddress: testutil.TCPAddress, - }, - }), - ), - ). - Return(testutil.NewResponse(&launchtypes.MsgSendRequestResponse{ - RequestID: TestGenesisValidatorRequestID, - AutoApproved: false, - }), nil). - Once() - - joinErr := network.Join( - context.Background(), - suite.ChainMock, - testutil.LaunchID, - gentxPath, - WithPublicAddress(testutil.TCPAddress), - ) - require.NoError(t, joinErr) - suite.AssertAllMocks(t) - }) - - t.Run("successfully send join request with custom gentx", func(t *testing.T) { - account := testutil.NewTestAccount(t, testutil.TestAccountName) - tmp := t.TempDir() - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - gentx := testutil.NewGentx( - addr, - TestDenom, - TestAmountString, - "", - testutil.PeerAddress, - ) - gentxPath := gentx.SaveTo(t, tmp) - suite, network := newSuite(account) - - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - launchtypes.NewMsgSendRequest( - addr, - testutil.LaunchID, - launchtypes.NewGenesisValidator( - testutil.LaunchID, - addr, - gentx.JSON(t), - []byte{}, - sdk.NewCoin(TestDenom, sdkmath.NewInt(TestAmountInt)), - launchtypes.Peer{ - Id: testutil.NodeID, - Connection: &launchtypes.Peer_TcpAddress{ - TcpAddress: testutil.TCPAddress, - }, - }, - ), - ), - ). - Return(testutil.NewResponse(&launchtypes.MsgSendRequestResponse{ - RequestID: TestGenesisValidatorRequestID, - AutoApproved: false, - }), nil). - Once() - - joinErr := network.Join(context.Background(), suite.ChainMock, testutil.LaunchID, gentxPath) - require.NoError(t, joinErr) - suite.AssertAllMocks(t) - }) - - t.Run("failed to send join request, failed to broadcast join tx", func(t *testing.T) { - account := testutil.NewTestAccount(t, testutil.TestAccountName) - tmp := t.TempDir() - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - gentx := testutil.NewGentx( - addr, - TestDenom, - TestAmountString, - "", - testutil.PeerAddress, - ) - gentxPath := gentx.SaveTo(t, tmp) - suite, network := newSuite(account) - expectedError := errors.New("failed to add validator") - - suite.ChainMock.On("NodeID", context.Background()).Return(testutil.NodeID, nil).Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - launchtypes.NewMsgSendRequest( - addr, - testutil.LaunchID, - launchtypes.NewGenesisValidator( - testutil.LaunchID, - addr, - gentx.JSON(t), - []byte{}, - sdk.NewCoin(TestDenom, sdkmath.NewInt(TestAmountInt)), - launchtypes.Peer{ - Id: testutil.NodeID, - Connection: &launchtypes.Peer_TcpAddress{ - TcpAddress: testutil.TCPAddress, - }, - }, - ), - ), - ). - Return( - testutil.NewResponse(&launchtypes.MsgSendRequestResponse{}), - expectedError, - ). - Once() - - joinErr := network.Join( - context.Background(), - suite.ChainMock, - testutil.LaunchID, - gentxPath, - WithPublicAddress(testutil.TCPAddress), - ) - require.Error(t, joinErr) - require.Equal(t, expectedError, joinErr) - suite.AssertAllMocks(t) - }) - - t.Run("successfully send join request with account request", func(t *testing.T) { - account := testutil.NewTestAccount(t, testutil.TestAccountName) - tmp := t.TempDir() - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - gentx := testutil.NewGentx( - addr, - TestDenom, - TestAmountString, - "", - testutil.PeerAddress, - ) - gentxPath := gentx.SaveTo(t, tmp) - suite, network := newSuite(account) - - suite.ChainMock.On("NodeID", context.Background()).Return(testutil.NodeID, nil).Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - launchtypes.NewMsgSendRequest( - addr, - testutil.LaunchID, - launchtypes.NewGenesisValidator( - testutil.LaunchID, - addr, - gentx.JSON(t), - []byte{}, - sdk.NewCoin(TestDenom, sdkmath.NewInt(TestAmountInt)), - launchtypes.Peer{ - Id: testutil.NodeID, - Connection: &launchtypes.Peer_TcpAddress{ - TcpAddress: testutil.TCPAddress, - }, - }, - ), - ), - ). - Return(testutil.NewResponse(&launchtypes.MsgSendRequestResponse{ - RequestID: TestGenesisValidatorRequestID, - AutoApproved: false, - }), nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - launchtypes.NewMsgSendRequest( - addr, - testutil.LaunchID, - launchtypes.NewGenesisAccount( - testutil.LaunchID, - addr, - sdk.NewCoins(sdk.NewCoin(TestDenom, sdkmath.NewInt(TestAmountInt))), - ), - ), - ). - Return(testutil.NewResponse(&launchtypes.MsgSendRequestResponse{ - RequestID: TestAccountRequestID, - AutoApproved: false, - }), nil). - Once() - - joinErr := network.Join( - context.Background(), - suite.ChainMock, - testutil.LaunchID, - gentxPath, - WithAccountRequest(sdk.NewCoins(sdk.NewCoin(TestDenom, sdkmath.NewInt(TestAmountInt)))), - WithPublicAddress(testutil.TCPAddress), - ) - require.NoError(t, joinErr) - suite.AssertAllMocks(t) - }) - - t.Run("failed to send join request, failed to read node id", func(t *testing.T) { - account := testutil.NewTestAccount(t, testutil.TestAccountName) - tmp := t.TempDir() - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - gentx := testutil.NewGentx( - addr, - TestDenom, - TestAmountString, - "", - testutil.PeerAddress, - ) - gentxPath := gentx.SaveTo(t, tmp) - suite, network := newSuite(account) - expectedError := errors.New("failed to get node id") - - suite.ChainMock. - On("NodeID", mock.Anything). - Return("", expectedError). - Once() - - joinErr := network.Join( - context.Background(), - suite.ChainMock, - testutil.LaunchID, - gentxPath, - WithPublicAddress(testutil.TCPAddress), - ) - require.Error(t, joinErr) - require.Equal(t, expectedError, joinErr) - suite.AssertAllMocks(t) - }) - - t.Run("failed to send join request, failed to read gentx", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - gentxPath = "invalid/path" - suite, network = newSuite(account) - expectedError = errors.New("chain home folder is not initialized yet: invalid/path") - ) - - joinErr := network.Join(context.Background(), suite.ChainMock, testutil.LaunchID, gentxPath) - require.Error(t, joinErr) - require.Equal(t, expectedError, joinErr) - suite.AssertAllMocks(t) - }) -} diff --git a/ignite/services/network/launch.go b/ignite/services/network/launch.go deleted file mode 100644 index e3399e6b2d..0000000000 --- a/ignite/services/network/launch.go +++ /dev/null @@ -1,100 +0,0 @@ -package network - -import ( - "context" - "fmt" - "time" - - launchtypes "github.com/tendermint/spn/x/launch/types" - - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// MinLaunchTimeOffset represents an offset used when minimum launch time is used -// minimum launch time will be block time + minimum launch time duration param -// block time when tx is executed is not predicable, therefore we add few seconds -// to ensure the minimum duration is reached. -const MinLaunchTimeOffset = time.Second * 30 - -// LaunchParams fetches the chain launch module params from SPN. -func (n Network) LaunchParams(ctx context.Context) (launchtypes.Params, error) { - res, err := n.launchQuery.Params(ctx, &launchtypes.QueryParamsRequest{}) - if err != nil { - return launchtypes.Params{}, err - } - return res.GetParams(), nil -} - -// TriggerLaunch launches a chain as a coordinator. -func (n Network) TriggerLaunch(ctx context.Context, launchID uint64, launchTime time.Time) error { - n.ev.Send(fmt.Sprintf("Launching chain %d", launchID), events.ProgressStart()) - params, err := n.LaunchParams(ctx) - if err != nil { - return err - } - - var ( - minLaunchTime = n.clock.Now().Add(params.LaunchTimeRange.MinLaunchTime).Add(MinLaunchTimeOffset) - maxLaunchTime = n.clock.Now().Add(params.LaunchTimeRange.MaxLaunchTime) - ) - address, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - if launchTime.IsZero() { - // Use minimum launch time by default - launchTime = minLaunchTime - } else { - // check launch time is in range - switch { - case launchTime.Before(minLaunchTime): - return fmt.Errorf("launch time %s lower than minimum %s", launchTime, minLaunchTime) - case launchTime.After(maxLaunchTime): - return fmt.Errorf("launch time %s bigger than maximum %s", launchTime, maxLaunchTime) - } - } - - msg := launchtypes.NewMsgTriggerLaunch(address, launchID, launchTime) - n.ev.Send("Setting launch time", events.ProgressUpdate()) - res, err := n.cosmos.BroadcastTx(ctx, n.account, msg) - if err != nil { - return err - } - - var launchRes launchtypes.MsgTriggerLaunchResponse - if err := res.Decode(&launchRes); err != nil { - return err - } - - n.ev.Send( - fmt.Sprintf("Chain %d will be launched on %s", launchID, launchTime), - events.ProgressFinish(), - ) - return nil -} - -// RevertLaunch reverts a launched chain as a coordinator. -func (n Network) RevertLaunch(ctx context.Context, launchID uint64, chain Chain) error { - n.ev.Send(fmt.Sprintf("Reverting launched chain %d", launchID), events.ProgressStart()) - - address, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - msg := launchtypes.NewMsgRevertLaunch(address, launchID) - _, err = n.cosmos.BroadcastTx(ctx, n.account, msg) - if err != nil { - return err - } - - n.ev.Send( - fmt.Sprintf("Chain %d launch was reverted", launchID), - events.ProgressFinish(), - ) - - n.ev.Send("Genesis time was reset", events.ProgressFinish()) - return nil -} diff --git a/ignite/services/network/launch_test.go b/ignite/services/network/launch_test.go deleted file mode 100644 index 713c62e28d..0000000000 --- a/ignite/services/network/launch_test.go +++ /dev/null @@ -1,286 +0,0 @@ -package network - -import ( - "context" - "errors" - "testing" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - launchtypes "github.com/tendermint/spn/x/launch/types" - - "github.com/ignite/cli/ignite/services/network/networktypes" - "github.com/ignite/cli/ignite/services/network/testutil" -) - -const ( - TestMinRemainingTime = time.Second * 3600 - TestMaxRemainingTime = time.Second * 86400 - TestRevertDelay = time.Second * 3600 -) - -func TestTriggerLaunch(t *testing.T) { - t.Run("successfully launch a chain", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.LaunchQueryMock. - On("Params", context.Background(), &launchtypes.QueryParamsRequest{}). - Return(&launchtypes.QueryParamsResponse{ - Params: launchtypes.NewParams( - TestMinRemainingTime, - TestMaxRemainingTime, - TestRevertDelay, - sdk.Coins(nil), - sdk.Coins(nil), - ), - }, nil). - Once() - suite.CosmosClientMock. - On("BroadcastTx", - context.Background(), - account, - &launchtypes.MsgTriggerLaunch{ - Coordinator: addr, - LaunchID: testutil.LaunchID, - LaunchTime: sampleTime.Add(TestMaxRemainingTime), - }). - Return(testutil.NewResponse(&launchtypes.MsgTriggerLaunchResponse{}), nil). - Once() - - launchError := network.TriggerLaunch(context.Background(), testutil.LaunchID, sampleTime.Add(TestMaxRemainingTime)) - require.NoError(t, launchError) - suite.AssertAllMocks(t) - }) - - t.Run("failed to launch a chain, remaining time is lower than allowed", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - remainingTimeLowerThanMinimum = sampleTime - ) - - suite.LaunchQueryMock. - On("Params", context.Background(), &launchtypes.QueryParamsRequest{}). - Return(&launchtypes.QueryParamsResponse{ - Params: launchtypes.NewParams( - TestMinRemainingTime, - TestMaxRemainingTime, - TestRevertDelay, - sdk.Coins(nil), - sdk.Coins(nil), - ), - }, nil). - Once() - - launchError := network.TriggerLaunch(context.Background(), testutil.LaunchID, remainingTimeLowerThanMinimum) - require.Errorf( - t, - launchError, - "remaining time %s lower than minimum %s", - remainingTimeLowerThanMinimum.String(), - sampleTime.Add(TestMinRemainingTime).Add(MinLaunchTimeOffset).String(), - ) - suite.AssertAllMocks(t) - }) - - t.Run("failed to launch a chain, remaining time is greater than allowed", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - remainingTimeGreaterThanMaximum = sampleTime.Add(TestMaxRemainingTime).Add(time.Second) - ) - - suite.LaunchQueryMock. - On("Params", context.Background(), &launchtypes.QueryParamsRequest{}). - Return(&launchtypes.QueryParamsResponse{ - Params: launchtypes.NewParams( - TestMinRemainingTime, - TestMaxRemainingTime, - TestRevertDelay, - sdk.Coins(nil), - sdk.Coins(nil), - ), - }, nil). - Once() - - launchError := network.TriggerLaunch(context.Background(), testutil.LaunchID, remainingTimeGreaterThanMaximum) - require.Errorf( - t, - launchError, - "remaining time %s greater than maximum %s", - remainingTimeGreaterThanMaximum.String(), - sampleTime.Add(TestMaxRemainingTime).String(), - ) - suite.AssertAllMocks(t) - }) - - t.Run("failed to launch a chain, failed to broadcast the launch tx", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - expectedError = errors.New("Failed to fetch") - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.LaunchQueryMock. - On("Params", context.Background(), &launchtypes.QueryParamsRequest{}). - Return(&launchtypes.QueryParamsResponse{ - Params: launchtypes.NewParams( - TestMinRemainingTime, - TestMaxRemainingTime, - TestRevertDelay, - sdk.Coins(nil), - sdk.Coins(nil), - ), - }, nil). - Once() - suite.CosmosClientMock. - On("BroadcastTx", - context.Background(), - account, - &launchtypes.MsgTriggerLaunch{ - Coordinator: addr, - LaunchID: testutil.LaunchID, - LaunchTime: sampleTime.Add(TestMaxRemainingTime), - }). - Return(testutil.NewResponse(&launchtypes.MsgTriggerLaunch{}), expectedError). - Once() - - launchError := network.TriggerLaunch(context.Background(), testutil.LaunchID, sampleTime.Add(TestMaxRemainingTime)) - require.Error(t, launchError) - require.Equal(t, expectedError, launchError) - suite.AssertAllMocks(t) - }) - - t.Run("failed to launch a chain, invalid response from chain", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - expectedError = errors.New("failed to fetch") - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.LaunchQueryMock. - On("Params", context.Background(), &launchtypes.QueryParamsRequest{}). - Return(&launchtypes.QueryParamsResponse{ - Params: launchtypes.NewParams( - TestMinRemainingTime, - TestMaxRemainingTime, - TestRevertDelay, - sdk.Coins(nil), - sdk.Coins(nil), - ), - }, nil). - Once() - suite.CosmosClientMock. - On("BroadcastTx", - context.Background(), - account, - &launchtypes.MsgTriggerLaunch{ - Coordinator: addr, - LaunchID: testutil.LaunchID, - LaunchTime: sampleTime.Add(TestMaxRemainingTime), - }). - Return(testutil.NewResponse(&launchtypes.MsgCreateChainResponse{}), expectedError). - Once() - - launchError := network.TriggerLaunch(context.Background(), testutil.LaunchID, sampleTime.Add(TestMaxRemainingTime)) - require.Error(t, launchError) - require.Equal(t, expectedError, launchError) - suite.AssertAllMocks(t) - }) - - t.Run("failed to launch a chain, failed to fetch chain params", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - expectedError = errors.New("failed to fetch") - ) - - suite.LaunchQueryMock. - On("Params", context.Background(), &launchtypes.QueryParamsRequest{}). - Return(&launchtypes.QueryParamsResponse{ - Params: launchtypes.NewParams( - TestMinRemainingTime, - TestMaxRemainingTime, - TestRevertDelay, - sdk.Coins(nil), - sdk.Coins(nil), - ), - }, expectedError). - Once() - - launchError := network.TriggerLaunch(context.Background(), testutil.LaunchID, sampleTime.Add(TestMaxRemainingTime)) - require.Error(t, launchError) - require.Equal(t, expectedError, launchError) - suite.AssertAllMocks(t) - }) -} - -func TestRevertLaunch(t *testing.T) { - t.Run("successfully revert launch", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.CosmosClientMock. - On("BroadcastTx", - context.Background(), - account, - &launchtypes.MsgRevertLaunch{ - Coordinator: addr, - LaunchID: testutil.LaunchID, - }). - Return(testutil.NewResponse(&launchtypes.MsgRevertLaunchResponse{}), nil). - Once() - - revertError := network.RevertLaunch(context.Background(), testutil.LaunchID, suite.ChainMock) - require.NoError(t, revertError) - suite.AssertAllMocks(t) - }) - - t.Run("failed to revert launch, failed to broadcast revert launch tx", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - expectedError = errors.New("failed to revert launch") - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.CosmosClientMock. - On("BroadcastTx", - context.Background(), - account, - &launchtypes.MsgRevertLaunch{ - Coordinator: addr, - LaunchID: testutil.LaunchID, - }). - Return( - testutil.NewResponse(&launchtypes.MsgRevertLaunchResponse{}), - expectedError, - ). - Once() - - revertError := network.RevertLaunch(context.Background(), testutil.LaunchID, suite.ChainMock) - require.Error(t, revertError) - require.Equal(t, expectedError, revertError) - suite.AssertAllMocks(t) - }) -} diff --git a/ignite/services/network/mocks/account_info.go b/ignite/services/network/mocks/account_info.go deleted file mode 100644 index a4ba47ad90..0000000000 --- a/ignite/services/network/mocks/account_info.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. - -package mocks - -import mock "github.com/stretchr/testify/mock" - -// AccountInfo is an autogenerated mock type for the AccountInfo type -type AccountInfo struct { - mock.Mock -} - -type mockConstructorTestingTNewAccountInfo interface { - mock.TestingT - Cleanup(func()) -} - -// NewAccountInfo creates a new instance of AccountInfo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewAccountInfo(t mockConstructorTestingTNewAccountInfo) *AccountInfo { - mock := &AccountInfo{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/ignite/services/network/mocks/bank_client.go b/ignite/services/network/mocks/bank_client.go deleted file mode 100644 index 2a8b17aa37..0000000000 --- a/ignite/services/network/mocks/bank_client.go +++ /dev/null @@ -1,303 +0,0 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. - -package mocks - -import ( - context "context" - - grpc "google.golang.org/grpc" - - mock "github.com/stretchr/testify/mock" - - types "github.com/cosmos/cosmos-sdk/x/bank/types" -) - -// BankClient is an autogenerated mock type for the BankClient type -type BankClient struct { - mock.Mock -} - -// AllBalances provides a mock function with given fields: ctx, in, opts -func (_m *BankClient) AllBalances(ctx context.Context, in *types.QueryAllBalancesRequest, opts ...grpc.CallOption) (*types.QueryAllBalancesResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllBalancesResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllBalancesRequest, ...grpc.CallOption) *types.QueryAllBalancesResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllBalancesResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllBalancesRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Balance provides a mock function with given fields: ctx, in, opts -func (_m *BankClient) Balance(ctx context.Context, in *types.QueryBalanceRequest, opts ...grpc.CallOption) (*types.QueryBalanceResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryBalanceResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryBalanceRequest, ...grpc.CallOption) *types.QueryBalanceResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryBalanceResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryBalanceRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DenomMetadata provides a mock function with given fields: ctx, in, opts -func (_m *BankClient) DenomMetadata(ctx context.Context, in *types.QueryDenomMetadataRequest, opts ...grpc.CallOption) (*types.QueryDenomMetadataResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryDenomMetadataResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryDenomMetadataRequest, ...grpc.CallOption) *types.QueryDenomMetadataResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryDenomMetadataResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryDenomMetadataRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DenomOwners provides a mock function with given fields: ctx, in, opts -func (_m *BankClient) DenomOwners(ctx context.Context, in *types.QueryDenomOwnersRequest, opts ...grpc.CallOption) (*types.QueryDenomOwnersResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryDenomOwnersResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryDenomOwnersRequest, ...grpc.CallOption) *types.QueryDenomOwnersResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryDenomOwnersResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryDenomOwnersRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DenomsMetadata provides a mock function with given fields: ctx, in, opts -func (_m *BankClient) DenomsMetadata(ctx context.Context, in *types.QueryDenomsMetadataRequest, opts ...grpc.CallOption) (*types.QueryDenomsMetadataResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryDenomsMetadataResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryDenomsMetadataRequest, ...grpc.CallOption) *types.QueryDenomsMetadataResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryDenomsMetadataResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryDenomsMetadataRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Params provides a mock function with given fields: ctx, in, opts -func (_m *BankClient) Params(ctx context.Context, in *types.QueryParamsRequest, opts ...grpc.CallOption) (*types.QueryParamsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryParamsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) *types.QueryParamsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryParamsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// SpendableBalances provides a mock function with given fields: ctx, in, opts -func (_m *BankClient) SpendableBalances(ctx context.Context, in *types.QuerySpendableBalancesRequest, opts ...grpc.CallOption) (*types.QuerySpendableBalancesResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QuerySpendableBalancesResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QuerySpendableBalancesRequest, ...grpc.CallOption) *types.QuerySpendableBalancesResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QuerySpendableBalancesResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QuerySpendableBalancesRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// SupplyOf provides a mock function with given fields: ctx, in, opts -func (_m *BankClient) SupplyOf(ctx context.Context, in *types.QuerySupplyOfRequest, opts ...grpc.CallOption) (*types.QuerySupplyOfResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QuerySupplyOfResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QuerySupplyOfRequest, ...grpc.CallOption) *types.QuerySupplyOfResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QuerySupplyOfResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QuerySupplyOfRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// TotalSupply provides a mock function with given fields: ctx, in, opts -func (_m *BankClient) TotalSupply(ctx context.Context, in *types.QueryTotalSupplyRequest, opts ...grpc.CallOption) (*types.QueryTotalSupplyResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryTotalSupplyResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryTotalSupplyRequest, ...grpc.CallOption) *types.QueryTotalSupplyResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryTotalSupplyResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryTotalSupplyRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type mockConstructorTestingTNewBankClient interface { - mock.TestingT - Cleanup(func()) -} - -// NewBankClient creates a new instance of BankClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewBankClient(t mockConstructorTestingTNewBankClient) *BankClient { - mock := &BankClient{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/ignite/services/network/mocks/campaign_client.go b/ignite/services/network/mocks/campaign_client.go deleted file mode 100644 index 2479086320..0000000000 --- a/ignite/services/network/mocks/campaign_client.go +++ /dev/null @@ -1,333 +0,0 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. - -package mocks - -import ( - context "context" - - grpc "google.golang.org/grpc" - - mock "github.com/stretchr/testify/mock" - - types "github.com/tendermint/spn/x/campaign/types" -) - -// CampaignClient is an autogenerated mock type for the CampaignClient type -type CampaignClient struct { - mock.Mock -} - -// Campaign provides a mock function with given fields: ctx, in, opts -func (_m *CampaignClient) Campaign(ctx context.Context, in *types.QueryGetCampaignRequest, opts ...grpc.CallOption) (*types.QueryGetCampaignResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetCampaignResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetCampaignRequest, ...grpc.CallOption) *types.QueryGetCampaignResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetCampaignResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetCampaignRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CampaignAll provides a mock function with given fields: ctx, in, opts -func (_m *CampaignClient) CampaignAll(ctx context.Context, in *types.QueryAllCampaignRequest, opts ...grpc.CallOption) (*types.QueryAllCampaignResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllCampaignResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllCampaignRequest, ...grpc.CallOption) *types.QueryAllCampaignResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllCampaignResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllCampaignRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CampaignChains provides a mock function with given fields: ctx, in, opts -func (_m *CampaignClient) CampaignChains(ctx context.Context, in *types.QueryGetCampaignChainsRequest, opts ...grpc.CallOption) (*types.QueryGetCampaignChainsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetCampaignChainsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetCampaignChainsRequest, ...grpc.CallOption) *types.QueryGetCampaignChainsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetCampaignChainsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetCampaignChainsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MainnetAccount provides a mock function with given fields: ctx, in, opts -func (_m *CampaignClient) MainnetAccount(ctx context.Context, in *types.QueryGetMainnetAccountRequest, opts ...grpc.CallOption) (*types.QueryGetMainnetAccountResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetMainnetAccountResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetMainnetAccountRequest, ...grpc.CallOption) *types.QueryGetMainnetAccountResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetMainnetAccountResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetMainnetAccountRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MainnetAccountAll provides a mock function with given fields: ctx, in, opts -func (_m *CampaignClient) MainnetAccountAll(ctx context.Context, in *types.QueryAllMainnetAccountRequest, opts ...grpc.CallOption) (*types.QueryAllMainnetAccountResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllMainnetAccountResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllMainnetAccountRequest, ...grpc.CallOption) *types.QueryAllMainnetAccountResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllMainnetAccountResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllMainnetAccountRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MainnetAccountBalance provides a mock function with given fields: ctx, in, opts -func (_m *CampaignClient) MainnetAccountBalance(ctx context.Context, in *types.QueryGetMainnetAccountBalanceRequest, opts ...grpc.CallOption) (*types.QueryGetMainnetAccountBalanceResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetMainnetAccountBalanceResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetMainnetAccountBalanceRequest, ...grpc.CallOption) *types.QueryGetMainnetAccountBalanceResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetMainnetAccountBalanceResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetMainnetAccountBalanceRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MainnetAccountBalanceAll provides a mock function with given fields: ctx, in, opts -func (_m *CampaignClient) MainnetAccountBalanceAll(ctx context.Context, in *types.QueryAllMainnetAccountBalanceRequest, opts ...grpc.CallOption) (*types.QueryAllMainnetAccountBalanceResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllMainnetAccountBalanceResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllMainnetAccountBalanceRequest, ...grpc.CallOption) *types.QueryAllMainnetAccountBalanceResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllMainnetAccountBalanceResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllMainnetAccountBalanceRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Params provides a mock function with given fields: ctx, in, opts -func (_m *CampaignClient) Params(ctx context.Context, in *types.QueryParamsRequest, opts ...grpc.CallOption) (*types.QueryParamsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryParamsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) *types.QueryParamsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryParamsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// SpecialAllocationsBalance provides a mock function with given fields: ctx, in, opts -func (_m *CampaignClient) SpecialAllocationsBalance(ctx context.Context, in *types.QuerySpecialAllocationsBalanceRequest, opts ...grpc.CallOption) (*types.QuerySpecialAllocationsBalanceResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QuerySpecialAllocationsBalanceResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QuerySpecialAllocationsBalanceRequest, ...grpc.CallOption) *types.QuerySpecialAllocationsBalanceResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QuerySpecialAllocationsBalanceResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QuerySpecialAllocationsBalanceRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// TotalShares provides a mock function with given fields: ctx, in, opts -func (_m *CampaignClient) TotalShares(ctx context.Context, in *types.QueryTotalSharesRequest, opts ...grpc.CallOption) (*types.QueryTotalSharesResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryTotalSharesResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryTotalSharesRequest, ...grpc.CallOption) *types.QueryTotalSharesResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryTotalSharesResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryTotalSharesRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type mockConstructorTestingTNewCampaignClient interface { - mock.TestingT - Cleanup(func()) -} - -// NewCampaignClient creates a new instance of CampaignClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewCampaignClient(t mockConstructorTestingTNewCampaignClient) *CampaignClient { - mock := &CampaignClient{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/ignite/services/network/mocks/chain.go b/ignite/services/network/mocks/chain.go deleted file mode 100644 index 4c4c9bd632..0000000000 --- a/ignite/services/network/mocks/chain.go +++ /dev/null @@ -1,253 +0,0 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. - -package mocks - -import ( - context "context" - - mock "github.com/stretchr/testify/mock" -) - -// Chain is an autogenerated mock type for the Chain type -type Chain struct { - mock.Mock -} - -// AppTOMLPath provides a mock function with given fields: -func (_m *Chain) AppTOMLPath() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CacheBinary provides a mock function with given fields: launchID -func (_m *Chain) CacheBinary(launchID uint64) error { - ret := _m.Called(launchID) - - var r0 error - if rf, ok := ret.Get(0).(func(uint64) error); ok { - r0 = rf(launchID) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ChainID provides a mock function with given fields: -func (_m *Chain) ChainID() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ConfigTOMLPath provides a mock function with given fields: -func (_m *Chain) ConfigTOMLPath() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DefaultGentxPath provides a mock function with given fields: -func (_m *Chain) DefaultGentxPath() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GenesisPath provides a mock function with given fields: -func (_m *Chain) GenesisPath() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GentxsPath provides a mock function with given fields: -func (_m *Chain) GentxsPath() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ID provides a mock function with given fields: -func (_m *Chain) ID() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Name provides a mock function with given fields: -func (_m *Chain) Name() string { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// NodeID provides a mock function with given fields: ctx -func (_m *Chain) NodeID(ctx context.Context) (string, error) { - ret := _m.Called(ctx) - - var r0 string - if rf, ok := ret.Get(0).(func(context.Context) string); ok { - r0 = rf(ctx) - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(ctx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// SourceHash provides a mock function with given fields: -func (_m *Chain) SourceHash() string { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// SourceURL provides a mock function with given fields: -func (_m *Chain) SourceURL() string { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -type mockConstructorTestingTNewChain interface { - mock.TestingT - Cleanup(func()) -} - -// NewChain creates a new instance of Chain. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewChain(t mockConstructorTestingTNewChain) *Chain { - mock := &Chain{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/ignite/services/network/mocks/cosmos_client.go b/ignite/services/network/mocks/cosmos_client.go deleted file mode 100644 index e1f934f61a..0000000000 --- a/ignite/services/network/mocks/cosmos_client.go +++ /dev/null @@ -1,125 +0,0 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. - -package mocks - -import ( - context "context" - - client "github.com/cosmos/cosmos-sdk/client" - - coretypes "github.com/tendermint/tendermint/rpc/core/types" - - cosmosaccount "github.com/ignite/cli/ignite/pkg/cosmosaccount" - - cosmosclient "github.com/ignite/cli/ignite/pkg/cosmosclient" - - mock "github.com/stretchr/testify/mock" - - types "github.com/cosmos/cosmos-sdk/types" -) - -// CosmosClient is an autogenerated mock type for the CosmosClient type -type CosmosClient struct { - mock.Mock -} - -// BroadcastTx provides a mock function with given fields: ctx, account, msgs -func (_m *CosmosClient) BroadcastTx(ctx context.Context, account cosmosaccount.Account, msgs ...types.Msg) (cosmosclient.Response, error) { - _va := make([]interface{}, len(msgs)) - for _i := range msgs { - _va[_i] = msgs[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, account) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 cosmosclient.Response - if rf, ok := ret.Get(0).(func(context.Context, cosmosaccount.Account, ...types.Msg) cosmosclient.Response); ok { - r0 = rf(ctx, account, msgs...) - } else { - r0 = ret.Get(0).(cosmosclient.Response) - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, cosmosaccount.Account, ...types.Msg) error); ok { - r1 = rf(ctx, account, msgs...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ConsensusInfo provides a mock function with given fields: ctx, height -func (_m *CosmosClient) ConsensusInfo(ctx context.Context, height int64) (cosmosclient.ConsensusInfo, error) { - ret := _m.Called(ctx, height) - - var r0 cosmosclient.ConsensusInfo - if rf, ok := ret.Get(0).(func(context.Context, int64) cosmosclient.ConsensusInfo); ok { - r0 = rf(ctx, height) - } else { - r0 = ret.Get(0).(cosmosclient.ConsensusInfo) - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { - r1 = rf(ctx, height) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Context provides a mock function with given fields: -func (_m *CosmosClient) Context() client.Context { - ret := _m.Called() - - var r0 client.Context - if rf, ok := ret.Get(0).(func() client.Context); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(client.Context) - } - - return r0 -} - -// Status provides a mock function with given fields: ctx -func (_m *CosmosClient) Status(ctx context.Context) (*coretypes.ResultStatus, error) { - ret := _m.Called(ctx) - - var r0 *coretypes.ResultStatus - if rf, ok := ret.Get(0).(func(context.Context) *coretypes.ResultStatus); ok { - r0 = rf(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultStatus) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(ctx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type mockConstructorTestingTNewCosmosClient interface { - mock.TestingT - Cleanup(func()) -} - -// NewCosmosClient creates a new instance of CosmosClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewCosmosClient(t mockConstructorTestingTNewCosmosClient) *CosmosClient { - mock := &CosmosClient{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/ignite/services/network/mocks/data/genesis.json b/ignite/services/network/mocks/data/genesis.json deleted file mode 100644 index 9b1206d741..0000000000 --- a/ignite/services/network/mocks/data/genesis.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "genesis_time": "2022-04-07T17:41:59.206851Z", - "chain_id": "test-custom-1", - "initial_height": "1", - "consensus_params": { - "block": { - "max_bytes": "22020096", - "max_gas": "-1", - "time_iota_ms": "1000" - }, - "evidence": { - "max_age_num_blocks": "100000", - "max_age_duration": "172800000000000", - "max_bytes": "1048576" - }, - "validator": { - "pub_key_types": [ - "ed25519" - ] - }, - "version": {} - }, - "app_hash": "", - "app_state": { - "bank": { - "balances": [ - { - "address": "cosmos1p5y33h5t8gw4dd2shdtdcv3a89mkyhsm6f2552", - "coins": [ - { - "denom": "stake", - "amount": "200000000" - }, - { - "denom": "token", - "amount": "20000" - } - ] - }, - { - "address": "cosmos10zv6xg8uxdnffkgc7s23hytxxa58q6mhy4tt8e", - "coins": [ - { - "denom": "stake", - "amount": "100000000" - }, - { - "denom": "token", - "amount": "10000" - } - ] - } - ] - }, - "staking": { - "delegations": [], - "exported": false, - "last_total_power": "0", - "last_validator_powers": [], - "params": { - "bond_denom": "stake", - "historical_entries": 10000, - "max_entries": 7, - "max_validators": 100, - "unbonding_time": "1814400s" - }, - "redelegations": [], - "unbonding_delegations": [], - "validators": [] - }, - "transfer": { - "denom_traces": [], - "params": { - "receive_enabled": true, - "send_enabled": true - }, - "port_id": "transfer" - } - } -} \ No newline at end of file diff --git a/ignite/services/network/mocks/ibc_client.go b/ignite/services/network/mocks/ibc_client.go deleted file mode 100644 index 778cccd9c5..0000000000 --- a/ignite/services/network/mocks/ibc_client.go +++ /dev/null @@ -1,267 +0,0 @@ -// Code generated by mockery v2.12.2. DO NOT EDIT. - -package mocks - -import ( - "context" - "testing" - - types "github.com/cosmos/ibc-go/v5/modules/core/02-client/types" - "github.com/stretchr/testify/mock" - "google.golang.org/grpc" -) - -// IBCClient is an autogenerated mock type for the QueryClient type -type IBCClient struct { - mock.Mock -} - -// ClientParams provides a mock function with given fields: ctx, in, opts -func (_m *IBCClient) ClientParams(ctx context.Context, in *types.QueryClientParamsRequest, opts ...grpc.CallOption) (*types.QueryClientParamsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryClientParamsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryClientParamsRequest, ...grpc.CallOption) *types.QueryClientParamsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryClientParamsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryClientParamsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ClientState provides a mock function with given fields: ctx, in, opts -func (_m *IBCClient) ClientState(ctx context.Context, in *types.QueryClientStateRequest, opts ...grpc.CallOption) (*types.QueryClientStateResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryClientStateResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryClientStateRequest, ...grpc.CallOption) *types.QueryClientStateResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryClientStateResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryClientStateRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ClientStates provides a mock function with given fields: ctx, in, opts -func (_m *IBCClient) ClientStates(ctx context.Context, in *types.QueryClientStatesRequest, opts ...grpc.CallOption) (*types.QueryClientStatesResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryClientStatesResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryClientStatesRequest, ...grpc.CallOption) *types.QueryClientStatesResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryClientStatesResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryClientStatesRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ClientStatus provides a mock function with given fields: ctx, in, opts -func (_m *IBCClient) ClientStatus(ctx context.Context, in *types.QueryClientStatusRequest, opts ...grpc.CallOption) (*types.QueryClientStatusResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryClientStatusResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryClientStatusRequest, ...grpc.CallOption) *types.QueryClientStatusResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryClientStatusResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryClientStatusRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ConsensusState provides a mock function with given fields: ctx, in, opts -func (_m *IBCClient) ConsensusState(ctx context.Context, in *types.QueryConsensusStateRequest, opts ...grpc.CallOption) (*types.QueryConsensusStateResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryConsensusStateResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryConsensusStateRequest, ...grpc.CallOption) *types.QueryConsensusStateResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryConsensusStateResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryConsensusStateRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ConsensusStates provides a mock function with given fields: ctx, in, opts -func (_m *IBCClient) ConsensusStates(ctx context.Context, in *types.QueryConsensusStatesRequest, opts ...grpc.CallOption) (*types.QueryConsensusStatesResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryConsensusStatesResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryConsensusStatesRequest, ...grpc.CallOption) *types.QueryConsensusStatesResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryConsensusStatesResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryConsensusStatesRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// UpgradedClientState provides a mock function with given fields: ctx, in, opts -func (_m *IBCClient) UpgradedClientState(ctx context.Context, in *types.QueryUpgradedClientStateRequest, opts ...grpc.CallOption) (*types.QueryUpgradedClientStateResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryUpgradedClientStateResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryUpgradedClientStateRequest, ...grpc.CallOption) *types.QueryUpgradedClientStateResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryUpgradedClientStateResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryUpgradedClientStateRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// UpgradedConsensusState provides a mock function with given fields: ctx, in, opts -func (_m *IBCClient) UpgradedConsensusState(ctx context.Context, in *types.QueryUpgradedConsensusStateRequest, opts ...grpc.CallOption) (*types.QueryUpgradedConsensusStateResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryUpgradedConsensusStateResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryUpgradedConsensusStateRequest, ...grpc.CallOption) *types.QueryUpgradedConsensusStateResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryUpgradedConsensusStateResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryUpgradedConsensusStateRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// NewIBCClient creates a new instance of IBCClient. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. -func NewIBCClient(t testing.TB) *IBCClient { - mock := &IBCClient{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/ignite/services/network/mocks/launch_client.go b/ignite/services/network/mocks/launch_client.go deleted file mode 100644 index c44e1117d2..0000000000 --- a/ignite/services/network/mocks/launch_client.go +++ /dev/null @@ -1,393 +0,0 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. - -package mocks - -import ( - context "context" - - grpc "google.golang.org/grpc" - - mock "github.com/stretchr/testify/mock" - - types "github.com/tendermint/spn/x/launch/types" -) - -// LaunchClient is an autogenerated mock type for the LaunchClient type -type LaunchClient struct { - mock.Mock -} - -// Chain provides a mock function with given fields: ctx, in, opts -func (_m *LaunchClient) Chain(ctx context.Context, in *types.QueryGetChainRequest, opts ...grpc.CallOption) (*types.QueryGetChainResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetChainResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetChainRequest, ...grpc.CallOption) *types.QueryGetChainResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetChainResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetChainRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ChainAll provides a mock function with given fields: ctx, in, opts -func (_m *LaunchClient) ChainAll(ctx context.Context, in *types.QueryAllChainRequest, opts ...grpc.CallOption) (*types.QueryAllChainResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllChainResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllChainRequest, ...grpc.CallOption) *types.QueryAllChainResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllChainResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllChainRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GenesisAccount provides a mock function with given fields: ctx, in, opts -func (_m *LaunchClient) GenesisAccount(ctx context.Context, in *types.QueryGetGenesisAccountRequest, opts ...grpc.CallOption) (*types.QueryGetGenesisAccountResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetGenesisAccountResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetGenesisAccountRequest, ...grpc.CallOption) *types.QueryGetGenesisAccountResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetGenesisAccountResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetGenesisAccountRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GenesisAccountAll provides a mock function with given fields: ctx, in, opts -func (_m *LaunchClient) GenesisAccountAll(ctx context.Context, in *types.QueryAllGenesisAccountRequest, opts ...grpc.CallOption) (*types.QueryAllGenesisAccountResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllGenesisAccountResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllGenesisAccountRequest, ...grpc.CallOption) *types.QueryAllGenesisAccountResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllGenesisAccountResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllGenesisAccountRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GenesisValidator provides a mock function with given fields: ctx, in, opts -func (_m *LaunchClient) GenesisValidator(ctx context.Context, in *types.QueryGetGenesisValidatorRequest, opts ...grpc.CallOption) (*types.QueryGetGenesisValidatorResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetGenesisValidatorResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetGenesisValidatorRequest, ...grpc.CallOption) *types.QueryGetGenesisValidatorResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetGenesisValidatorResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetGenesisValidatorRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GenesisValidatorAll provides a mock function with given fields: ctx, in, opts -func (_m *LaunchClient) GenesisValidatorAll(ctx context.Context, in *types.QueryAllGenesisValidatorRequest, opts ...grpc.CallOption) (*types.QueryAllGenesisValidatorResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllGenesisValidatorResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllGenesisValidatorRequest, ...grpc.CallOption) *types.QueryAllGenesisValidatorResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllGenesisValidatorResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllGenesisValidatorRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ParamChangeAll provides a mock function with given fields: ctx, in, opts -func (_m *LaunchClient) ParamChangeAll(ctx context.Context, in *types.QueryAllParamChangeRequest, opts ...grpc.CallOption) (*types.QueryAllParamChangeResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllParamChangeResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllParamChangeRequest, ...grpc.CallOption) *types.QueryAllParamChangeResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllParamChangeResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllParamChangeRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Params provides a mock function with given fields: ctx, in, opts -func (_m *LaunchClient) Params(ctx context.Context, in *types.QueryParamsRequest, opts ...grpc.CallOption) (*types.QueryParamsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryParamsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) *types.QueryParamsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryParamsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Request provides a mock function with given fields: ctx, in, opts -func (_m *LaunchClient) Request(ctx context.Context, in *types.QueryGetRequestRequest, opts ...grpc.CallOption) (*types.QueryGetRequestResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetRequestResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetRequestRequest, ...grpc.CallOption) *types.QueryGetRequestResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetRequestResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetRequestRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RequestAll provides a mock function with given fields: ctx, in, opts -func (_m *LaunchClient) RequestAll(ctx context.Context, in *types.QueryAllRequestRequest, opts ...grpc.CallOption) (*types.QueryAllRequestResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllRequestResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllRequestRequest, ...grpc.CallOption) *types.QueryAllRequestResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllRequestResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllRequestRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// VestingAccount provides a mock function with given fields: ctx, in, opts -func (_m *LaunchClient) VestingAccount(ctx context.Context, in *types.QueryGetVestingAccountRequest, opts ...grpc.CallOption) (*types.QueryGetVestingAccountResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetVestingAccountResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetVestingAccountRequest, ...grpc.CallOption) *types.QueryGetVestingAccountResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetVestingAccountResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetVestingAccountRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// VestingAccountAll provides a mock function with given fields: ctx, in, opts -func (_m *LaunchClient) VestingAccountAll(ctx context.Context, in *types.QueryAllVestingAccountRequest, opts ...grpc.CallOption) (*types.QueryAllVestingAccountResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllVestingAccountResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllVestingAccountRequest, ...grpc.CallOption) *types.QueryAllVestingAccountResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllVestingAccountResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllVestingAccountRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type mockConstructorTestingTNewLaunchClient interface { - mock.TestingT - Cleanup(func()) -} - -// NewLaunchClient creates a new instance of LaunchClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewLaunchClient(t mockConstructorTestingTNewLaunchClient) *LaunchClient { - mock := &LaunchClient{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/ignite/services/network/mocks/monitoringc_client.go b/ignite/services/network/mocks/monitoringc_client.go deleted file mode 100644 index f585bf98c5..0000000000 --- a/ignite/services/network/mocks/monitoringc_client.go +++ /dev/null @@ -1,237 +0,0 @@ -// Code generated by mockery v2.12.2. DO NOT EDIT. - -package mocks - -import ( - "context" - "testing" - - "github.com/stretchr/testify/mock" - "github.com/tendermint/spn/x/monitoringc/types" - "google.golang.org/grpc" -) - -// MonitoringcClient is an autogenerated mock type for the QueryClient type -type MonitoringcClient struct { - mock.Mock -} - -// LaunchIDFromChannelID provides a mock function with given fields: ctx, in, opts -func (_m *MonitoringcClient) LaunchIDFromChannelID(ctx context.Context, in *types.QueryGetLaunchIDFromChannelIDRequest, opts ...grpc.CallOption) (*types.QueryGetLaunchIDFromChannelIDResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetLaunchIDFromChannelIDResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetLaunchIDFromChannelIDRequest, ...grpc.CallOption) *types.QueryGetLaunchIDFromChannelIDResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetLaunchIDFromChannelIDResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetLaunchIDFromChannelIDRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// LaunchIDFromChannelIDAll provides a mock function with given fields: ctx, in, opts -func (_m *MonitoringcClient) LaunchIDFromChannelIDAll(ctx context.Context, in *types.QueryAllLaunchIDFromChannelIDRequest, opts ...grpc.CallOption) (*types.QueryAllLaunchIDFromChannelIDResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllLaunchIDFromChannelIDResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllLaunchIDFromChannelIDRequest, ...grpc.CallOption) *types.QueryAllLaunchIDFromChannelIDResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllLaunchIDFromChannelIDResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllLaunchIDFromChannelIDRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MonitoringHistory provides a mock function with given fields: ctx, in, opts -func (_m *MonitoringcClient) MonitoringHistory(ctx context.Context, in *types.QueryGetMonitoringHistoryRequest, opts ...grpc.CallOption) (*types.QueryGetMonitoringHistoryResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetMonitoringHistoryResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetMonitoringHistoryRequest, ...grpc.CallOption) *types.QueryGetMonitoringHistoryResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetMonitoringHistoryResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetMonitoringHistoryRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Params provides a mock function with given fields: ctx, in, opts -func (_m *MonitoringcClient) Params(ctx context.Context, in *types.QueryParamsRequest, opts ...grpc.CallOption) (*types.QueryParamsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryParamsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) *types.QueryParamsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryParamsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ProviderClientID provides a mock function with given fields: ctx, in, opts -func (_m *MonitoringcClient) ProviderClientID(ctx context.Context, in *types.QueryGetProviderClientIDRequest, opts ...grpc.CallOption) (*types.QueryGetProviderClientIDResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetProviderClientIDResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetProviderClientIDRequest, ...grpc.CallOption) *types.QueryGetProviderClientIDResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetProviderClientIDResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetProviderClientIDRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ProviderClientIDAll provides a mock function with given fields: ctx, in, opts -func (_m *MonitoringcClient) ProviderClientIDAll(ctx context.Context, in *types.QueryAllProviderClientIDRequest, opts ...grpc.CallOption) (*types.QueryAllProviderClientIDResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllProviderClientIDResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllProviderClientIDRequest, ...grpc.CallOption) *types.QueryAllProviderClientIDResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllProviderClientIDResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllProviderClientIDRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// VerifiedClientIds provides a mock function with given fields: ctx, in, opts -func (_m *MonitoringcClient) VerifiedClientIds(ctx context.Context, in *types.QueryGetVerifiedClientIdsRequest, opts ...grpc.CallOption) (*types.QueryGetVerifiedClientIdsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetVerifiedClientIdsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetVerifiedClientIdsRequest, ...grpc.CallOption) *types.QueryGetVerifiedClientIdsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetVerifiedClientIdsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetVerifiedClientIdsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// NewMonitoringcClient creates a new instance of MonitoringcClient. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. -func NewMonitoringcClient(t testing.TB) *MonitoringcClient { - mock := &MonitoringcClient{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/ignite/services/network/mocks/monitoringp_client.go b/ignite/services/network/mocks/monitoringp_client.go deleted file mode 100644 index f7cf4a69ba..0000000000 --- a/ignite/services/network/mocks/monitoringp_client.go +++ /dev/null @@ -1,151 +0,0 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. - -package mocks - -import ( - "context" - - "github.com/stretchr/testify/mock" - "github.com/tendermint/spn/x/monitoringp/types" - "google.golang.org/grpc" -) - -// MonitoringpClient is an autogenerated mock type for the QueryClient type -type MonitoringpClient struct { - mock.Mock -} - -// ConnectionChannelID provides a mock function with given fields: ctx, in, opts -func (_m *MonitoringpClient) ConnectionChannelID(ctx context.Context, in *types.QueryGetConnectionChannelIDRequest, opts ...grpc.CallOption) (*types.QueryGetConnectionChannelIDResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetConnectionChannelIDResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetConnectionChannelIDRequest, ...grpc.CallOption) *types.QueryGetConnectionChannelIDResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetConnectionChannelIDResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetConnectionChannelIDRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ConsumerClientID provides a mock function with given fields: ctx, in, opts -func (_m *MonitoringpClient) ConsumerClientID(ctx context.Context, in *types.QueryGetConsumerClientIDRequest, opts ...grpc.CallOption) (*types.QueryGetConsumerClientIDResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetConsumerClientIDResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetConsumerClientIDRequest, ...grpc.CallOption) *types.QueryGetConsumerClientIDResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetConsumerClientIDResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetConsumerClientIDRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MonitoringInfo provides a mock function with given fields: ctx, in, opts -func (_m *MonitoringpClient) MonitoringInfo(ctx context.Context, in *types.QueryGetMonitoringInfoRequest, opts ...grpc.CallOption) (*types.QueryGetMonitoringInfoResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetMonitoringInfoResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetMonitoringInfoRequest, ...grpc.CallOption) *types.QueryGetMonitoringInfoResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetMonitoringInfoResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetMonitoringInfoRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Params provides a mock function with given fields: ctx, in, opts -func (_m *MonitoringpClient) Params(ctx context.Context, in *types.QueryParamsRequest, opts ...grpc.CallOption) (*types.QueryParamsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryParamsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) *types.QueryParamsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryParamsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type NewMonitoringpClientT interface { - mock.TestingT - Cleanup(func()) -} - -// NewMonitoringpClient creates a new instance of MonitoringpClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewMonitoringpClient(t NewMonitoringpClientT) *MonitoringpClient { - mock := &MonitoringpClient{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/ignite/services/network/mocks/profile_client.go b/ignite/services/network/mocks/profile_client.go deleted file mode 100644 index 2cbfb59c8f..0000000000 --- a/ignite/services/network/mocks/profile_client.go +++ /dev/null @@ -1,213 +0,0 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. - -package mocks - -import ( - context "context" - - grpc "google.golang.org/grpc" - - mock "github.com/stretchr/testify/mock" - - types "github.com/tendermint/spn/x/profile/types" -) - -// ProfileClient is an autogenerated mock type for the ProfileClient type -type ProfileClient struct { - mock.Mock -} - -// Coordinator provides a mock function with given fields: ctx, in, opts -func (_m *ProfileClient) Coordinator(ctx context.Context, in *types.QueryGetCoordinatorRequest, opts ...grpc.CallOption) (*types.QueryGetCoordinatorResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetCoordinatorResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetCoordinatorRequest, ...grpc.CallOption) *types.QueryGetCoordinatorResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetCoordinatorResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetCoordinatorRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CoordinatorAll provides a mock function with given fields: ctx, in, opts -func (_m *ProfileClient) CoordinatorAll(ctx context.Context, in *types.QueryAllCoordinatorRequest, opts ...grpc.CallOption) (*types.QueryAllCoordinatorResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllCoordinatorResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllCoordinatorRequest, ...grpc.CallOption) *types.QueryAllCoordinatorResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllCoordinatorResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllCoordinatorRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CoordinatorByAddress provides a mock function with given fields: ctx, in, opts -func (_m *ProfileClient) CoordinatorByAddress(ctx context.Context, in *types.QueryGetCoordinatorByAddressRequest, opts ...grpc.CallOption) (*types.QueryGetCoordinatorByAddressResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetCoordinatorByAddressResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetCoordinatorByAddressRequest, ...grpc.CallOption) *types.QueryGetCoordinatorByAddressResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetCoordinatorByAddressResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetCoordinatorByAddressRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Validator provides a mock function with given fields: ctx, in, opts -func (_m *ProfileClient) Validator(ctx context.Context, in *types.QueryGetValidatorRequest, opts ...grpc.CallOption) (*types.QueryGetValidatorResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetValidatorResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetValidatorRequest, ...grpc.CallOption) *types.QueryGetValidatorResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetValidatorResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetValidatorRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ValidatorAll provides a mock function with given fields: ctx, in, opts -func (_m *ProfileClient) ValidatorAll(ctx context.Context, in *types.QueryAllValidatorRequest, opts ...grpc.CallOption) (*types.QueryAllValidatorResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllValidatorResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllValidatorRequest, ...grpc.CallOption) *types.QueryAllValidatorResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllValidatorResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllValidatorRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ValidatorByOperatorAddress provides a mock function with given fields: ctx, in, opts -func (_m *ProfileClient) ValidatorByOperatorAddress(ctx context.Context, in *types.QueryGetValidatorByOperatorAddressRequest, opts ...grpc.CallOption) (*types.QueryGetValidatorByOperatorAddressResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetValidatorByOperatorAddressResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetValidatorByOperatorAddressRequest, ...grpc.CallOption) *types.QueryGetValidatorByOperatorAddressResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetValidatorByOperatorAddressResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetValidatorByOperatorAddressRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type mockConstructorTestingTNewProfileClient interface { - mock.TestingT - Cleanup(func()) -} - -// NewProfileClient creates a new instance of ProfileClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewProfileClient(t mockConstructorTestingTNewProfileClient) *ProfileClient { - mock := &ProfileClient{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/ignite/services/network/mocks/reward_client.go b/ignite/services/network/mocks/reward_client.go deleted file mode 100644 index 28d3122ec6..0000000000 --- a/ignite/services/network/mocks/reward_client.go +++ /dev/null @@ -1,123 +0,0 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. - -package mocks - -import ( - context "context" - - grpc "google.golang.org/grpc" - - mock "github.com/stretchr/testify/mock" - - types "github.com/tendermint/spn/x/reward/types" -) - -// RewardClient is an autogenerated mock type for the RewardClient type -type RewardClient struct { - mock.Mock -} - -// Params provides a mock function with given fields: ctx, in, opts -func (_m *RewardClient) Params(ctx context.Context, in *types.QueryParamsRequest, opts ...grpc.CallOption) (*types.QueryParamsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryParamsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) *types.QueryParamsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryParamsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RewardPool provides a mock function with given fields: ctx, in, opts -func (_m *RewardClient) RewardPool(ctx context.Context, in *types.QueryGetRewardPoolRequest, opts ...grpc.CallOption) (*types.QueryGetRewardPoolResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryGetRewardPoolResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryGetRewardPoolRequest, ...grpc.CallOption) *types.QueryGetRewardPoolResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryGetRewardPoolResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryGetRewardPoolRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RewardPoolAll provides a mock function with given fields: ctx, in, opts -func (_m *RewardClient) RewardPoolAll(ctx context.Context, in *types.QueryAllRewardPoolRequest, opts ...grpc.CallOption) (*types.QueryAllRewardPoolResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllRewardPoolResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllRewardPoolRequest, ...grpc.CallOption) *types.QueryAllRewardPoolResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllRewardPoolResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllRewardPoolRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type mockConstructorTestingTNewRewardClient interface { - mock.TestingT - Cleanup(func()) -} - -// NewRewardClient creates a new instance of RewardClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewRewardClient(t mockConstructorTestingTNewRewardClient) *RewardClient { - mock := &RewardClient{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/ignite/services/network/mocks/staking_client.go b/ignite/services/network/mocks/staking_client.go deleted file mode 100644 index 355b3373f9..0000000000 --- a/ignite/services/network/mocks/staking_client.go +++ /dev/null @@ -1,453 +0,0 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. - -package mocks - -import ( - context "context" - - grpc "google.golang.org/grpc" - - mock "github.com/stretchr/testify/mock" - - types "github.com/cosmos/cosmos-sdk/x/staking/types" -) - -// StakingClient is an autogenerated mock type for the StakingClient type -type StakingClient struct { - mock.Mock -} - -// Delegation provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) Delegation(ctx context.Context, in *types.QueryDelegationRequest, opts ...grpc.CallOption) (*types.QueryDelegationResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryDelegationResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryDelegationRequest, ...grpc.CallOption) *types.QueryDelegationResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryDelegationResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryDelegationRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DelegatorDelegations provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) DelegatorDelegations(ctx context.Context, in *types.QueryDelegatorDelegationsRequest, opts ...grpc.CallOption) (*types.QueryDelegatorDelegationsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryDelegatorDelegationsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryDelegatorDelegationsRequest, ...grpc.CallOption) *types.QueryDelegatorDelegationsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryDelegatorDelegationsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryDelegatorDelegationsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DelegatorUnbondingDelegations provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) DelegatorUnbondingDelegations(ctx context.Context, in *types.QueryDelegatorUnbondingDelegationsRequest, opts ...grpc.CallOption) (*types.QueryDelegatorUnbondingDelegationsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryDelegatorUnbondingDelegationsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryDelegatorUnbondingDelegationsRequest, ...grpc.CallOption) *types.QueryDelegatorUnbondingDelegationsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryDelegatorUnbondingDelegationsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryDelegatorUnbondingDelegationsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DelegatorValidator provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) DelegatorValidator(ctx context.Context, in *types.QueryDelegatorValidatorRequest, opts ...grpc.CallOption) (*types.QueryDelegatorValidatorResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryDelegatorValidatorResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryDelegatorValidatorRequest, ...grpc.CallOption) *types.QueryDelegatorValidatorResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryDelegatorValidatorResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryDelegatorValidatorRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DelegatorValidators provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) DelegatorValidators(ctx context.Context, in *types.QueryDelegatorValidatorsRequest, opts ...grpc.CallOption) (*types.QueryDelegatorValidatorsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryDelegatorValidatorsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryDelegatorValidatorsRequest, ...grpc.CallOption) *types.QueryDelegatorValidatorsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryDelegatorValidatorsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryDelegatorValidatorsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// HistoricalInfo provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) HistoricalInfo(ctx context.Context, in *types.QueryHistoricalInfoRequest, opts ...grpc.CallOption) (*types.QueryHistoricalInfoResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryHistoricalInfoResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryHistoricalInfoRequest, ...grpc.CallOption) *types.QueryHistoricalInfoResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryHistoricalInfoResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryHistoricalInfoRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Params provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) Params(ctx context.Context, in *types.QueryParamsRequest, opts ...grpc.CallOption) (*types.QueryParamsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryParamsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) *types.QueryParamsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryParamsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Pool provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) Pool(ctx context.Context, in *types.QueryPoolRequest, opts ...grpc.CallOption) (*types.QueryPoolResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryPoolResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryPoolRequest, ...grpc.CallOption) *types.QueryPoolResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryPoolResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryPoolRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Redelegations provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) Redelegations(ctx context.Context, in *types.QueryRedelegationsRequest, opts ...grpc.CallOption) (*types.QueryRedelegationsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryRedelegationsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryRedelegationsRequest, ...grpc.CallOption) *types.QueryRedelegationsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryRedelegationsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryRedelegationsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// UnbondingDelegation provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) UnbondingDelegation(ctx context.Context, in *types.QueryUnbondingDelegationRequest, opts ...grpc.CallOption) (*types.QueryUnbondingDelegationResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryUnbondingDelegationResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryUnbondingDelegationRequest, ...grpc.CallOption) *types.QueryUnbondingDelegationResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryUnbondingDelegationResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryUnbondingDelegationRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Validator provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) Validator(ctx context.Context, in *types.QueryValidatorRequest, opts ...grpc.CallOption) (*types.QueryValidatorResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryValidatorResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryValidatorRequest, ...grpc.CallOption) *types.QueryValidatorResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryValidatorResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryValidatorRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ValidatorDelegations provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) ValidatorDelegations(ctx context.Context, in *types.QueryValidatorDelegationsRequest, opts ...grpc.CallOption) (*types.QueryValidatorDelegationsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryValidatorDelegationsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryValidatorDelegationsRequest, ...grpc.CallOption) *types.QueryValidatorDelegationsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryValidatorDelegationsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryValidatorDelegationsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ValidatorUnbondingDelegations provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) ValidatorUnbondingDelegations(ctx context.Context, in *types.QueryValidatorUnbondingDelegationsRequest, opts ...grpc.CallOption) (*types.QueryValidatorUnbondingDelegationsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryValidatorUnbondingDelegationsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryValidatorUnbondingDelegationsRequest, ...grpc.CallOption) *types.QueryValidatorUnbondingDelegationsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryValidatorUnbondingDelegationsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryValidatorUnbondingDelegationsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Validators provides a mock function with given fields: ctx, in, opts -func (_m *StakingClient) Validators(ctx context.Context, in *types.QueryValidatorsRequest, opts ...grpc.CallOption) (*types.QueryValidatorsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryValidatorsResponse - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryValidatorsRequest, ...grpc.CallOption) *types.QueryValidatorsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryValidatorsResponse) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryValidatorsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type mockConstructorTestingTNewStakingClient interface { - mock.TestingT - Cleanup(func()) -} - -// NewStakingClient creates a new instance of StakingClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewStakingClient(t mockConstructorTestingTNewStakingClient) *StakingClient { - mock := &StakingClient{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/ignite/services/network/network.go b/ignite/services/network/network.go deleted file mode 100644 index c74e57f19d..0000000000 --- a/ignite/services/network/network.go +++ /dev/null @@ -1,152 +0,0 @@ -package network - -import ( - "context" - "strconv" - - "github.com/cosmos/cosmos-sdk/client" - sdktypes "github.com/cosmos/cosmos-sdk/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/pkg/errors" - campaigntypes "github.com/tendermint/spn/x/campaign/types" - launchtypes "github.com/tendermint/spn/x/launch/types" - monitoringctypes "github.com/tendermint/spn/x/monitoringc/types" - profiletypes "github.com/tendermint/spn/x/profile/types" - rewardtypes "github.com/tendermint/spn/x/reward/types" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - - "github.com/ignite/cli/ignite/pkg/cosmosaccount" - "github.com/ignite/cli/ignite/pkg/cosmosclient" - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/pkg/xtime" -) - -//go:generate mockery --name CosmosClient --case underscore -type CosmosClient interface { - Context() client.Context - BroadcastTx(ctx context.Context, account cosmosaccount.Account, msgs ...sdktypes.Msg) (cosmosclient.Response, error) - Status(ctx context.Context) (*ctypes.ResultStatus, error) - ConsensusInfo(ctx context.Context, height int64) (cosmosclient.ConsensusInfo, error) -} - -// Network is network builder. -type Network struct { - node Node - ev events.Bus - cosmos CosmosClient - account cosmosaccount.Account - campaignQuery campaigntypes.QueryClient - launchQuery launchtypes.QueryClient - profileQuery profiletypes.QueryClient - rewardQuery rewardtypes.QueryClient - stakingQuery stakingtypes.QueryClient - bankQuery banktypes.QueryClient - monitoringConsumerQuery monitoringctypes.QueryClient - clock xtime.Clock -} - -//go:generate mockery --name Chain --case underscore -type Chain interface { - ID() (string, error) - ChainID() (string, error) - Name() string - SourceURL() string - SourceHash() string - GenesisPath() (string, error) - GentxsPath() (string, error) - DefaultGentxPath() (string, error) - AppTOMLPath() (string, error) - ConfigTOMLPath() (string, error) - NodeID(ctx context.Context) (string, error) - CacheBinary(launchID uint64) error -} - -type Option func(*Network) - -func WithCampaignQueryClient(client campaigntypes.QueryClient) Option { - return func(n *Network) { - n.campaignQuery = client - } -} - -func WithProfileQueryClient(client profiletypes.QueryClient) Option { - return func(n *Network) { - n.profileQuery = client - } -} - -func WithLaunchQueryClient(client launchtypes.QueryClient) Option { - return func(n *Network) { - n.launchQuery = client - } -} - -func WithRewardQueryClient(client rewardtypes.QueryClient) Option { - return func(n *Network) { - n.rewardQuery = client - } -} - -func WithStakingQueryClient(client stakingtypes.QueryClient) Option { - return func(n *Network) { - n.node.stakingQuery = client - } -} - -func WithMonitoringConsumerQueryClient(client monitoringctypes.QueryClient) Option { - return func(n *Network) { - n.monitoringConsumerQuery = client - } -} - -func WithBankQueryClient(client banktypes.QueryClient) Option { - return func(n *Network) { - n.bankQuery = client - } -} - -func WithCustomClock(clock xtime.Clock) Option { - return func(n *Network) { - n.clock = clock - } -} - -// CollectEvents collects events from the network builder. -func CollectEvents(ev events.Bus) Option { - return func(n *Network) { - n.ev = ev - } -} - -// New creates a Builder. -func New(cosmos CosmosClient, account cosmosaccount.Account, options ...Option) Network { - n := Network{ - cosmos: cosmos, - account: account, - node: NewNode(cosmos), - campaignQuery: campaigntypes.NewQueryClient(cosmos.Context()), - launchQuery: launchtypes.NewQueryClient(cosmos.Context()), - profileQuery: profiletypes.NewQueryClient(cosmos.Context()), - rewardQuery: rewardtypes.NewQueryClient(cosmos.Context()), - stakingQuery: stakingtypes.NewQueryClient(cosmos.Context()), - bankQuery: banktypes.NewQueryClient(cosmos.Context()), - monitoringConsumerQuery: monitoringctypes.NewQueryClient(cosmos.Context()), - clock: xtime.NewClockSystem(), - } - for _, opt := range options { - opt(&n) - } - return n -} - -func ParseID(id string) (uint64, error) { - objID, err := strconv.ParseUint(id, 10, 64) - if err != nil { - return 0, errors.Wrap(err, "error parsing ID") - } - if objID == 0 { - return 0, errors.New("ID must be greater than 0") - } - return objID, nil -} diff --git a/ignite/services/network/network_test.go b/ignite/services/network/network_test.go deleted file mode 100644 index 26f98c7a57..0000000000 --- a/ignite/services/network/network_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package network - -import ( - "errors" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "github.com/ignite/cli/ignite/pkg/cosmosaccount" - "github.com/ignite/cli/ignite/pkg/xtime" - "github.com/ignite/cli/ignite/services/network/testutil" -) - -var sampleTime = time.Unix(1000, 1000) - -func newSuite(account cosmosaccount.Account) (testutil.Suite, Network) { - suite := testutil.NewSuite() - return suite, New( - suite.CosmosClientMock, - account, - WithCampaignQueryClient(suite.CampaignQueryMock), - WithLaunchQueryClient(suite.LaunchQueryMock), - WithProfileQueryClient(suite.ProfileQueryMock), - WithRewardQueryClient(suite.RewardClient), - WithStakingQueryClient(suite.StakingClient), - WithMonitoringConsumerQueryClient(suite.MonitoringConsumerClient), - WithBankQueryClient(suite.BankClient), - WithCustomClock(xtime.NewClockMock(sampleTime)), - ) -} - -func TestParseID(t *testing.T) { - tests := []struct { - name string - id string - want uint64 - err error - }{ - { - name: "valid number", - id: "10", - want: 10, - }, - { - name: "invalid uint", - id: "-10", - err: errors.New("error parsing ID: strconv.ParseUint: parsing \"-10\": invalid syntax"), - }, - { - name: "invalid string", - id: "test", - err: errors.New("error parsing ID: strconv.ParseUint: parsing \"test\": invalid syntax"), - }, - { - name: "invalid launch id", - id: "0", - err: errors.New("ID must be greater than 0"), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ParseID(tt.id) - if tt.err != nil { - require.Error(t, err) - require.Equal(t, tt.err.Error(), err.Error()) - return - } - require.NoError(t, err) - require.Equal(t, tt.want, got) - }) - } -} - -func SampleSharePercent(t *testing.T, denom string, nominator, denominator uint64) SharePercent { - sp, err := NewSharePercent(denom, nominator, denominator) - require.NoError(t, err) - return sp -} diff --git a/ignite/services/network/networkchain/account.go b/ignite/services/network/networkchain/account.go deleted file mode 100644 index 148ca51b85..0000000000 --- a/ignite/services/network/networkchain/account.go +++ /dev/null @@ -1,107 +0,0 @@ -package networkchain - -import ( - "context" - "errors" - "os" - "path/filepath" - - chaincmdrunner "github.com/ignite/cli/ignite/pkg/chaincmd/runner" - "github.com/ignite/cli/ignite/pkg/cosmosutil" - "github.com/ignite/cli/ignite/pkg/randstr" - "github.com/ignite/cli/ignite/pkg/xos" - "github.com/ignite/cli/ignite/services/chain" -) - -const ( - passphraseLength = 32 - sampleAccount = "alice" -) - -// InitAccount initializes an account for the blockchain and issue a gentx in config/gentx/gentx.json. -func (c Chain) InitAccount(ctx context.Context, v chain.Validator, accountName string) (string, error) { - if !c.isInitialized { - return "", errors.New("the blockchain must be initialized to initialize an account") - } - - chainCmd, err := c.chain.Commands(ctx) - if err != nil { - return "", err - } - - // create the chain account. - address, err := c.ImportAccount(ctx, accountName) - if err != nil { - return "", err - } - - // add account into the genesis - err = chainCmd.AddGenesisAccount(ctx, address, v.StakingAmount) - if err != nil { - return "", err - } - - // create the gentx. - issuedGentxPath, err := c.chain.IssueGentx(ctx, v) - if err != nil { - return "", err - } - - // rename the issued gentx into gentx.json - gentxPath := filepath.Join(filepath.Dir(issuedGentxPath), cosmosutil.GentxFilename) - return gentxPath, xos.Rename(issuedGentxPath, gentxPath) -} - -// ImportAccount imports an account from Starport into the chain. -// we first export the account into a temporary key file and import it with the chain CLI. -func (c *Chain) ImportAccount(ctx context.Context, name string) (string, error) { - // keys import command of chain CLI requires that the key file is encrypted with a passphrase of at least 8 characters - // we generate a random passphrase to import the account - passphrase := randstr.Runes(passphraseLength) - - // export the key in a temporary file. - armored, err := c.ar.Export(name, passphrase) - if err != nil { - return "", err - } - - keyFile, err := os.CreateTemp("", "") - if err != nil { - return "", err - } - defer os.Remove(keyFile.Name()) - - if _, err := keyFile.Write([]byte(armored)); err != nil { - return "", err - } - - // import the key file into the chain. - chainCmd, err := c.chain.Commands(ctx) - if err != nil { - return "", err - } - - acc, err := chainCmd.ImportAccount(ctx, name, keyFile.Name(), passphrase) - return acc.Address, err -} - -// detectPrefix detects the account address prefix for the chain -// the method, creates a sample account and parses the address prefix from it. -func (c Chain) detectPrefix(ctx context.Context) (string, error) { - chainCmd, err := c.chain.Commands(ctx) - if err != nil { - return "", err - } - - var acc chaincmdrunner.Account - acc, err = chainCmd.ShowAccount(ctx, sampleAccount) - if errors.Is(err, chaincmdrunner.ErrAccountDoesNotExist) { - // the sample account doesn't exist, we create it - acc, err = chainCmd.AddAccount(ctx, sampleAccount, "", "") - } - if err != nil { - return "", err - } - - return cosmosutil.GetAddressPrefix(acc.Address) -} diff --git a/ignite/services/network/networkchain/binarycache.go b/ignite/services/network/networkchain/binarycache.go deleted file mode 100644 index 3ed4cd90be..0000000000 --- a/ignite/services/network/networkchain/binarycache.go +++ /dev/null @@ -1,86 +0,0 @@ -package networkchain - -import ( - "github.com/ignite/cli/ignite/config" - "github.com/ignite/cli/ignite/pkg/checksum" - "github.com/ignite/cli/ignite/pkg/confile" - "github.com/ignite/cli/ignite/pkg/xfilepath" -) - -const ( - SPNCacheDirectory = "spn" - BinaryCacheDirectory = "binary-cache" - BinaryCacheFilename = "checksums.yml" -) - -type BinaryCacheList struct { - CachedBinaries []Binary `yaml:"cached_binaries"` -} - -// Binary associates launch id with build hash where build hash is sha256(binary, source).. -type Binary struct { - LaunchID uint64 - BuildHash string -} - -func (l *BinaryCacheList) Set(launchID uint64, buildHash string) { - for i, binary := range l.CachedBinaries { - if binary.LaunchID == launchID { - l.CachedBinaries[i].BuildHash = buildHash - return - } - } - l.CachedBinaries = append(l.CachedBinaries, Binary{ - LaunchID: launchID, - BuildHash: buildHash, - }) -} - -func (l *BinaryCacheList) Get(launchID uint64) (string, bool) { - for _, binary := range l.CachedBinaries { - if binary.LaunchID == launchID { - return binary.BuildHash, true - } - } - return "", false -} - -// cacheBinaryForLaunchID caches hash sha256(sha256(binary) + sourcehash) for launch id. -func cacheBinaryForLaunchID(launchID uint64, binaryHash, sourceHash string) error { - cachePath, err := getBinaryCacheFilepath() - if err != nil { - return err - } - cacheList := BinaryCacheList{} - err = confile.New(confile.DefaultYAMLEncodingCreator, cachePath).Load(&cacheList) - if err != nil { - return err - } - cacheList.Set(launchID, checksum.Strings(binaryHash, sourceHash)) - - return confile.New(confile.DefaultYAMLEncodingCreator, cachePath).Save(cacheList) -} - -// checkBinaryCacheForLaunchID checks if binary for the given launch was already built. -func checkBinaryCacheForLaunchID(launchID uint64, binaryHash, sourceHash string) (bool, error) { - cachePath, err := getBinaryCacheFilepath() - if err != nil { - return false, err - } - cacheList := BinaryCacheList{} - err = confile.New(confile.DefaultYAMLEncodingCreator, cachePath).Load(&cacheList) - if err != nil { - return false, err - } - buildHash, ok := cacheList.Get(launchID) - return ok && buildHash == checksum.Strings(binaryHash, sourceHash), nil -} - -func getBinaryCacheFilepath() (string, error) { - return xfilepath.Join( - config.DirPath, - xfilepath.Path(SPNCacheDirectory), - xfilepath.Path(BinaryCacheDirectory), - xfilepath.Path(BinaryCacheFilename), - )() -} diff --git a/ignite/services/network/networkchain/config.go b/ignite/services/network/networkchain/config.go deleted file mode 100644 index 04927c8183..0000000000 --- a/ignite/services/network/networkchain/config.go +++ /dev/null @@ -1,50 +0,0 @@ -package networkchain - -import ( - "path/filepath" - - "github.com/ignite/cli/ignite/pkg/confile" - "github.com/ignite/cli/ignite/pkg/cosmosutil" -) - -const ( - HTTPTunnelChisel = "chisel" -) - -const SPNConfigFile = "spn.yml" - -type Config struct { - TunneledPeers []TunneledPeer `json:"tunneled_peers" yaml:"tunneled_peers"` -} - -// TunneledPeer represents http tunnel to a peer which can't be reached via regular tcp connection. -type TunneledPeer struct { - // Name represents tunnel type e.g. "chisel" - Name string `json:"name" yaml:"name"` - - // Address represents http address of the tunnel e.g. "https://tendermint-starport-i5e75cplx02.ws-eu31.gitpod.io/" - Address string `json:"address" yaml:"address"` - - // NodeID tendermint node id of the node behind the tunnel e.g. "e6a59e37b2761f26a21c9168f78a7f2b07c120c7" - NodeID string `json:"node_id" yaml:"node_id"` - - // LocalPort specifies port which has to be used for local tunnel client - LocalPort string `json:"local_port" yaml:"local_port"` -} - -func GetSPNConfig(path string) (conf Config, err error) { - err = confile.New(confile.DefaultYAMLEncodingCreator, path).Load(&conf) - return -} - -func SetSPNConfig(config Config, path string) error { - return confile.New(confile.DefaultYAMLEncodingCreator, path).Save(config) -} - -func (c *Chain) SPNConfigPath() (string, error) { - home, err := c.Home() - if err != nil { - return "", err - } - return filepath.Join(home, cosmosutil.ChainConfigDir, SPNConfigFile), nil -} diff --git a/ignite/services/network/networkchain/home.go b/ignite/services/network/networkchain/home.go deleted file mode 100644 index 9623e5cdd1..0000000000 --- a/ignite/services/network/networkchain/home.go +++ /dev/null @@ -1,30 +0,0 @@ -package networkchain - -import ( - "os" - "path/filepath" - "strconv" - - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// ChainHome returns the default home dir used for a chain from SPN. -func ChainHome(launchID uint64) (path string) { - home, err := os.UserHomeDir() - if err != nil { - panic(err) - } - - return filepath.Join(home, networktypes.SPN, strconv.FormatUint(launchID, 10)) -} - -// IsChainHomeExist checks if a home with the provided launchID already exist. -func IsChainHomeExist(launchID uint64) (path string, ok bool, err error) { - home := ChainHome(launchID) - - if _, err := os.Stat(home); os.IsNotExist(err) { - return home, false, nil - } - - return home, true, nil -} diff --git a/ignite/services/network/networkchain/home_test.go b/ignite/services/network/networkchain/home_test.go deleted file mode 100644 index bfc7adacd6..0000000000 --- a/ignite/services/network/networkchain/home_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package networkchain_test - -import ( - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/ignite/cli/ignite/services/network/networkchain" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -func TestChainHome(t *testing.T) { - home, err := os.UserHomeDir() - require.NoError(t, err) - - chainHome := networkchain.ChainHome(0) - require.Equal(t, filepath.Join(home, networktypes.SPN, "0"), chainHome) - - chainHome = networkchain.ChainHome(10) - require.Equal(t, filepath.Join(home, networktypes.SPN, "10"), chainHome) -} diff --git a/ignite/services/network/networkchain/init.go b/ignite/services/network/networkchain/init.go deleted file mode 100644 index 7543ed8dbd..0000000000 --- a/ignite/services/network/networkchain/init.go +++ /dev/null @@ -1,206 +0,0 @@ -package networkchain - -import ( - "context" - "errors" - "fmt" - "os" - "path/filepath" - - chainconfig "github.com/ignite/cli/ignite/config/chain" - "github.com/ignite/cli/ignite/pkg/cache" - cosmosgenesis "github.com/ignite/cli/ignite/pkg/cosmosutil/genesis" - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/services/chain" -) - -// Init initializes blockchain by building the binaries and running the init command, -// creates the initial genesis of the chain, and sets up a validator key. -func (c *Chain) Init(ctx context.Context, cacheStorage cache.Storage) error { - chainHome, err := c.chain.Home() - if err != nil { - return err - } - - // cleanup home dir of app if exists. - if err = os.RemoveAll(chainHome); err != nil { - return err - } - - // build the chain and initialize it with a new validator key - if _, err := c.Build(ctx, cacheStorage); err != nil { - return err - } - - c.ev.Send("Initializing the blockchain", events.ProgressStart()) - - if err = c.chain.Init(ctx, chain.InitArgsNone); err != nil { - return err - } - - c.ev.Send("Blockchain initialized", events.ProgressFinish()) - - // initialize and verify the genesis - if err = c.initGenesis(ctx); err != nil { - return err - } - - c.isInitialized = true - - return nil -} - -// initGenesis creates the initial genesis of the genesis depending on the initial genesis type (default, url, ...) -func (c *Chain) initGenesis(ctx context.Context) error { - c.ev.Send("Computing the Genesis", events.ProgressStart()) - - genesisPath, err := c.chain.GenesisPath() - if err != nil { - return err - } - - // remove existing genesis - if err := os.RemoveAll(genesisPath); err != nil { - return err - } - - // if the blockchain has a genesis URL, the initial genesis is fetched from the URL - // otherwise, the default genesis is used, which requires no action since the default genesis is generated from the init command - switch { - case c.genesisURL != "": - c.ev.Send("Fetching custom Genesis from URL", events.ProgressUpdate()) - genesis, err := cosmosgenesis.FromURL(ctx, c.genesisURL, genesisPath) - if err != nil { - return err - } - - if genesis.TarballPath() != "" { - c.ev.Send( - fmt.Sprintf("Extracted custom Genesis from tarball at %s", genesis.TarballPath()), - events.ProgressFinish(), - ) - } else { - c.ev.Send("Custom Genesis JSON from URL fetched", events.ProgressFinish()) - } - - hash, err := genesis.Hash() - if err != nil { - return err - } - - // if the blockchain has been initialized with no genesis hash, we assign the fetched hash to it - // otherwise we check the genesis integrity with the existing hash - if c.genesisHash == "" { - c.genesisHash = hash - } else if hash != c.genesisHash { - return fmt.Errorf("genesis from URL %s is invalid. expected hash %s, actual hash %s", c.genesisURL, c.genesisHash, hash) - } - - genBytes, err := genesis.Bytes() - if err != nil { - return err - } - - // replace the default genesis with the fetched genesis - if err := os.WriteFile(genesisPath, genBytes, 0o644); err != nil { - return err - } - case c.genesisConfig != "": - c.ev.Send("Fetching custom genesis from chain config", events.ProgressUpdate()) - - // first, initialize with default genesis - cmd, err := c.chain.Commands(ctx) - if err != nil { - return err - } - - // TODO: use validator moniker https://github.com/ignite/cli/issues/1834 - if err := cmd.Init(ctx, "moniker"); err != nil { - return err - } - - // find config in downloaded source - path := filepath.Join(c.path, c.genesisConfig) - if _, err := os.Stat(path); err != nil { - return fmt.Errorf("the config for genesis doesn't exist: %w", err) - } - - config, err := chainconfig.ParseNetworkFile(path) - if err != nil { - return err - } - - // make sure that chain id given during chain.New() has the most priority. - chainID, err := c.ID() - if err != nil { - return err - } - if config.Genesis != nil { - config.Genesis["chain_id"] = chainID - } - - // update genesis file with the genesis values defined in the config - if err := c.chain.UpdateGenesisFile(config.Genesis); err != nil { - return err - } - - if err := c.chain.InitAccounts(ctx, config); err != nil { - return err - } - - default: - // default genesis is used, init CLI command is used to generate it - cmd, err := c.chain.Commands(ctx) - if err != nil { - return err - } - - // TODO: use validator moniker https://github.com/ignite/cli/issues/1834 - if err := cmd.Init(ctx, "moniker"); err != nil { - return err - } - } - - // check the initial genesis is valid - if err := c.checkInitialGenesis(ctx); err != nil { - return err - } - - c.ev.Send("Genesis initialized", events.ProgressFinish()) - return nil -} - -// checkGenesis checks the stored genesis is valid. -func (c *Chain) checkInitialGenesis(ctx context.Context) error { - // perform static analysis of the chain with the validate-genesis command. - chainCmd, err := c.chain.Commands(ctx) - if err != nil { - return err - } - - // the chain initial genesis should not contain gentx, gentxs should be added through requests - genesisPath, err := c.chain.GenesisPath() - if err != nil { - return err - } - - chainGenesis, err := cosmosgenesis.FromPath(genesisPath) - if err != nil { - return err - } - - gentxCount, err := chainGenesis.GentxCount() - if err != nil { - return err - } - - if gentxCount > 0 { - return errors.New("the initial genesis for the chain should not contain gentx") - } - - return chainCmd.ValidateGenesis(ctx) - - // TODO: static analysis of the genesis with validate-genesis doesn't check the full validity of the genesis - // example: gentxs formats are not checked - // to perform a full validity check of the genesis we must try to start the chain with sample accounts -} diff --git a/ignite/services/network/networkchain/networkchain.go b/ignite/services/network/networkchain/networkchain.go deleted file mode 100644 index f17abbcb76..0000000000 --- a/ignite/services/network/networkchain/networkchain.go +++ /dev/null @@ -1,421 +0,0 @@ -package networkchain - -import ( - "context" - "errors" - "os" - "os/exec" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - - chainconfig "github.com/ignite/cli/ignite/config/chain" - "github.com/ignite/cli/ignite/pkg/cache" - "github.com/ignite/cli/ignite/pkg/chaincmd" - "github.com/ignite/cli/ignite/pkg/checksum" - "github.com/ignite/cli/ignite/pkg/cosmosaccount" - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/pkg/gitpod" - "github.com/ignite/cli/ignite/services/chain" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// Chain represents a network blockchain and lets you interact with its source code and binary. -type Chain struct { - id string - launchID uint64 - - path string - home string - - url string - hash string - genesisURL string - genesisHash string - genesisConfig string - launchTime time.Time - - accountBalance sdk.Coins - - keyringBackend chaincmd.KeyringBackend - - isInitialized bool - checkDependencies bool - - ref plumbing.ReferenceName - - chain *chain.Chain - ev events.Bus - ar cosmosaccount.Registry -} - -// SourceOption sets the source for blockchain. -type SourceOption func(*Chain) - -// Option sets other initialization options. -type Option func(*Chain) - -// SourceRemote sets the default branch on a remote as source for the blockchain. -func SourceRemote(url string) SourceOption { - return func(c *Chain) { - c.url = url - } -} - -// SourceRemoteBranch sets the branch on a remote as source for the blockchain. -func SourceRemoteBranch(url, branch string) SourceOption { - return func(c *Chain) { - c.url = url - c.ref = plumbing.NewBranchReferenceName(branch) - } -} - -// SourceRemoteTag sets the tag on a remote as source for the blockchain. -func SourceRemoteTag(url, tag string) SourceOption { - return func(c *Chain) { - c.url = url - c.ref = plumbing.NewTagReferenceName(tag) - } -} - -// SourceRemoteHash uses a remote hash as source for the blockchain. -func SourceRemoteHash(url, hash string) SourceOption { - return func(c *Chain) { - c.url = url - c.hash = hash - } -} - -// SourceLaunch returns a source option for initializing a chain from a launch. -func SourceLaunch(launch networktypes.ChainLaunch) SourceOption { - return func(c *Chain) { - c.id = launch.ChainID - c.launchID = launch.ID - c.url = launch.SourceURL - c.hash = launch.SourceHash - c.genesisURL = launch.GenesisURL - c.genesisHash = launch.GenesisHash - c.genesisConfig = launch.GenesisConfig - c.home = ChainHome(launch.ID) - c.launchTime = launch.LaunchTime - c.accountBalance = launch.AccountBalance - } -} - -// WithHome provides a specific home path for the blockchain for the initialization. -func WithHome(path string) Option { - return func(c *Chain) { - c.home = path - } -} - -// WithKeyringBackend provides the keyring backend to use to initialize the blockchain. -func WithKeyringBackend(keyringBackend chaincmd.KeyringBackend) Option { - return func(c *Chain) { - c.keyringBackend = keyringBackend - } -} - -// WithGenesisFromURL provides a genesis url for the initial genesis of the chain blockchain. -func WithGenesisFromURL(genesisURL string) Option { - return func(c *Chain) { - c.genesisURL = genesisURL - } -} - -// WithGenesisFromConfig provides a config file for the initial genesis of the chain blockchain. -func WithGenesisFromConfig(genesisConfig string) Option { - return func(c *Chain) { - c.genesisConfig = genesisConfig - } -} - -// CollectEvents collects events from the chain. -func CollectEvents(ev events.Bus) Option { - return func(c *Chain) { - c.ev = ev - } -} - -// CheckDependencies checks that cached Go dependencies of the chain have -// not been modified since they were downloaded. Dependencies are checked -// by running `go mod verify`. -func CheckDependencies() Option { - return func(c *Chain) { - c.checkDependencies = true - } -} - -// New initializes a network blockchain from source and options. -func New(ctx context.Context, ar cosmosaccount.Registry, source SourceOption, options ...Option) (*Chain, error) { - c := &Chain{ - ar: ar, - } - source(c) - for _, apply := range options { - apply(c) - } - - c.ev.Send("Fetching the source code", events.ProgressStart()) - - var err error - if c.path, c.hash, err = fetchSource(ctx, c.url, c.ref, c.hash); err != nil { - return nil, err - } - - c.ev.Send("Source code fetched", events.ProgressFinish()) - c.ev.Send("Setting up the blockchain", events.ProgressStart()) - - chainOption := []chain.Option{ - chain.ID(c.id), - chain.HomePath(c.home), - } - - if c.checkDependencies { - chainOption = append(chainOption, chain.CheckDependencies()) - } - - // use test keyring backend on Gitpod in order to prevent prompting for keyring - // password. This happens because Gitpod uses containers. - if gitpod.IsOnGitpod() { - c.keyringBackend = chaincmd.KeyringBackendTest - } - - chainOption = append(chainOption, chain.KeyringBackend(c.keyringBackend)) - - chain, err := chain.New(c.path, chainOption...) - if err != nil { - return nil, err - } - - c.chain = chain - c.ev.Send("Blockchain set up", events.ProgressFinish()) - - return c, nil -} - -func (c Chain) ChainID() (string, error) { - return c.chain.ChainID() -} - -func (c Chain) ID() (string, error) { - return c.chain.ID() -} - -func (c Chain) Name() string { - return c.chain.Name() -} - -func (c Chain) SetHome(home string) { - c.chain.SetHome(home) -} - -func (c Chain) Home() (path string, err error) { - return c.chain.Home() -} - -func (c Chain) BinaryName() (name string, err error) { - return c.chain.Binary() -} - -func (c Chain) GenesisPath() (path string, err error) { - return c.chain.GenesisPath() -} - -func (c Chain) GentxsPath() (path string, err error) { - return c.chain.GentxsPath() -} - -func (c Chain) DefaultGentxPath() (path string, err error) { - return c.chain.DefaultGentxPath() -} - -func (c Chain) AppTOMLPath() (string, error) { - return c.chain.AppTOMLPath() -} - -func (c Chain) ConfigTOMLPath() (string, error) { - return c.chain.ConfigTOMLPath() -} - -func (c Chain) SourceURL() string { - return c.url -} - -func (c Chain) SourceHash() string { - return c.hash -} - -func (c Chain) IsAccountBalanceFixed() bool { - return !c.accountBalance.IsZero() -} - -func (c Chain) AccountBalance() sdk.Coins { - return c.accountBalance -} - -func (c Chain) IsHomeDirExist() (ok bool, err error) { - home, err := c.chain.Home() - if err != nil { - return false, err - } - - _, err = os.Stat(home) - if os.IsNotExist(err) { - return false, nil - } - return err == nil, err -} - -// NodeID returns the chain node id. -func (c Chain) NodeID(ctx context.Context) (string, error) { - chainCmd, err := c.chain.Commands(ctx) - if err != nil { - return "", err - } - - nodeID, err := chainCmd.ShowNodeID(ctx) - if err != nil { - return "", err - } - return nodeID, nil -} - -// CheckConfigVersion checks that the config version is the latest. -func (c Chain) CheckConfigVersion() error { - configPath := c.chain.ConfigPath() - if configPath == "" { - return chainconfig.ErrConfigNotFound - } - - file, err := os.Open(configPath) - if err != nil { - return err - } - - defer file.Close() - - return chainconfig.CheckVersion(file) -} - -// Build builds chain sources, also checks if source was already built. -func (c *Chain) Build(ctx context.Context, cacheStorage cache.Storage) (binaryName string, err error) { - // Check that the config version is the latest before building the binary - if err = c.CheckConfigVersion(); err != nil && !errors.Is(err, chainconfig.ErrConfigNotFound) { - return - } - - // if chain was already published and has launch id check binary cache - if c.launchID != 0 { - if binaryName, err = c.chain.Binary(); err != nil { - return "", err - } - binaryChecksum, err := checksum.Binary(binaryName) - if err != nil && !errors.Is(err, exec.ErrNotFound) { - return "", err - } - binaryMatch, err := checkBinaryCacheForLaunchID(c.launchID, binaryChecksum, c.hash) - if err != nil { - return "", err - } - if binaryMatch { - return binaryName, nil - } - } - - c.ev.Send("Building the chain's binary", events.ProgressStart()) - - // build binary - if binaryName, err = c.chain.Build(ctx, cacheStorage, "", true, false); err != nil { - return "", err - } - - c.ev.Send("Chain's binary built", events.ProgressFinish()) - - // cache built binary for launch id - if c.launchID != 0 { - if err := c.CacheBinary(c.launchID); err != nil { - return "", nil - } - } - - return binaryName, nil -} - -// CacheBinary caches last built chain binary associated with launch id. -func (c *Chain) CacheBinary(launchID uint64) error { - binaryName, err := c.chain.Binary() - if err != nil { - return err - } - binaryChecksum, err := checksum.Binary(binaryName) - if err != nil { - return err - } - return cacheBinaryForLaunchID(launchID, binaryChecksum, c.hash) -} - -// fetchSource fetches the chain source from url and returns a temporary path where source is saved. -func fetchSource( - ctx context.Context, - url string, - ref plumbing.ReferenceName, - customHash string, -) (path, hash string, err error) { - var repo *git.Repository - - if path, err = os.MkdirTemp("", ""); err != nil { - return "", "", err - } - - // ensure the path for chain source exists - if err := os.MkdirAll(path, 0o755); err != nil { - return "", "", err - } - - // prepare clone options. - gitoptions := &git.CloneOptions{ - URL: url, - } - - // clone the ref when specified, this is used by chain coordinators on create. - if ref != "" { - gitoptions.ReferenceName = ref - gitoptions.SingleBranch = true - } - if repo, err = git.PlainCloneContext(ctx, path, false, gitoptions); err != nil { - return "", "", err - } - - if customHash != "" { - hash = customHash - - // checkout to a certain hash when specified. this is used by validators to make sure to use - // the locked version of the blockchain. - wt, err := repo.Worktree() - if err != nil { - return "", "", err - } - h, err := repo.ResolveRevision(plumbing.Revision(customHash)) - if err != nil { - return "", "", err - } - githash := *h - if err := wt.Checkout(&git.CheckoutOptions{ - Hash: githash, - }); err != nil { - return "", "", err - } - } else { - // when no specific hash is provided. HEAD is fetched - ref, err := repo.Head() - if err != nil { - return "", "", err - } - hash = ref.Hash().String() - } - - return path, hash, nil -} diff --git a/ignite/services/network/networkchain/prepare.go b/ignite/services/network/networkchain/prepare.go deleted file mode 100644 index 5dfc0e5d18..0000000000 --- a/ignite/services/network/networkchain/prepare.go +++ /dev/null @@ -1,351 +0,0 @@ -package networkchain - -import ( - "context" - "fmt" - "os" - "path/filepath" - "strconv" - "strings" - - "github.com/pelletier/go-toml" - "github.com/pkg/errors" - launchtypes "github.com/tendermint/spn/x/launch/types" - - "github.com/ignite/cli/ignite/pkg/cache" - "github.com/ignite/cli/ignite/pkg/cosmosutil" - cosmosgenesis "github.com/ignite/cli/ignite/pkg/cosmosutil/genesis" - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/pkg/jsonfile" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// Prepare prepares the chain to be launched from genesis information. -func (c Chain) Prepare( - ctx context.Context, - cacheStorage cache.Storage, - gi networktypes.GenesisInformation, - rewardsInfo networktypes.Reward, - spnChainID string, - lastBlockHeight, - consumerUnbondingTime int64, -) error { - // chain initialization - genesisPath, err := c.chain.GenesisPath() - if err != nil { - return err - } - - _, err = os.Stat(genesisPath) - - switch { - case os.IsNotExist(err): - // if no config exists, perform a full initialization of the chain with a new validator key - if err = c.Init(ctx, cacheStorage); err != nil { - return err - } - case err != nil: - return err - default: - // if config and validator key already exists, build the chain and initialize the genesis - if _, err := c.Build(ctx, cacheStorage); err != nil { - return err - } - - if err := c.initGenesis(ctx); err != nil { - return err - } - } - - if err := c.buildGenesis( - ctx, - gi, - rewardsInfo, - spnChainID, - lastBlockHeight, - consumerUnbondingTime, - ); err != nil { - return err - } - - cmd, err := c.chain.Commands(ctx) - if err != nil { - return err - } - - // ensure genesis has a valid format - if err := cmd.ValidateGenesis(ctx); err != nil { - return err - } - - // reset the saved state in case the chain has been started before - if err := cmd.UnsafeReset(ctx); err != nil { - return err - } - - return nil -} - -// buildGenesis builds the genesis for the chain from the launch approved requests. -func (c Chain) buildGenesis( - ctx context.Context, - gi networktypes.GenesisInformation, - rewardsInfo networktypes.Reward, - spnChainID string, - lastBlockHeight, - consumerUnbondingTime int64, -) error { - c.ev.Send("Building the genesis", events.ProgressStart()) - - addressPrefix, err := c.detectPrefix(ctx) - if err != nil { - return errors.Wrap(err, "error detecting chain prefix") - } - - // apply genesis information to the genesis - if err := c.applyGenesisAccounts(ctx, gi.GenesisAccounts, addressPrefix); err != nil { - return errors.Wrap(err, "error applying genesis accounts to genesis") - } - if err := c.applyVestingAccounts(ctx, gi.VestingAccounts, addressPrefix); err != nil { - return errors.Wrap(err, "error applying vesting accounts to genesis") - } - if err := c.applyGenesisValidators(ctx, gi.GenesisValidators); err != nil { - return errors.Wrap(err, "error applying genesis validators to genesis") - } - - genesisPath, err := c.chain.GenesisPath() - if err != nil { - return errors.Wrap(err, "genesis of the blockchain can't be read") - } - - genesis, err := cosmosgenesis.FromPath(genesisPath) - if err != nil { - return errors.Wrap(err, "genesis of the blockchain can't be parsed") - } - - // update chain ID and launch time - if err := genesis.Update( - jsonfile.WithKeyValue(cosmosgenesis.FieldChainID, c.id), - jsonfile.WithKeyValueTimestamp(cosmosgenesis.FieldGenesisTime, c.launchTime.Unix()), - ); err != nil { - return errors.Wrap(err, "genesis cannot be updated") - } - - // update reward related fields if the testnet is incentivized (with a last block height for reward distribution) - if lastBlockHeight > 0 { - if err := genesis.Update( - jsonfile.WithKeyValue(cosmosgenesis.FieldConsumerChainID, spnChainID), - jsonfile.WithKeyValueInt(cosmosgenesis.FieldLastBlockHeight, lastBlockHeight), - jsonfile.WithKeyValue(cosmosgenesis.FieldConsensusTimestamp, rewardsInfo.ConsensusState.Timestamp), - jsonfile.WithKeyValue(cosmosgenesis.FieldConsensusNextValidatorsHash, rewardsInfo.ConsensusState.NextValidatorsHash), - jsonfile.WithKeyValue(cosmosgenesis.FieldConsensusRootHash, rewardsInfo.ConsensusState.Root.Hash), - jsonfile.WithKeyValueInt(cosmosgenesis.FieldConsumerUnbondingPeriod, consumerUnbondingTime), - jsonfile.WithKeyValueUint(cosmosgenesis.FieldConsumerRevisionHeight, rewardsInfo.RevisionHeight), - ); err != nil { - return errors.Wrap(err, "genesis cannot be updated for reward related fields") - } - } - - if err := applyParamChanges(genesis, gi.ParamChanges); err != nil { - return fmt.Errorf("error applying param changes to genesis: %w", err) - } - - c.ev.Send("Genesis built", events.ProgressFinish()) - - return nil -} - -// applyGenesisAccounts adds the genesis account into the genesis using the chain CLI. -func (c Chain) applyGenesisAccounts( - ctx context.Context, - genesisAccs []networktypes.GenesisAccount, - addressPrefix string, -) error { - var err error - - cmd, err := c.chain.Commands(ctx) - if err != nil { - return err - } - - for _, acc := range genesisAccs { - // change the address prefix to the target chain prefix - acc.Address, err = cosmosutil.ChangeAddressPrefix(acc.Address, addressPrefix) - if err != nil { - return err - } - - // call the add genesis account CLI command - err = cmd.AddGenesisAccount(ctx, acc.Address, acc.Coins.String()) - if err != nil { - return err - } - } - - return nil -} - -// applyVestingAccounts adds the genesis vesting account into the genesis using the chain CLI. -func (c Chain) applyVestingAccounts( - ctx context.Context, - vestingAccs []networktypes.VestingAccount, - addressPrefix string, -) error { - cmd, err := c.chain.Commands(ctx) - if err != nil { - return err - } - - for _, acc := range vestingAccs { - acc.Address, err = cosmosutil.ChangeAddressPrefix(acc.Address, addressPrefix) - if err != nil { - return err - } - - // call the add genesis account CLI command with delayed vesting option - err = cmd.AddVestingAccount( - ctx, - acc.Address, - acc.TotalBalance.String(), - acc.Vesting.String(), - acc.EndTime, - ) - if err != nil { - return err - } - } - - return nil -} - -// applyGenesisValidators gathers the validator gentxs into the genesis and adds peers in config. -func (c Chain) applyGenesisValidators(ctx context.Context, genesisVals []networktypes.GenesisValidator) error { - // no validator - if len(genesisVals) == 0 { - return nil - } - - // reset the gentx directory - gentxDir, err := c.chain.GentxsPath() - if err != nil { - return err - } - if err := os.RemoveAll(gentxDir); err != nil { - return err - } - if err := os.MkdirAll(gentxDir, 0o700); err != nil { - return err - } - - // write gentxs - for i, val := range genesisVals { - gentxPath := filepath.Join(gentxDir, fmt.Sprintf("gentx%d.json", i)) - if err = os.WriteFile(gentxPath, val.Gentx, 0o666); err != nil { - return err - } - } - - // gather gentxs - cmd, err := c.chain.Commands(ctx) - if err != nil { - return err - } - if err := cmd.CollectGentxs(ctx); err != nil { - return err - } - - return c.updateConfigFromGenesisValidators(genesisVals) -} - -// applyParamChanges applies the param changes into the genesis. -func applyParamChanges( - genesis *cosmosgenesis.Genesis, - paramChanges []networktypes.ParamChange, -) error { - changes := make([]jsonfile.UpdateFileOption, len(paramChanges)) - - for i, pc := range paramChanges { - changes[i] = jsonfile.WithKeyValueByte(cosmosgenesis.ModuleParamField(pc.Module, pc.Param), pc.Value) - } - - if err := genesis.Update(changes...); err != nil { - return errors.Wrap(err, "failed to apply param change to genesis") - } - - return nil -} - -// updateConfigFromGenesisValidators adds the peer addresses into the config.toml of the chain. -func (c Chain) updateConfigFromGenesisValidators(genesisVals []networktypes.GenesisValidator) error { - var ( - p2pAddresses []string - tunnelAddresses []TunneledPeer - ) - for i, val := range genesisVals { - if !cosmosutil.VerifyPeerFormat(val.Peer) { - return errors.Errorf("invalid peer: %s", val.Peer.Id) - } - switch conn := val.Peer.Connection.(type) { - case *launchtypes.Peer_TcpAddress: - p2pAddresses = append(p2pAddresses, fmt.Sprintf("%s@%s", val.Peer.Id, conn.TcpAddress)) - case *launchtypes.Peer_HttpTunnel: - tunneledPeer := TunneledPeer{ - Name: conn.HttpTunnel.Name, - Address: conn.HttpTunnel.Address, - NodeID: val.Peer.Id, - LocalPort: strconv.Itoa(i + 22000), - } - tunnelAddresses = append(tunnelAddresses, tunneledPeer) - p2pAddresses = append(p2pAddresses, fmt.Sprintf("%s@127.0.0.1:%s", tunneledPeer.NodeID, tunneledPeer.LocalPort)) - default: - return fmt.Errorf("invalid peer type") - } - } - - if len(p2pAddresses) > 0 { - // set persistent peers - configPath, err := c.chain.ConfigTOMLPath() - if err != nil { - return err - } - configToml, err := toml.LoadFile(configPath) - if err != nil { - return err - } - configToml.Set("p2p.persistent_peers", strings.Join(p2pAddresses, ",")) - if err != nil { - return err - } - - // if there are tunneled peers they will be connected with tunnel clients via localhost, - // so we need to allow to have few nodes with the same ip - if len(tunnelAddresses) > 0 { - configToml.Set("p2p.allow_duplicate_ip", true) - } - - // save config.toml file - configTomlFile, err := os.OpenFile(configPath, os.O_RDWR|os.O_TRUNC, 0o644) - if err != nil { - return err - } - defer configTomlFile.Close() - - if _, err = configToml.WriteTo(configTomlFile); err != nil { - return err - } - } - - if len(tunnelAddresses) > 0 { - tunneledPeersConfigPath, err := c.SPNConfigPath() - if err != nil { - return err - } - - if err = SetSPNConfig(Config{ - TunneledPeers: tunnelAddresses, - }, tunneledPeersConfigPath); err != nil { - return err - } - } - return nil -} diff --git a/ignite/services/network/networkchain/request.go b/ignite/services/network/networkchain/request.go deleted file mode 100644 index 91b35b69cc..0000000000 --- a/ignite/services/network/networkchain/request.go +++ /dev/null @@ -1,62 +0,0 @@ -package networkchain - -import ( - "context" - "fmt" - - "github.com/pkg/errors" - - cosmosgenesis "github.com/ignite/cli/ignite/pkg/cosmosutil/genesis" - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// CheckRequestChangeParam builds the genesis for the chain from the launch approved requests. -func (c Chain) CheckRequestChangeParam( - ctx context.Context, - module, - param string, - value []byte, -) error { - c.ev.Send("Checking the param change", events.ProgressStart()) - - if err := c.initGenesis(ctx); err != nil { - return err - } - - genesisPath, err := c.chain.GenesisPath() - if err != nil { - return errors.Wrap(err, "genesis of the blockchain can't be read") - } - - genesis, err := cosmosgenesis.FromPath(genesisPath) - if err != nil { - return errors.Wrap(err, "genesis of the blockchain can't be parsed") - } - - pc := []networktypes.ParamChange{ - { - Module: module, - Param: param, - Value: value, - }, - } - - if err := applyParamChanges(genesis, pc); err != nil { - return fmt.Errorf("error applying param changes to genesis: %w", err) - } - - cmd, err := c.chain.Commands(ctx) - if err != nil { - return err - } - - // ensure genesis has a valid format - if err := cmd.ValidateGenesis(ctx); err != nil { - return fmt.Errorf("invalid parameter change requested: %w", err) - } - - c.ev.Send("Param change verified", events.ProgressFinish()) - - return nil -} diff --git a/ignite/services/network/networkchain/simulate.go b/ignite/services/network/networkchain/simulate.go deleted file mode 100644 index 9b60fef73a..0000000000 --- a/ignite/services/network/networkchain/simulate.go +++ /dev/null @@ -1,223 +0,0 @@ -package networkchain - -import ( - "context" - "fmt" - "os" - "strings" - "time" - - "github.com/cenkalti/backoff" - "github.com/pelletier/go-toml" - "github.com/pkg/errors" - - "github.com/ignite/cli/ignite/pkg/availableport" - "github.com/ignite/cli/ignite/pkg/cache" - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/pkg/httpstatuschecker" - "github.com/ignite/cli/ignite/pkg/xurl" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// listeningTimeout is the maximum time to wait for the chain start. -const listeningTimeout = time.Minute * 1 - -// validatorSetNilErrorMessages contains variation for SDK validator set empty error message/ -// to detect if the chain fails to start because the validator set is nil. -var validatorSetNilErrorMessages = []string{ - "validator set is nil in genesis and still empty after InitChain", - "validator set is empty after InitGenesis", -} - -// SimulateRequests simulates the genesis creation and the start of the network from the provided requests. -func (c Chain) SimulateRequests( - ctx context.Context, - cacheStorage cache.Storage, - gi networktypes.GenesisInformation, - reqs []networktypes.Request, -) (err error) { - c.ev.Send("Verifying requests format", events.ProgressStart()) - for _, req := range reqs { - // static verification of the request - if err := networktypes.VerifyRequest(req); err != nil { - return err - } - - // apply the request to the genesis information - gi, err = gi.ApplyRequest(req) - if err != nil { - return err - } - } - c.ev.Send("Requests format verified", events.ProgressFinish()) - - // prepare the chain with the requests - if err := c.Prepare( - ctx, - cacheStorage, - gi, - networktypes.Reward{RevisionHeight: 1}, - networktypes.SPNChainID, - 1, - 2, - ); err != nil { - return err - } - - c.ev.Send("Trying starting the network with the requests", events.ProgressStart()) - if err := c.simulateChainStart(ctx); err != nil { - return err - } - c.ev.Send("The network can be started", events.ProgressFinish()) - - return nil -} - -// SimulateChainStart simulates and verify the chain start by starting it with a simulation config -// and checking if the gentxs execution is successful. -func (c Chain) simulateChainStart(ctx context.Context) error { - cmd, err := c.chain.Commands(ctx) - if err != nil { - return err - } - - // set the config with random ports to test the start command - rpcAddr, err := c.setSimulationConfig() - if err != nil { - return err - } - - // verify that the chain can be started with a valid genesis - ctx, cancel := context.WithTimeout(ctx, listeningTimeout) - exit := make(chan error) - - // routine to check the app is listening - go func() { - defer cancel() - exit <- isChainListening(ctx, rpcAddr) - }() - - // check an error is realted to validator set empty - checkValidatorSetEmptyError := func(err error) bool { - if err != nil { - for _, errStr := range validatorSetNilErrorMessages { - if strings.Contains(err.Error(), errStr) { - return true - } - } - } - - return false - } - - // routine chain start - go func() { - // if the error is validator set is nil, it means the genesis didn't get broken after an applied request - // the genesis was correctly generated but there is no gentxs so far - // so we don't consider it as an error making requests to verify as invalid - err := cmd.Start(ctx) - if checkValidatorSetEmptyError(err) { - err = nil - } - exit <- errors.Wrap(err, "the chain failed to start") - }() - - return <-exit -} - -// setSimulationConfig sets in the config random available ports to allow check if the chain network can start. -func (c Chain) setSimulationConfig() (string, error) { - // generate random server ports and servers list - ports, err := availableport.Find(5) - if err != nil { - return "", err - } - genAddr := func(port int) string { - return fmt.Sprintf("localhost:%d", port) - } - - // updating app toml - appPath, err := c.AppTOMLPath() - if err != nil { - return "", err - } - config, err := toml.LoadFile(appPath) - if err != nil { - return "", err - } - - apiAddr, err := xurl.TCP(genAddr(ports[0])) - if err != nil { - return "", err - } - - config.Set("api.enable", true) - config.Set("api.enabled-unsafe-cors", true) - config.Set("rpc.cors_allowed_origins", []string{"*"}) - config.Set("api.address", apiAddr) - config.Set("grpc.address", genAddr(ports[1])) - - file, err := os.OpenFile(appPath, os.O_RDWR|os.O_TRUNC, 0o644) - if err != nil { - return "", err - } - defer file.Close() - - if _, err := config.WriteTo(file); err != nil { - return "", err - } - - // updating config toml - configPath, err := c.ConfigTOMLPath() - if err != nil { - return "", err - } - config, err = toml.LoadFile(configPath) - if err != nil { - return "", err - } - - rpcAddr, err := xurl.TCP(genAddr(ports[2])) - if err != nil { - return "", err - } - - p2pAddr, err := xurl.TCP(genAddr(ports[3])) - if err != nil { - return "", err - } - - config.Set("rpc.cors_allowed_origins", []string{"*"}) - config.Set("consensus.timeout_commit", "1s") - config.Set("consensus.timeout_propose", "1s") - config.Set("rpc.laddr", rpcAddr) - config.Set("p2p.laddr", p2pAddr) - config.Set("rpc.pprof_laddr", genAddr(ports[4])) - - file, err = os.OpenFile(configPath, os.O_RDWR|os.O_TRUNC, 0o644) - if err != nil { - return "", err - } - defer file.Close() - - _, err = config.WriteTo(file) - - return genAddr(ports[2]), err -} - -// isChainListening checks if the chain is listening for RPC queries on the specified address. -func isChainListening(ctx context.Context, rpcAddr string) error { - checkAlive := func() error { - addr, err := xurl.HTTP(rpcAddr) - if err != nil { - return fmt.Errorf("invalid rpc address format %s: %w", rpcAddr, err) - } - - ok, err := httpstatuschecker.Check(ctx, fmt.Sprintf("%s/health", addr)) - if err == nil && !ok { - err = errors.New("app is not online") - } - return err - } - return backoff.Retry(checkAlive, backoff.WithContext(backoff.NewConstantBackOff(time.Second), ctx)) -} diff --git a/ignite/services/network/networktypes/chainlaunch.go b/ignite/services/network/networktypes/chainlaunch.go deleted file mode 100644 index 4c949242ca..0000000000 --- a/ignite/services/network/networktypes/chainlaunch.go +++ /dev/null @@ -1,87 +0,0 @@ -package networktypes - -import ( - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - yaml "github.com/goccy/go-yaml" - launchtypes "github.com/tendermint/spn/x/launch/types" -) - -type ( - NetworkType string - - // ChainLaunch represents the launch of a chain on SPN. - ChainLaunch struct { - ID uint64 `json:"ID"` - ConsumerRevisionHeight int64 `json:"ConsumerRevisionHeight"` - ChainID string `json:"ChainID"` - SourceURL string `json:"SourceURL"` - SourceHash string `json:"SourceHash"` - GenesisURL string `json:"GenesisURL"` - GenesisHash string `json:"GenesisHash"` - GenesisConfig string `json:"GenesisConfig"` - LaunchTime time.Time `json:"LaunchTime"` - ProjectID uint64 `json:"ProjectID"` - LaunchTriggered bool `json:"LaunchTriggered"` - Network NetworkType `json:"Network"` - Reward string `json:"Reward,omitempty"` - AccountBalance sdk.Coins `json:"AccountBalance"` - Metadata interface{} `json:"Metadata"` - } -) - -const ( - NetworkTypeMainnet NetworkType = "mainnet" - NetworkTypeTestnet NetworkType = "testnet" -) - -func (n NetworkType) String() string { - return string(n) -} - -// ToChainLaunch converts a chain launch data from SPN and returns a ChainLaunch object. -func ToChainLaunch(chain launchtypes.Chain) ChainLaunch { - var launchTime time.Time - if chain.LaunchTriggered { - launchTime = chain.LaunchTime - } - - network := NetworkTypeTestnet - if chain.IsMainnet { - network = NetworkTypeMainnet - } - - launch := ChainLaunch{ - ID: chain.LaunchID, - ConsumerRevisionHeight: chain.ConsumerRevisionHeight, - ChainID: chain.GenesisChainID, - SourceURL: chain.SourceURL, - SourceHash: chain.SourceHash, - LaunchTime: launchTime, - ProjectID: chain.CampaignID, - LaunchTriggered: chain.LaunchTriggered, - Network: network, - AccountBalance: chain.AccountBalance, - } - - err := yaml.Unmarshal(chain.Metadata, &launch.Metadata) - if err != nil { - // an error shouldn't happen - // in case it occurs, we consider metadata as invalid and dismiss those - launch.Metadata = nil - } - - // check if custom genesis URL is provided. - if customGenesisURL := chain.InitialGenesis.GetGenesisURL(); customGenesisURL != nil { - launch.GenesisURL = customGenesisURL.Url - launch.GenesisHash = customGenesisURL.Hash - } - - // check if custom config genesis if provided. - if customGenesisConfig := chain.InitialGenesis.GetGenesisConfig(); customGenesisConfig != nil { - launch.GenesisConfig = customGenesisConfig.File - } - - return launch -} diff --git a/ignite/services/network/networktypes/chainlaunch_test.go b/ignite/services/network/networktypes/chainlaunch_test.go deleted file mode 100644 index 22ef0a27b2..0000000000 --- a/ignite/services/network/networktypes/chainlaunch_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package networktypes_test - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - launchtypes "github.com/tendermint/spn/x/launch/types" - - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -func TestToChainLaunch(t *testing.T) { - tests := []struct { - name string - fetched launchtypes.Chain - expected networktypes.ChainLaunch - }{ - { - name: "chain with default genesis", - fetched: launchtypes.Chain{ - LaunchID: 1, - GenesisChainID: "foo-1", - SourceURL: "foo.com", - SourceHash: "0xaaa", - HasCampaign: true, - CampaignID: 1, - InitialGenesis: launchtypes.NewDefaultInitialGenesis(), - }, - expected: networktypes.ChainLaunch{ - ID: 1, - ChainID: "foo-1", - SourceURL: "foo.com", - SourceHash: "0xaaa", - GenesisURL: "", - GenesisHash: "", - LaunchTriggered: false, - ProjectID: 1, - Network: "testnet", - }, - }, - { - name: "launched chain with custom genesis url and no project", - fetched: launchtypes.Chain{ - LaunchID: 1, - GenesisChainID: "bar-1", - SourceURL: "bar.com", - SourceHash: "0xbbb", - LaunchTriggered: true, - LaunchTime: time.Unix(100, 100).UTC(), - InitialGenesis: launchtypes.NewGenesisURL( - "genesisfoo.com", - "0xccc", - ), - }, - expected: networktypes.ChainLaunch{ - ID: 1, - ChainID: "bar-1", - SourceURL: "bar.com", - SourceHash: "0xbbb", - GenesisURL: "genesisfoo.com", - GenesisHash: "0xccc", - LaunchTriggered: true, - LaunchTime: time.Unix(100, 100).UTC(), - ProjectID: 0, - Network: "testnet", - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require.EqualValues(t, tt.expected, networktypes.ToChainLaunch(tt.fetched)) - }) - } -} diff --git a/ignite/services/network/networktypes/error.go b/ignite/services/network/networktypes/error.go deleted file mode 100644 index 933573977a..0000000000 --- a/ignite/services/network/networktypes/error.go +++ /dev/null @@ -1,22 +0,0 @@ -package networktypes - -import ( - "fmt" - - "github.com/pkg/errors" -) - -// ErrInvalidRequest is an error returned in methods manipulating requests when they are invalid. -type ErrInvalidRequest struct { - requestID uint64 -} - -// Error implements error. -func (err ErrInvalidRequest) Error() string { - return fmt.Sprintf("request %d is invalid", err.requestID) -} - -// NewWrappedErrInvalidRequest returns a wrapped ErrInvalidRequest. -func NewWrappedErrInvalidRequest(requestID uint64, message string) error { - return errors.Wrap(ErrInvalidRequest{requestID: requestID}, message) -} diff --git a/ignite/services/network/networktypes/genesisinformation.go b/ignite/services/network/networktypes/genesisinformation.go deleted file mode 100644 index e8f7a92584..0000000000 --- a/ignite/services/network/networktypes/genesisinformation.go +++ /dev/null @@ -1,264 +0,0 @@ -package networktypes - -import ( - "github.com/pkg/errors" - - sdk "github.com/cosmos/cosmos-sdk/types" - launchtypes "github.com/tendermint/spn/x/launch/types" -) - -// GenesisInformation represents all information for a chain to construct the genesis. -// This structure indexes accounts and validators by their address for better performance. -type GenesisInformation struct { - // make sure to use slices for the following because slices are ordered. - // they later used to create a Genesis so, having them ordered is important to - // be able to produce a deterministic Genesis. - - GenesisAccounts []GenesisAccount - VestingAccounts []VestingAccount - GenesisValidators []GenesisValidator - ParamChanges []ParamChange -} - -// GenesisAccount represents an account with initial coin allocation for the chain for the chain genesis. -type GenesisAccount struct { - Address string `json:"Address,omitempty"` - Coins sdk.Coins `json:"Coins,omitempty"` -} - -// VestingAccount represents a vesting account with initial coin allocation and vesting option for the chain genesis. -// VestingAccount supports currently only delayed vesting option. -type VestingAccount struct { - Address string `json:"Address,omitempty"` - TotalBalance sdk.Coins `json:"TotalBalance,omitempty"` - Vesting sdk.Coins `json:"Vesting,omitempty"` - EndTime int64 `json:"EndTime,omitempty"` -} - -// GenesisValidator represents a genesis validator associated with a gentx in the chain genesis. -type GenesisValidator struct { - Address string `json:"Address,omitempty"` - Gentx []byte `json:"Gentx,omitempty"` - Peer launchtypes.Peer `json:"Peer,omitempty"` - SelfDelegation sdk.Coin `json:"SelfDelegation,omitempty"` -} - -// ParamChange represents a parameter change to be applied to the chain genesis. -type ParamChange struct { - Module string `json:"Module,omitempty"` - Param string `json:"Param,omitempty"` - Value []byte `json:"Value,omitempty"` -} - -// ToGenesisAccount converts genesis account from SPN. -func ToGenesisAccount(acc launchtypes.GenesisAccount) GenesisAccount { - return GenesisAccount{ - Address: acc.Address, - Coins: acc.Coins, - } -} - -// ToVestingAccount converts vesting account from SPN. -func ToVestingAccount(acc launchtypes.VestingAccount) (VestingAccount, error) { - delayedVesting := acc.VestingOptions.GetDelayedVesting() - if delayedVesting == nil { - return VestingAccount{}, errors.New("only delayed vesting option is supported") - } - - return VestingAccount{ - Address: acc.Address, - TotalBalance: delayedVesting.TotalBalance, - Vesting: delayedVesting.Vesting, - EndTime: delayedVesting.EndTime.Unix(), - }, nil -} - -// ToGenesisValidator converts genesis validator from SPN. -func ToGenesisValidator(val launchtypes.GenesisValidator) GenesisValidator { - return GenesisValidator{ - Address: val.Address, - Gentx: val.GenTx, - Peer: val.Peer, - SelfDelegation: val.SelfDelegation, - } -} - -// ToParamChange converts param change from SPN. -func ToParamChange(pc launchtypes.ParamChange) ParamChange { - return ParamChange{ - Param: pc.Param, - Module: pc.Module, - Value: pc.Value, - } -} - -// NewGenesisInformation initializes new GenesisInformation. -func NewGenesisInformation( - genAccs []GenesisAccount, - vestingAccs []VestingAccount, - genVals []GenesisValidator, - paramChanges []ParamChange, -) (gi GenesisInformation) { - return GenesisInformation{ - GenesisAccounts: genAccs, - VestingAccounts: vestingAccs, - GenesisValidators: genVals, - ParamChanges: paramChanges, - } -} - -// ContainsGenesisAccount returns true if GenesisInformation contains given address. -// Returns index if true, -1 if false. -func (gi GenesisInformation) ContainsGenesisAccount(address string) (bool, int) { - for i, account := range gi.GenesisAccounts { - if account.Address == address { - return true, i - } - } - return false, -1 -} - -// ContainsVestingAccount returns true if GenesisInformation contains given address. -// Returns index if true, -1 if false. -func (gi GenesisInformation) ContainsVestingAccount(address string) (bool, int) { - for i, account := range gi.VestingAccounts { - if account.Address == address { - return true, i - } - } - return false, -1 -} - -// ContainsGenesisValidator returns true if GenesisInformation contains given address. -// Returns index if true, -1 if false. -func (gi GenesisInformation) ContainsGenesisValidator(address string) (bool, int) { - for i, account := range gi.GenesisValidators { - if account.Address == address { - return true, i - } - } - return false, -1 -} - -// ContainsParamChange returns true if GenesisInformation contains given module-param pair. -// Returns index if true, -1 if false. -func (gi GenesisInformation) ContainsParamChange(module, param string) (bool, int) { - for i, paramChange := range gi.ParamChanges { - if paramChange.Module == module && paramChange.Param == param { - return true, i - } - } - return false, -1 -} - -func (gi *GenesisInformation) AddGenesisAccount(acc GenesisAccount) { - gi.GenesisAccounts = append(gi.GenesisAccounts, acc) -} - -func (gi *GenesisInformation) AddVestingAccount(acc VestingAccount) { - gi.VestingAccounts = append(gi.VestingAccounts, acc) -} - -func (gi *GenesisInformation) AddGenesisValidator(val GenesisValidator) { - gi.GenesisValidators = append(gi.GenesisValidators, val) -} - -func (gi *GenesisInformation) RemoveGenesisAccount(address string) { - for i, account := range gi.GenesisAccounts { - if account.Address == address { - gi.GenesisAccounts = append(gi.GenesisAccounts[:i], gi.GenesisAccounts[i+1:]...) - } - } -} - -func (gi *GenesisInformation) RemoveVestingAccount(address string) { - for i, account := range gi.VestingAccounts { - if account.Address == address { - gi.VestingAccounts = append(gi.VestingAccounts[:i], gi.VestingAccounts[i+1:]...) - } - } -} - -func (gi *GenesisInformation) RemoveGenesisValidator(address string) { - for i, account := range gi.GenesisValidators { - if account.Address == address { - gi.GenesisValidators = append(gi.GenesisValidators[:i], gi.GenesisValidators[i+1:]...) - } - } -} - -// AddParamChange adds a ParamChange to the GenesisInformation. -// Appends if entry does not exist. Updates if it already exists. -func (gi *GenesisInformation) AddParamChange(pc ParamChange) { - contains, index := gi.ContainsParamChange(pc.Module, pc.Param) - if contains { - gi.ParamChanges[index] = pc - return - } - gi.ParamChanges = append(gi.ParamChanges, pc) -} - -// ApplyRequest applies to the genesisInformation the changes implied by the approval of a request. -func (gi GenesisInformation) ApplyRequest(request Request) (GenesisInformation, error) { - switch requestContent := request.Content.Content.(type) { - case *launchtypes.RequestContent_GenesisAccount: - // new genesis account in the genesis - ga := ToGenesisAccount(*requestContent.GenesisAccount) - genExist, _ := gi.ContainsGenesisAccount(ga.Address) - vestingExist, _ := gi.ContainsVestingAccount(ga.Address) - if genExist || vestingExist { - return gi, NewWrappedErrInvalidRequest(request.RequestID, "genesis account already in genesis") - } - gi.AddGenesisAccount(ga) - - case *launchtypes.RequestContent_VestingAccount: - // new vesting account in the genesis - va, err := ToVestingAccount(*requestContent.VestingAccount) - if err != nil { - // we don't treat this error as errInvalidRequests - // because it can occur if we don't support this format of vesting account - // but the request is still correct - return gi, err - } - - genExist, _ := gi.ContainsGenesisAccount(va.Address) - vestingExist, _ := gi.ContainsVestingAccount(va.Address) - if genExist || vestingExist { - return gi, NewWrappedErrInvalidRequest(request.RequestID, "vesting account already in genesis") - } - gi.AddVestingAccount(va) - - case *launchtypes.RequestContent_AccountRemoval: - // account removed from the genesis - ar := requestContent.AccountRemoval - genExist, _ := gi.ContainsGenesisAccount(ar.Address) - vestingExist, _ := gi.ContainsVestingAccount(ar.Address) - if !genExist && !vestingExist { - return gi, NewWrappedErrInvalidRequest(request.RequestID, "account can't be removed because it doesn't exist") - } - gi.RemoveGenesisAccount(ar.Address) - gi.RemoveVestingAccount(ar.Address) - - case *launchtypes.RequestContent_GenesisValidator: - // new genesis validator in the genesis - gv := ToGenesisValidator(*requestContent.GenesisValidator) - if contains, _ := gi.ContainsGenesisValidator(gv.Address); contains { - return gi, NewWrappedErrInvalidRequest(request.RequestID, "genesis validator already in genesis") - } - gi.AddGenesisValidator(gv) - - case *launchtypes.RequestContent_ValidatorRemoval: - // validator removed from the genesis - vr := requestContent.ValidatorRemoval - if contains, _ := gi.ContainsGenesisValidator(vr.ValAddress); !contains { - return gi, NewWrappedErrInvalidRequest(request.RequestID, "genesis validator can't be removed because it doesn't exist") - } - - case *launchtypes.RequestContent_ParamChange: - // param changed in genesis file - pc := ToParamChange(*requestContent.ParamChange) - gi.AddParamChange(pc) - } - - return gi, nil -} diff --git a/ignite/services/network/networktypes/genesisinformation_test.go b/ignite/services/network/networktypes/genesisinformation_test.go deleted file mode 100644 index 5223b13058..0000000000 --- a/ignite/services/network/networktypes/genesisinformation_test.go +++ /dev/null @@ -1,392 +0,0 @@ -package networktypes_test - -import ( - "testing" - "time" - - sdkmath "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - launchtypes "github.com/tendermint/spn/x/launch/types" - - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -var sampleCoins = sdk.NewCoins(sdk.NewCoin("bar", sdkmath.NewInt(1000)), sdk.NewCoin("foo", sdkmath.NewInt(2000))) - -func TestToGenesisAccount(t *testing.T) { - tests := []struct { - name string - fetched launchtypes.GenesisAccount - expected networktypes.GenesisAccount - }{ - { - name: "genesis account", - fetched: launchtypes.GenesisAccount{ - Address: "spn123", - Coins: sampleCoins, - }, - expected: networktypes.GenesisAccount{ - Address: "spn123", - Coins: sampleCoins, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require.EqualValues(t, tt.expected, networktypes.ToGenesisAccount(tt.fetched)) - }) - } -} - -func TestToVestingAccount(t *testing.T) { - tests := []struct { - name string - fetched launchtypes.VestingAccount - expected networktypes.VestingAccount - isError bool - }{ - { - name: "vesting account", - fetched: launchtypes.VestingAccount{ - Address: "spn123", - VestingOptions: *launchtypes.NewDelayedVesting( - sampleCoins, - sampleCoins, - time.Unix(0, 0), - ), - }, - expected: networktypes.VestingAccount{ - Address: "spn123", - TotalBalance: sampleCoins, - Vesting: sampleCoins, - EndTime: time.Unix(0, 0).Unix(), - }, - }, - { - name: "unrecognized vesting option", - fetched: launchtypes.VestingAccount{ - Address: "spn123", - VestingOptions: launchtypes.VestingOptions{ - Options: nil, - }, - }, - isError: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - vestingAcc, err := networktypes.ToVestingAccount(tt.fetched) - require.EqualValues(t, tt.isError, err != nil) - require.EqualValues(t, tt.expected, vestingAcc) - }) - } -} - -func TestToGenesisValidator(t *testing.T) { - tests := []struct { - name string - fetched launchtypes.GenesisValidator - expected networktypes.GenesisValidator - }{ - { - name: "genesis validator", - fetched: launchtypes.GenesisValidator{ - GenTx: []byte("abc"), - Peer: launchtypes.NewPeerConn("abc", "abc@0.0.0.0"), - }, - expected: networktypes.GenesisValidator{ - Gentx: []byte("abc"), - Peer: launchtypes.NewPeerConn("abc", "abc@0.0.0.0"), - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require.EqualValues(t, tt.expected, networktypes.ToGenesisValidator(tt.fetched)) - }) - } -} - -func TestToParamChange(t *testing.T) { - tests := []struct { - name string - fetched launchtypes.ParamChange - expected networktypes.ParamChange - }{ - { - name: "param change", - fetched: launchtypes.ParamChange{ - LaunchID: 0, - Module: "foo", - Param: "bar", - Value: []byte("value"), - }, - expected: networktypes.ParamChange{ - Module: "foo", - Param: "bar", - Value: []byte("value"), - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require.EqualValues(t, tt.expected, networktypes.ToParamChange(tt.fetched)) - }) - } -} - -func TestGenesisInformation_ApplyRequest(t *testing.T) { - newCoin := func(str string) sdk.Coin { - c, err := sdk.ParseCoinNormalized(str) - require.NoError(t, err) - return c - } - newCoins := func(str string) sdk.Coins { - c, err := sdk.ParseCoinsNormalized(str) - require.NoError(t, err) - return c - } - - // used as a template for tests - genesisInformation := networktypes.NewGenesisInformation( - []networktypes.GenesisAccount{ - { - Address: "spn1g50xher44l9hjuatjdfxgv254jh2wgzfs55yu3", - Coins: sdk.NewCoins(sdk.NewCoin("foo", sdkmath.NewInt(1000))), - }, - }, - []networktypes.VestingAccount{ - { - Address: "spn1gkzf4e0x6wr4djfd8h82v6cy507gy5v4spaus3", - TotalBalance: sdk.NewCoins(sdk.NewCoin("foo", sdkmath.NewInt(1000))), - Vesting: sdk.NewCoins(sdk.NewCoin("foo", sdkmath.NewInt(500))), - EndTime: time.Now().Unix(), - }, - }, - []networktypes.GenesisValidator{ - { - Address: "spn1pquxnnpnjyl3ptz3uxs0lrs93s5ljepzq4wyp6", - Gentx: []byte("aaa"), - Peer: launchtypes.NewPeerConn("foo", "foo"), - }, - }, - []networktypes.ParamChange{ - { - Module: "mint", - Param: "mint_denom", - Value: []byte("\"bar\""), - }, - }, - ) - - tests := []struct { - name string - gi networktypes.GenesisInformation - r networktypes.Request - invalidRequest bool - }{ - { - name: "genesis account request", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewGenesisAccount( - 0, - "spn1sgphx4vxt63xhvgp9wpewajyxeqt04twfj7gcc", - newCoins("1000bar"), - ), - }, - }, - { - name: "vesting account request", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewVestingAccount( - 0, - "spn19klee4szqpeu0laqze5srhdxtp6fuhcztdrh7c", - *launchtypes.NewDelayedVesting( - newCoins("1000bar"), - newCoins("500bar"), - time.Now(), - ), - ), - }, - }, - { - name: "genesis validator request", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewGenesisValidator( - 0, - "spn1xnn9w76mf42t249486ss65lvga7gqs02erpw24", - []byte("bbb"), - []byte("ccc"), - newCoin("1000bar"), - launchtypes.NewPeerConn("bar", "bar"), - ), - }, - }, - { - name: "genesis account: existing genesis account", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewGenesisAccount( - 0, - "spn1g50xher44l9hjuatjdfxgv254jh2wgzfs55yu3", - newCoins("1000bar"), - ), - }, - invalidRequest: true, - }, - { - name: "genesis account: existing vesting account", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewGenesisAccount( - 0, - "spn1gkzf4e0x6wr4djfd8h82v6cy507gy5v4spaus3", - newCoins("1000bar"), - ), - }, - invalidRequest: true, - }, - { - name: "vesting account: existing genesis account", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewVestingAccount( - 0, - "spn1g50xher44l9hjuatjdfxgv254jh2wgzfs55yu3", - *launchtypes.NewDelayedVesting( - newCoins("1000bar"), - newCoins("500bar"), - time.Now(), - ), - ), - }, - invalidRequest: true, - }, - { - name: "vesting account: existing vesting account", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewVestingAccount( - 0, - "spn1gkzf4e0x6wr4djfd8h82v6cy507gy5v4spaus3", - *launchtypes.NewDelayedVesting( - newCoins("1000bar"), - newCoins("500bar"), - time.Now(), - ), - ), - }, - invalidRequest: true, - }, - { - name: "existing genesis validator", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewGenesisValidator( - 0, - "spn1pquxnnpnjyl3ptz3uxs0lrs93s5ljepzq4wyp6", - []byte("bbb"), - []byte("ccc"), - newCoin("1000bar"), - launchtypes.NewPeerConn("bar", "bar"), - ), - }, - invalidRequest: true, - }, - { - name: "remove genesis account", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewAccountRemoval("spn1g50xher44l9hjuatjdfxgv254jh2wgzfs55yu3"), - }, - }, - { - name: "remove vesting account", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewAccountRemoval("spn1gkzf4e0x6wr4djfd8h82v6cy507gy5v4spaus3"), - }, - }, - { - name: "remove genesis validator", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewValidatorRemoval("spn1pquxnnpnjyl3ptz3uxs0lrs93s5ljepzq4wyp6"), - }, - }, - { - name: "remove account: non-existent account", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewAccountRemoval("spn1pquxnnpnjyl3ptz3uxs0lrs93s5ljepzq4wyp6"), - }, - invalidRequest: true, - }, - { - name: "remove account: non-existent genesis validator", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewValidatorRemoval("spn1g50xher44l9hjuatjdfxgv254jh2wgzfs55yu3"), - }, - invalidRequest: true, - }, - { - name: "change param", - gi: genesisInformation, - r: networktypes.Request{ - Content: launchtypes.NewParamChange(0, "mint", "mint_denom", []byte("\"foo\"")), - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - newGi, err := tt.gi.ApplyRequest(tt.r) - if tt.invalidRequest { - require.ErrorAs(t, err, &networktypes.ErrInvalidRequest{}) - return - } - - // parse difference following request - switch rc := tt.r.Content.Content.(type) { - case *launchtypes.RequestContent_GenesisAccount: - ga := networktypes.ToGenesisAccount(*rc.GenesisAccount) - contains, index := newGi.ContainsGenesisAccount(ga.Address) - require.True(t, contains) - require.EqualValues(t, ga, newGi.GenesisAccounts[index]) - - case *launchtypes.RequestContent_VestingAccount: - va, err := networktypes.ToVestingAccount(*rc.VestingAccount) - require.NoError(t, err) - contains, index := newGi.ContainsVestingAccount(va.Address) - require.True(t, contains) - require.EqualValues(t, va, newGi.VestingAccounts[index]) - - case *launchtypes.RequestContent_AccountRemoval: - contains, _ := newGi.ContainsGenesisAccount(rc.AccountRemoval.Address) - require.False(t, contains) - contains, _ = newGi.ContainsVestingAccount(rc.AccountRemoval.Address) - require.False(t, contains) - - case *launchtypes.RequestContent_GenesisValidator: - gv := networktypes.ToGenesisValidator(*rc.GenesisValidator) - contains, index := newGi.ContainsGenesisValidator(gv.Address) - require.True(t, contains) - require.EqualValues(t, gv, newGi.GenesisValidators[index]) - - case *launchtypes.RequestContent_ValidatorRemoval: - contains, _ := newGi.ContainsGenesisAccount(rc.ValidatorRemoval.ValAddress) - require.False(t, contains) - - case *launchtypes.RequestContent_ParamChange: - pc := networktypes.ToParamChange(*rc.ParamChange) - contains, index := newGi.ContainsParamChange(pc.Module, pc.Param) - require.True(t, contains) - require.EqualValues(t, pc, newGi.ParamChanges[index]) - } - }) - } -} diff --git a/ignite/services/network/networktypes/networktypes.go b/ignite/services/network/networktypes/networktypes.go deleted file mode 100644 index a74f071afa..0000000000 --- a/ignite/services/network/networktypes/networktypes.go +++ /dev/null @@ -1,21 +0,0 @@ -package networktypes - -const ( - // SPNChainID name used as SPN chain id. - SPNChainID = "spn-1" - - // SPN name used as an address prefix and as a home dir for chains to publish. - SPN = "spn" - - // SPNDenom is the denom used for the spn chain native token. - SPNDenom = "uspn" - - // SPNVersion is the spn ibc version used for the relayer connection. - SPNVersion = "monitoring-1" - - // SPNPortID is the spn ibc port id used for the relayer connection. - SPNPortID = "monitoringc" - - // ChainPortID is the chain ibc port id used for the relayer connection. - ChainPortID = "monitoringp" -) diff --git a/ignite/services/network/networktypes/profile.go b/ignite/services/network/networktypes/profile.go deleted file mode 100644 index b528740bfa..0000000000 --- a/ignite/services/network/networktypes/profile.go +++ /dev/null @@ -1,117 +0,0 @@ -package networktypes - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - campaigntypes "github.com/tendermint/spn/x/campaign/types" - profiletypes "github.com/tendermint/spn/x/profile/types" -) - -// Validator represents the Validator profile on SPN. -type Validator struct { - Address string `json:"Address"` - OperatorAddresses []string `json:"OperatorAddresses"` - Identity string `json:"Identity"` - Website string `json:"Website"` - Details string `json:"Details"` - Moniker string `json:"Moniker"` - SecurityContact string `json:"SecurityContact"` -} - -func (v Validator) ToProfile( - projectID uint64, - vouchers sdk.Coins, - shares campaigntypes.Shares, -) Profile { - return Profile{ - ProjectID: projectID, - Address: v.Address, - Identity: v.Identity, - Website: v.Website, - Details: v.Details, - Moniker: v.Moniker, - SecurityContact: v.SecurityContact, - Vouchers: vouchers, - Shares: shares, - } -} - -// ToValidator converts a Validator data from SPN and returns a Validator object. -func ToValidator(val profiletypes.Validator) Validator { - return Validator{ - Address: val.Address, - OperatorAddresses: val.OperatorAddresses, - Identity: val.Description.Identity, - Website: val.Description.Website, - Details: val.Description.Details, - Moniker: val.Description.Moniker, - SecurityContact: val.Description.SecurityContact, - } -} - -// Coordinator represents the Coordinator profile on SPN. -type Coordinator struct { - CoordinatorID uint64 `json:"ID"` - Address string `json:"Address"` - Active bool `json:"Active"` - Identity string `json:"Identity"` - Website string `json:"Website"` - Details string `json:"Details"` -} - -func (c Coordinator) ToProfile( - projectID uint64, - vouchers sdk.Coins, - shares campaigntypes.Shares, -) Profile { - return Profile{ - ProjectID: projectID, - Address: c.Address, - Identity: c.Identity, - Website: c.Website, - Details: c.Details, - Vouchers: vouchers, - Shares: shares, - } -} - -// ToCoordinator converts a Coordinator data from SPN and returns a Coordinator object. -func ToCoordinator(coord profiletypes.Coordinator) Coordinator { - return Coordinator{ - CoordinatorID: coord.CoordinatorID, - Address: coord.Address, - Active: coord.Active, - Identity: coord.Description.Identity, - Website: coord.Description.Website, - Details: coord.Description.Details, - } -} - -type ( - // ChainShare represents the share of a chain on SPN. - ChainShare struct { - LaunchID uint64 `json:"LaunchID"` - Shares sdk.Coins `json:"Shares"` - } - - // Profile represents the address profile on SPN. - Profile struct { - Address string `json:"Address"` - ProjectID uint64 `json:"ProjectID,omitempty"` - Identity string `json:"Identity,omitempty"` - Website string `json:"Website,omitempty"` - Details string `json:"Details,omitempty"` - Moniker string `json:"Moniker,omitempty"` - SecurityContact string `json:"SecurityContact,omitempty"` - Vouchers sdk.Coins `json:"Vouchers,omitempty"` - Shares campaigntypes.Shares `json:"Shares,omitempty"` - } - - // ProfileAcc represents the address profile method interface. - ProfileAcc interface { - ToProfile( - projectID uint64, - vouchers sdk.Coins, - shares campaigntypes.Shares, - ) Profile - } -) diff --git a/ignite/services/network/networktypes/project.go b/ignite/services/network/networktypes/project.go deleted file mode 100644 index 8dd49c10bb..0000000000 --- a/ignite/services/network/networktypes/project.go +++ /dev/null @@ -1,60 +0,0 @@ -package networktypes - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - campaigntypes "github.com/tendermint/spn/x/campaign/types" -) - -// Project represents the project of a chain on SPN. -type Project struct { - ID uint64 `json:"ID"` - Name string `json:"Name"` - CoordinatorID uint64 `json:"CoordinatorID"` - MainnetID uint64 `json:"MainnetID"` - MainnetInitialized bool `json:"MainnetInitialized"` - TotalSupply sdk.Coins `json:"TotalSupply"` - AllocatedShares string `json:"AllocatedShares"` - Metadata string `json:"Metadata"` -} - -// ToProject converts a project data from SPN and returns a Project object. -func ToProject(campaign campaigntypes.Campaign) Project { - return Project{ - ID: campaign.CampaignID, - Name: campaign.CampaignName, - CoordinatorID: campaign.CoordinatorID, - MainnetID: campaign.MainnetID, - MainnetInitialized: campaign.MainnetInitialized, - TotalSupply: campaign.TotalSupply, - AllocatedShares: campaign.AllocatedShares.String(), - Metadata: string(campaign.Metadata), - } -} - -// MainnetAccount represents the project mainnet account of a chain on SPN. -type MainnetAccount struct { - Address string `json:"Address"` - Shares campaigntypes.Shares `json:"Shares"` -} - -// ToMainnetAccount converts a mainnet account data from SPN and returns a MainnetAccount object. -func ToMainnetAccount(acc campaigntypes.MainnetAccount) MainnetAccount { - return MainnetAccount{ - Address: acc.Address, - Shares: acc.Shares, - } -} - -// ProjectChains represents the chains of a project on SPN. -type ProjectChains struct { - ProjectID uint64 `json:"ProjectID"` - Chains []uint64 `json:"Chains"` -} - -// ToProjectChains converts a project chains data from SPN and returns a ProjectChains object. -func ToProjectChains(c campaigntypes.CampaignChains) ProjectChains { - return ProjectChains{ - ProjectID: c.CampaignID, - Chains: c.Chains, - } -} diff --git a/ignite/services/network/networktypes/request.go b/ignite/services/network/networktypes/request.go deleted file mode 100644 index 15b195c4cf..0000000000 --- a/ignite/services/network/networktypes/request.go +++ /dev/null @@ -1,109 +0,0 @@ -package networktypes - -import ( - "fmt" - - launchtypes "github.com/tendermint/spn/x/launch/types" - "github.com/tendermint/tendermint/crypto/ed25519" - - "github.com/ignite/cli/ignite/pkg/cosmosutil" - "github.com/ignite/cli/ignite/pkg/xtime" -) - -type ( - // Request represents the launch Request of a chain on SPN. - Request struct { - LaunchID uint64 `json:"LaunchID"` - RequestID uint64 `json:"RequestID"` - Creator string `json:"Creator"` - CreatedAt string `json:"CreatedAt"` - Content launchtypes.RequestContent `json:"Content"` - Status string `json:"Status"` - } -) - -// ToRequest converts a request data from SPN and returns a Request object. -func ToRequest(request launchtypes.Request) Request { - return Request{ - LaunchID: request.LaunchID, - RequestID: request.RequestID, - Creator: request.Creator, - CreatedAt: xtime.FormatUnixInt(request.CreatedAt), - Content: request.Content, - Status: launchtypes.Request_Status_name[int32(request.Status)], - } -} - -// VerifyRequest verifies the validity of the request from its content (static check). -func VerifyRequest(request Request) error { - req, ok := request.Content.Content.(*launchtypes.RequestContent_GenesisValidator) - if ok { - err := VerifyAddValidatorRequest(req) - if err != nil { - return NewWrappedErrInvalidRequest(request.RequestID, err.Error()) - } - } - - return nil -} - -// VerifyAddValidatorRequest verifies the validator request parameters. -func VerifyAddValidatorRequest(req *launchtypes.RequestContent_GenesisValidator) error { - // If this is an add validator request - var ( - peer = req.GenesisValidator.Peer - valAddress = req.GenesisValidator.Address - consPubKey = req.GenesisValidator.ConsPubKey - selfDelegation = req.GenesisValidator.SelfDelegation - ) - - // Check values inside the gentx are correct - info, err := cosmosutil.ParseGentx(req.GenesisValidator.GenTx) - if err != nil { - return fmt.Errorf("cannot parse gentx %w", err) - } - - // Change the address prefix fetched from the gentx to the one used on SPN - // Because all on-chain stored address on SPN uses the SPN prefix - spnFetchedAddress, err := cosmosutil.ChangeAddressPrefix(info.DelegatorAddress, SPN) - if err != nil { - return err - } - - // Check validator address - if valAddress != spnFetchedAddress { - return fmt.Errorf( - "the validator address %s doesn't match the one inside the gentx %s", - valAddress, - spnFetchedAddress, - ) - } - - // Check validator address - if !info.PubKey.Equals(ed25519.PubKey(consPubKey)) { - return fmt.Errorf( - "the consensus pub key %s doesn't match the one inside the gentx %s", - ed25519.PubKey(consPubKey).String(), - info.PubKey.String(), - ) - } - - // Check self delegation - if selfDelegation.Denom != info.SelfDelegation.Denom || - !selfDelegation.IsEqual(info.SelfDelegation) { - return fmt.Errorf( - "the self delegation %s doesn't match the one inside the gentx %s", - selfDelegation.String(), - info.SelfDelegation.String(), - ) - } - - // Check the format of the peer - if !cosmosutil.VerifyPeerFormat(peer) { - return fmt.Errorf( - "the peer address %s doesn't match the peer format :", - peer.String(), - ) - } - return nil -} diff --git a/ignite/services/network/networktypes/request_test.go b/ignite/services/network/networktypes/request_test.go deleted file mode 100644 index e8cc6b639c..0000000000 --- a/ignite/services/network/networktypes/request_test.go +++ /dev/null @@ -1,146 +0,0 @@ -package networktypes_test - -import ( - "encoding/base64" - "fmt" - "testing" - - sdkmath "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - launchtypes "github.com/tendermint/spn/x/launch/types" - "github.com/tendermint/tendermint/crypto/ed25519" - - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -func TestVerifyAddValidatorRequest(t *testing.T) { - gentx := []byte(`{ - "body": { - "messages": [ - { - "delegator_address": "cosmos1dd246yq6z5vzjz9gh8cff46pll75yyl8ygndsj", - "pubkey": { - "@type": "/cosmos.crypto.ed25519.PubKey", - "key": "aeQLCJOjXUyB7evOodI4mbrshIt3vhHGlycJDbUkaMs=" - }, - "validator_address": "cosmosvaloper1dd246yq6z5vzjz9gh8cff46pll75yyl8pu8cup", - "value": { - "amount": "95000000", - "denom": "stake" - } - } - ] - } -}`) - pk, err := base64.StdEncoding.DecodeString("aeQLCJOjXUyB7evOodI4mbrshIt3vhHGlycJDbUkaMs=") - require.NoError(t, err) - - tests := []struct { - name string - req *launchtypes.RequestContent_GenesisValidator - want error - }{ - { - name: "valid genesis validator request", - req: &launchtypes.RequestContent_GenesisValidator{ - GenesisValidator: &launchtypes.GenesisValidator{ - Address: "spn1dd246yq6z5vzjz9gh8cff46pll75yyl8c5tt7g", - GenTx: gentx, - ConsPubKey: ed25519.PubKey(pk), - SelfDelegation: sdk.NewCoin("stake", sdkmath.NewInt(95000000)), - Peer: launchtypes.NewPeerConn("nodeid", "127.163.0.1:2446"), - }, - }, - }, - { - name: "invalid peer host", - req: &launchtypes.RequestContent_GenesisValidator{ - GenesisValidator: &launchtypes.GenesisValidator{ - Address: "spn1dd246yq6z5vzjz9gh8cff46pll75yyl8c5tt7g", - GenTx: gentx, - ConsPubKey: ed25519.PubKey(pk), - SelfDelegation: sdk.NewCoin("stake", sdkmath.NewInt(95000000)), - Peer: launchtypes.NewPeerConn("nodeid", "122.114.800.11"), - }, - }, - want: fmt.Errorf("the peer address id:\"nodeid\" tcpAddress:\"122.114.800.11\" doesn't match the peer format :"), - }, - { - name: "invalid gentx", - req: &launchtypes.RequestContent_GenesisValidator{ - GenesisValidator: &launchtypes.GenesisValidator{ - Address: "spn1dd246yq6z5vzjz9gh8cff46pll75yyl8c5tt7g", - GenTx: []byte(`{}`), - ConsPubKey: ed25519.PubKey(pk), - SelfDelegation: sdk.NewCoin("stake", sdkmath.NewInt(95000000)), - Peer: launchtypes.NewPeerConn("nodeid", "127.163.0.1:2446"), - }, - }, - want: fmt.Errorf("cannot parse gentx the gentx cannot be parsed"), - }, - { - name: "invalid self delegation denom", - req: &launchtypes.RequestContent_GenesisValidator{ - GenesisValidator: &launchtypes.GenesisValidator{ - Address: "spn1dd246yq6z5vzjz9gh8cff46pll75yyl8c5tt7g", - GenTx: gentx, - ConsPubKey: ed25519.PubKey(pk), - SelfDelegation: sdk.NewCoin("foo", sdkmath.NewInt(95000000)), - Peer: launchtypes.NewPeerConn("nodeid", "127.163.0.1:2446"), - }, - }, - want: fmt.Errorf("the self delegation 95000000foo doesn't match the one inside the gentx 95000000stake"), - }, - { - name: "invalid self delegation value", - req: &launchtypes.RequestContent_GenesisValidator{ - GenesisValidator: &launchtypes.GenesisValidator{ - Address: "spn1dd246yq6z5vzjz9gh8cff46pll75yyl8c5tt7g", - GenTx: gentx, - ConsPubKey: ed25519.PubKey(pk), - SelfDelegation: sdk.NewCoin("stake", sdkmath.NewInt(3)), - Peer: launchtypes.NewPeerConn("nodeid", "127.163.0.1:2446"), - }, - }, - want: fmt.Errorf("the self delegation 3stake doesn't match the one inside the gentx 95000000stake"), - }, - { - name: "invalid consensus pub key", - req: &launchtypes.RequestContent_GenesisValidator{ - GenesisValidator: &launchtypes.GenesisValidator{ - Address: "spn1dd246yq6z5vzjz9gh8cff46pll75yyl8c5tt7g", - GenTx: gentx, - ConsPubKey: ed25519.PubKey("cosmos1gkheudhhjsvq0s8fxt7p6pwe0k3k30kepcnz9p="), - SelfDelegation: sdk.NewCoin("stake", sdkmath.NewInt(95000000)), - Peer: launchtypes.NewPeerConn("nodeid", "127.163.0.1:2446"), - }, - }, - want: fmt.Errorf("the consensus pub key PubKeyEd25519{636F736D6F7331676B6865756468686A737671307338667874377036707765306B336B33306B6570636E7A39703D} doesn't match the one inside the gentx PubKeyEd25519{69E40B0893A35D4C81EDEBCEA1D23899BAEC848B77BE11C69727090DB52468CB}"), - }, - { - name: "invalid validator address", - req: &launchtypes.RequestContent_GenesisValidator{ - GenesisValidator: &launchtypes.GenesisValidator{ - Address: "spn1gkheudhhjsvq0s8fxt7p6pwe0k3k30keaytytm", - GenTx: gentx, - ConsPubKey: ed25519.PubKey(pk), - SelfDelegation: sdk.NewCoin("stake", sdkmath.NewInt(95000000)), - Peer: launchtypes.NewPeerConn("nodeid", "127.163.0.1:2446"), - }, - }, - want: fmt.Errorf("the validator address spn1gkheudhhjsvq0s8fxt7p6pwe0k3k30keaytytm doesn't match the one inside the gentx spn1dd246yq6z5vzjz9gh8cff46pll75yyl8c5tt7g"), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := networktypes.VerifyAddValidatorRequest(tt.req) - if tt.want != nil { - require.Error(t, err) - require.Equal(t, tt.want.Error(), err.Error()) - return - } - require.NoError(t, err) - }) - } -} diff --git a/ignite/services/network/networktypes/reward.go b/ignite/services/network/networktypes/reward.go deleted file mode 100644 index f7b8cfba6c..0000000000 --- a/ignite/services/network/networktypes/reward.go +++ /dev/null @@ -1,22 +0,0 @@ -package networktypes - -import ( - spntypes "github.com/tendermint/spn/pkg/types" -) - -type ( - // Reward is node reward info. - Reward struct { - ConsensusState spntypes.ConsensusState - ValidatorSet spntypes.ValidatorSet - RevisionHeight uint64 - } - - // RewardIBCInfo holds IBC info to relay packets to claim rewards. - RewardIBCInfo struct { - ChainID string - ClientID string - ConnectionID string - ChannelID string - } -) diff --git a/ignite/services/network/node.go b/ignite/services/network/node.go deleted file mode 100644 index aabf467dd5..0000000000 --- a/ignite/services/network/node.go +++ /dev/null @@ -1,192 +0,0 @@ -package network - -import ( - "context" - "encoding/base64" - "errors" - - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ibcclienttypes "github.com/cosmos/ibc-go/v5/modules/core/02-client/types" - ibcconntypes "github.com/cosmos/ibc-go/v5/modules/core/03-connection/types" - ibcchanneltypes "github.com/cosmos/ibc-go/v5/modules/core/04-channel/types" - spntypes "github.com/tendermint/spn/pkg/types" - monitoringptypes "github.com/tendermint/spn/x/monitoringp/types" - - "github.com/ignite/cli/ignite/pkg/cosmoserror" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// Node is node builder. -type Node struct { - cosmos CosmosClient - stakingQuery stakingtypes.QueryClient - ibcClientQuery ibcclienttypes.QueryClient - ibcConnQuery ibcconntypes.QueryClient - ibcChannelQuery ibcchanneltypes.QueryClient - monitoringProviderQuery monitoringptypes.QueryClient -} - -// NewNode creates a new client for node API. -func NewNode(cosmos CosmosClient) Node { - return Node{ - cosmos: cosmos, - stakingQuery: stakingtypes.NewQueryClient(cosmos.Context()), - ibcClientQuery: ibcclienttypes.NewQueryClient(cosmos.Context()), - ibcConnQuery: ibcconntypes.NewQueryClient(cosmos.Context()), - ibcChannelQuery: ibcchanneltypes.NewQueryClient(cosmos.Context()), - monitoringProviderQuery: monitoringptypes.NewQueryClient(cosmos.Context()), - } -} - -// RewardsInfo Fetches the consensus state with the validator set and the unbounding time. -func (n Node) RewardsInfo(ctx context.Context) ( - reward networktypes.Reward, - chainID string, - unbondingTimeSeconds int64, - err error, -) { - status, err := n.cosmos.Status(ctx) - if err != nil { - return networktypes.Reward{}, "", 0, err - } - lastBlockHeight := status.SyncInfo.LatestBlockHeight - - info, err := n.consensus(ctx, n.cosmos, lastBlockHeight) - if err != nil { - return networktypes.Reward{}, "", 0, err - } - - stakingParams, err := n.stakingParams(ctx) - if err != nil { - return networktypes.Reward{}, "", 0, err - } - - return info, - status.NodeInfo.Network, - int64(stakingParams.UnbondingTime.Seconds()), - nil -} - -// RewardIBCInfo returns IBC info to relay packets to claim rewards for the chain. -func (n Node) RewardIBCInfo(ctx context.Context) (networktypes.RewardIBCInfo, error) { - clientID, err := n.consumerClientID(ctx) - if err != nil && !errors.Is(err, ErrObjectNotFound) { - return networktypes.RewardIBCInfo{}, err - } - - channelID, err := n.connectionChannelID(ctx) - if err != nil && !errors.Is(err, ErrObjectNotFound) { - return networktypes.RewardIBCInfo{}, err - } - - connections, err := n.clientConnections(ctx, clientID) - if err != nil && !errors.Is(err, ErrObjectNotFound) { - return networktypes.RewardIBCInfo{}, err - } - - info := networktypes.RewardIBCInfo{ - ClientID: clientID, - ChannelID: channelID, - } - - if len(connections) > 0 { - info.ConnectionID = connections[0] - } - - return info, nil -} - -// consensus Fetches the consensus state with the validator set. -func (n Node) consensus(ctx context.Context, client CosmosClient, height int64) (networktypes.Reward, error) { - consensusState, err := client.ConsensusInfo(ctx, height) - if err != nil { - return networktypes.Reward{}, err - } - - spnConsensusState := spntypes.NewConsensusState( - consensusState.Timestamp, - consensusState.NextValidatorsHash, - consensusState.Root, - ) - - validators := make([]spntypes.Validator, len(consensusState.ValidatorSet.Validators)) - for i, validator := range consensusState.ValidatorSet.Validators { - validators[i] = spntypes.NewValidator( - base64.StdEncoding.EncodeToString(validator.PubKey.GetEd25519()), - validator.ProposerPriority, - validator.VotingPower, - ) - } - - reward := networktypes.Reward{ - ConsensusState: spnConsensusState, - ValidatorSet: spntypes.NewValidatorSet(validators...), - RevisionHeight: uint64(height), - } - - return reward, nil -} - -// connectionChannels fetches the chain connection channels by connection id. -func (n Node) connectionChannels(ctx context.Context, connectionID string) (channels []string, err error) { - res, err := n.ibcChannelQuery.ConnectionChannels(ctx, &ibcchanneltypes.QueryConnectionChannelsRequest{ - Connection: connectionID, - }) - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return channels, nil - } else if err != nil { - return nil, err - } - for _, channel := range res.Channels { - channels = append(channels, channel.ChannelId) - } - return -} - -// clientConnections fetches the chain client connections by client id. -func (n Node) clientConnections(ctx context.Context, clientID string) ([]string, error) { - res, err := n.ibcConnQuery.ClientConnections(ctx, &ibcconntypes.QueryClientConnectionsRequest{ - ClientId: clientID, - }) - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return []string{}, nil - } else if err != nil { - return nil, err - } - return res.ConnectionPaths, err -} - -// stakingParams fetches the staking module params. -func (n Node) stakingParams(ctx context.Context) (stakingtypes.Params, error) { - res, err := n.stakingQuery.Params(ctx, &stakingtypes.QueryParamsRequest{}) - if err != nil { - return stakingtypes.Params{}, err - } - return res.Params, nil -} - -// consumerClientID fetches the consumer client id from the monitoring provider. -func (n Node) consumerClientID(ctx context.Context) (string, error) { - res, err := n.monitoringProviderQuery.ConsumerClientID( - ctx, &monitoringptypes.QueryGetConsumerClientIDRequest{}, - ) - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return "", ErrObjectNotFound - } else if err != nil { - return "", err - } - return res.ConsumerClientID.ClientID, nil -} - -// connectionChannelID fetches the consumer connection chnnael id from the monitoring provider. -func (n Node) connectionChannelID(ctx context.Context) (string, error) { - res, err := n.monitoringProviderQuery.ConnectionChannelID( - ctx, &monitoringptypes.QueryGetConnectionChannelIDRequest{}, - ) - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return "", ErrObjectNotFound - } else if err != nil { - return "", err - } - return res.ConnectionChannelID.ChannelID, nil -} diff --git a/ignite/services/network/peer.go b/ignite/services/network/peer.go deleted file mode 100644 index 166b092423..0000000000 --- a/ignite/services/network/peer.go +++ /dev/null @@ -1,101 +0,0 @@ -package network - -import ( - "context" - "fmt" - "path/filepath" - "strings" - "time" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/server" - "github.com/pkg/errors" - launchtypes "github.com/tendermint/spn/x/launch/types" - - "github.com/ignite/cli/ignite/pkg/cosmosutil" - "github.com/ignite/cli/ignite/pkg/ctxticker" - "github.com/ignite/cli/ignite/pkg/gitpod" - "github.com/ignite/cli/ignite/pkg/xchisel" - "github.com/ignite/cli/ignite/services/network/networkchain" -) - -func PeerAddress(peer launchtypes.Peer) (string, error) { - var peerAddr string - switch conn := peer.Connection.(type) { - case *launchtypes.Peer_TcpAddress: - peerAddr = fmt.Sprintf("%s@%s", peer.Id, conn.TcpAddress) - case *launchtypes.Peer_HttpTunnel: - peerAddr = fmt.Sprintf("%s@%s", peer.Id, conn.HttpTunnel.Address) - default: - return peerAddr, fmt.Errorf("invalid peer connection type: %T", peer.Connection) - } - return peerAddr, nil -} - -func ParsePeerAddress(addr string) (launchtypes.Peer, error) { - sp := strings.Split(addr, "@") - if len(sp) != 2 { - return launchtypes.Peer{}, errors.New("invalid peer address format") - } - return launchtypes.NewPeerConn(sp[0], sp[1]), nil -} - -const TunnelRerunDelay = 5 * time.Second - -// StartProxyForTunneledPeers starts an HTTP proxy server and HTTP proxy clients -// for each node that needs HTTP tunneling. -// HTTP tunneling is activated **ONLY** if your app's `$APP_HOME/config` dir has an `spn.yml` file -// and only if this file has `tunneled_peers` field inside with a list of tunneled peers/nodes. -// -// If you're using SPN as coordinator and do not want to allow HTTP tunneling feature at all, -// you can prevent `spn.yml` file to being generated by not approving validator requests -// that has HTTP tunneling enabled instead of plain TCP connections. -func StartProxyForTunneledPeers(ctx context.Context, clientCtx client.Context, serverCtx *server.Context) { - spnConfigPath := filepath.Join(clientCtx.HomeDir, cosmosutil.ChainConfigDir, networkchain.SPNConfigFile) - spnConfig, err := networkchain.GetSPNConfig(spnConfigPath) - if err != nil { - serverCtx.Logger.Error("Failed to open spn config file", "reason", err.Error()) - return - } - // exit if there aren't tunneled validators in the network - if len(spnConfig.TunneledPeers) == 0 { - return - } - - for _, peer := range spnConfig.TunneledPeers { - if peer.Name == networkchain.HTTPTunnelChisel { - peer := peer - go func() { - ctxticker.DoNow(ctx, TunnelRerunDelay, func() error { - serverCtx.Logger.Info("Starting chisel client", "tunnelAddress", peer.Address, "localPort", peer.LocalPort) - err := xchisel.StartClient(ctx, peer.Address, peer.LocalPort, "26656") - if err != nil { - serverCtx.Logger.Error("Failed to start chisel client", - "tunnelAddress", peer.Address, - "localPort", peer.LocalPort, - "reason", err.Error(), - ) - } - return nil - }) - }() - } - } - - if gitpod.IsOnGitpod() { - go func() { - ctxticker.DoNow(ctx, TunnelRerunDelay, func() error { - serverCtx.Logger.Info("Starting chisel server", "port", xchisel.DefaultServerPort) - err := xchisel.StartServer(ctx, xchisel.DefaultServerPort) - if err != nil { - serverCtx.Logger.Error( - "Failed to start chisel server", - "port", xchisel.DefaultServerPort, - "reason", err.Error(), - ) - } - return nil - }) - }() - } -} diff --git a/ignite/services/network/peer_test.go b/ignite/services/network/peer_test.go deleted file mode 100644 index 9ee0e19c97..0000000000 --- a/ignite/services/network/peer_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package network - -import ( - "errors" - "testing" - - "github.com/stretchr/testify/require" - launchtypes "github.com/tendermint/spn/x/launch/types" -) - -func TestPeerAddress(t *testing.T) { - tests := []struct { - name string - peer launchtypes.Peer - want string - err error - }{ - { - name: "simple peer connection", - peer: launchtypes.NewPeerConn("simple-conn", "200.100.50.20"), - want: "simple-conn@200.100.50.20", - }, - { - name: "http tunnel peer", - peer: launchtypes.NewPeerTunnel("httpTunnel", "tunnel", "200.100.50.20"), - want: "httpTunnel@200.100.50.20", - }, - { - name: "invalid peer", - peer: launchtypes.Peer{Id: "invalid-peer", Connection: nil}, - err: errors.New("invalid peer connection type: "), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := PeerAddress(tt.peer) - if tt.err != nil { - require.Error(t, err) - require.Equal(t, tt.err.Error(), err.Error()) - return - } - require.NoError(t, err) - require.Equal(t, tt.want, got) - }) - } -} diff --git a/ignite/services/network/profile.go b/ignite/services/network/profile.go deleted file mode 100644 index 7fb139650c..0000000000 --- a/ignite/services/network/profile.go +++ /dev/null @@ -1,206 +0,0 @@ -package network - -import ( - "context" - "errors" - - sdk "github.com/cosmos/cosmos-sdk/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - campaigntypes "github.com/tendermint/spn/x/campaign/types" - profiletypes "github.com/tendermint/spn/x/profile/types" - - "github.com/ignite/cli/ignite/pkg/cosmoserror" - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// CoordinatorIDByAddress returns the CoordinatorByAddress from SPN. -func (n Network) CoordinatorIDByAddress(ctx context.Context, address string) (uint64, error) { - n.ev.Send("Fetching coordinator by address", events.ProgressStart()) - resCoordByAddr, err := n.profileQuery. - CoordinatorByAddress(ctx, - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: address, - }, - ) - - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return 0, ErrObjectNotFound - } else if err != nil { - return 0, err - } - return resCoordByAddr.CoordinatorByAddress.CoordinatorID, nil -} - -// SetCoordinatorDescription set the description of a coordinator -// or creates the coordinator if it doesn't exist yet for the sender address. -func (n Network) SetCoordinatorDescription(ctx context.Context, description profiletypes.CoordinatorDescription) error { - n.ev.Send("Setting coordinator description", events.ProgressStart()) - - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - // check if coordinator exists - _, err = n.CoordinatorIDByAddress(ctx, addr) - if errors.Is(err, ErrObjectNotFound) { - // create a new coordinator - msgCreateCoordinator := profiletypes.NewMsgCreateCoordinator( - addr, - description.Identity, - description.Website, - description.Details, - ) - res, err := n.cosmos.BroadcastTx(ctx, n.account, msgCreateCoordinator) - if err != nil { - return err - } - var requestRes profiletypes.MsgCreateCoordinatorResponse - return res.Decode(&requestRes) - } else if err == nil { - // update the description for the coordinator - msgUpdateCoordinatorDescription := profiletypes.NewMsgUpdateCoordinatorDescription( - addr, - description.Identity, - description.Website, - description.Details, - ) - res, err := n.cosmos.BroadcastTx(ctx, n.account, msgUpdateCoordinatorDescription) - if err != nil { - return err - } - var requestRes profiletypes.MsgUpdateCoordinatorDescriptionResponse - return res.Decode(&requestRes) - } - return err -} - -// Coordinator returns the Coordinator by address from SPN. -func (n Network) Coordinator(ctx context.Context, address string) (networktypes.Coordinator, error) { - n.ev.Send("Fetching coordinator details", events.ProgressStart()) - coordinatorID, err := n.CoordinatorIDByAddress(ctx, address) - if err != nil { - return networktypes.Coordinator{}, err - } - resCoord, err := n.profileQuery. - Coordinator(ctx, - &profiletypes.QueryGetCoordinatorRequest{ - CoordinatorID: coordinatorID, - }, - ) - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return networktypes.Coordinator{}, ErrObjectNotFound - } else if err != nil { - return networktypes.Coordinator{}, err - } - return networktypes.ToCoordinator(resCoord.Coordinator), nil -} - -// SetValidatorDescription set a validator profile. -func (n Network) SetValidatorDescription(ctx context.Context, validator profiletypes.Validator) error { - n.ev.Send("Setting validator description", events.ProgressStart()) - - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - message := profiletypes.NewMsgUpdateValidatorDescription( - addr, - validator.Description.Identity, - validator.Description.Moniker, - validator.Description.Website, - validator.Description.SecurityContact, - validator.Description.Details, - ) - - res, err := n.cosmos.BroadcastTx(ctx, n.account, message) - if err != nil { - return err - } - - var requestRes profiletypes.MsgUpdateValidatorDescriptionResponse - return res.Decode(&requestRes) -} - -// Validator returns the Validator by address from SPN. -func (n Network) Validator(ctx context.Context, address string) (networktypes.Validator, error) { - n.ev.Send("Fetching validator description", events.ProgressStart()) - res, err := n.profileQuery. - Validator(ctx, - &profiletypes.QueryGetValidatorRequest{ - Address: address, - }, - ) - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return networktypes.Validator{}, ErrObjectNotFound - } else if err != nil { - return networktypes.Validator{}, err - } - return networktypes.ToValidator(res.Validator), nil -} - -// Balances returns the all balances by address from SPN. -func (n Network) Balances(ctx context.Context, address string) (sdk.Coins, error) { - n.ev.Send("Fetching address balances", events.ProgressStart()) - res, err := banktypes.NewQueryClient(n.cosmos.Context()).AllBalances(ctx, - &banktypes.QueryAllBalancesRequest{ - Address: address, - }, - ) - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return sdk.Coins{}, ErrObjectNotFound - } else if err != nil { - return sdk.Coins{}, err - } - return res.Balances, nil -} - -// Profile returns the address profile info. -func (n Network) Profile(ctx context.Context, projectID uint64) (networktypes.Profile, error) { - address, err := n.account.Address(networktypes.SPN) - if err != nil { - return networktypes.Profile{}, err - } - - // fetch vouchers held by the account - coins, err := n.Balances(ctx, address) - if err != nil { - return networktypes.Profile{}, err - } - vouchers := sdk.NewCoins() - for _, coin := range coins { - // parse the coin to filter all non-voucher coins from the balance - _, err := campaigntypes.VoucherCampaign(coin.Denom) - if err == nil { - vouchers = append(vouchers, coin) - } - } - vouchers = vouchers.Sort() - - var shares campaigntypes.Shares - - // if a project ID is specified, fetches the shares of the project - if projectID > 0 { - acc, err := n.MainnetAccount(ctx, projectID, address) - if err != nil && !errors.Is(err, ErrObjectNotFound) { - return networktypes.Profile{}, err - } - shares = acc.Shares - } - - var p networktypes.ProfileAcc - p, err = n.Validator(ctx, address) - if errors.Is(err, ErrObjectNotFound) { - p, err = n.Coordinator(ctx, address) - if errors.Is(err, ErrObjectNotFound) { - p = networktypes.Coordinator{Address: address} - } else if err != nil { - return networktypes.Profile{}, err - } - } else if err != nil { - return networktypes.Profile{}, err - } - return p.ToProfile(projectID, vouchers, shares), nil -} diff --git a/ignite/services/network/project.go b/ignite/services/network/project.go deleted file mode 100644 index 031f1deebf..0000000000 --- a/ignite/services/network/project.go +++ /dev/null @@ -1,185 +0,0 @@ -package network - -import ( - "context" - "errors" - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" - campaigntypes "github.com/tendermint/spn/x/campaign/types" - - "github.com/ignite/cli/ignite/pkg/cosmoserror" - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -type ( - // Prop updates project proposal. - Prop func(*updateProp) - - // updateProp represents the update project proposal. - updateProp struct { - name string - metadata []byte - totalSupply sdk.Coins - } -) - -// WithProjectName provides a name proposal to update the project. -func WithProjectName(name string) Prop { - return func(c *updateProp) { - c.name = name - } -} - -// WithProjectMetadata provides a meta data proposal to update the project. -func WithProjectMetadata(metadata string) Prop { - return func(c *updateProp) { - c.metadata = []byte(metadata) - } -} - -// WithProjectTotalSupply provides a total supply proposal to update the project. -func WithProjectTotalSupply(totalSupply sdk.Coins) Prop { - return func(c *updateProp) { - c.totalSupply = totalSupply - } -} - -// Project fetches the project from Network. -func (n Network) Project(ctx context.Context, projectID uint64) (networktypes.Project, error) { - n.ev.Send("Fetching project information", events.ProgressStart()) - res, err := n.campaignQuery.Campaign(ctx, &campaigntypes.QueryGetCampaignRequest{ - CampaignID: projectID, - }) - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return networktypes.Project{}, ErrObjectNotFound - } else if err != nil { - return networktypes.Project{}, err - } - return networktypes.ToProject(res.Campaign), nil -} - -// Projects fetches the projects from Network. -func (n Network) Projects(ctx context.Context) ([]networktypes.Project, error) { - var projects []networktypes.Project - - n.ev.Send("Fetching projects information", events.ProgressStart()) - res, err := n.campaignQuery.CampaignAll(ctx, &campaigntypes.QueryAllCampaignRequest{}) - if err != nil { - return projects, err - } - - // Parse fetched projects - for _, project := range res.Campaign { - projects = append(projects, networktypes.ToProject(project)) - } - - return projects, nil -} - -// CreateProject creates a project in Network. -func (n Network) CreateProject(ctx context.Context, name, metadata string, totalSupply sdk.Coins) (uint64, error) { - n.ev.Send(fmt.Sprintf("Creating project %s", name), events.ProgressStart()) - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return 0, err - } - - msgCreateCampaign := campaigntypes.NewMsgCreateCampaign( - addr, - name, - totalSupply, - []byte(metadata), - ) - res, err := n.cosmos.BroadcastTx(ctx, n.account, msgCreateCampaign) - if err != nil { - return 0, err - } - - var createCampaignRes campaigntypes.MsgCreateCampaignResponse - if err := res.Decode(&createCampaignRes); err != nil { - return 0, err - } - - return createCampaignRes.CampaignID, nil -} - -// InitializeMainnet Initialize the mainnet of the project. -func (n Network) InitializeMainnet( - ctx context.Context, - projectID uint64, - sourceURL, - sourceHash string, - mainnetChainID string, -) (uint64, error) { - n.ev.Send("Initializing the mainnet project", events.ProgressStart()) - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return 0, err - } - - msg := campaigntypes.NewMsgInitializeMainnet( - addr, - projectID, - sourceURL, - sourceHash, - mainnetChainID, - ) - - res, err := n.cosmos.BroadcastTx(ctx, n.account, msg) - if err != nil { - return 0, err - } - - var initMainnetRes campaigntypes.MsgInitializeMainnetResponse - if err := res.Decode(&initMainnetRes); err != nil { - return 0, err - } - - n.ev.Send(fmt.Sprintf("Project %d initialized on mainnet", projectID), events.ProgressFinish()) - - return initMainnetRes.MainnetID, nil -} - -// UpdateProject updates the project name or metadata. -func (n Network) UpdateProject( - ctx context.Context, - id uint64, - props ...Prop, -) error { - // Apply the options provided by the user - p := updateProp{} - for _, apply := range props { - apply(&p) - } - - n.ev.Send(fmt.Sprintf("Updating the project %d", id), events.ProgressStart()) - account, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - msgs := make([]sdk.Msg, 0) - if p.name != "" || len(p.metadata) > 0 { - msgs = append(msgs, campaigntypes.NewMsgEditCampaign( - account, - id, - p.name, - p.metadata, - )) - } - if !p.totalSupply.Empty() { - msgs = append(msgs, campaigntypes.NewMsgUpdateTotalSupply( - account, - id, - p.totalSupply, - )) - } - - if _, err := n.cosmos.BroadcastTx(ctx, n.account, msgs...); err != nil { - return err - } - n.ev.Send(fmt.Sprintf("Project %d updated", id), events.ProgressFinish()) - return nil -} diff --git a/ignite/services/network/publish.go b/ignite/services/network/publish.go deleted file mode 100644 index f8fb93d9a0..0000000000 --- a/ignite/services/network/publish.go +++ /dev/null @@ -1,269 +0,0 @@ -package network - -import ( - "context" - "errors" - "os" - "path/filepath" - - cosmosgenesis "github.com/ignite/cli/ignite/pkg/cosmosutil/genesis" - - sdk "github.com/cosmos/cosmos-sdk/types" - campaigntypes "github.com/tendermint/spn/x/campaign/types" - launchtypes "github.com/tendermint/spn/x/launch/types" - profiletypes "github.com/tendermint/spn/x/profile/types" - - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// publishOptions holds info about how to create a chain. -type publishOptions struct { - genesisURL string - genesisConfig string - chainID string - projectID uint64 - metadata string - totalSupply sdk.Coins - sharePercentages SharePercents - mainnet bool - accountBalance sdk.Coins -} - -// PublishOption configures chain creation. -type PublishOption func(*publishOptions) - -// WithProject add a project id. -func WithProject(id uint64) PublishOption { - return func(o *publishOptions) { - o.projectID = id - } -} - -// WithChainID use a custom chain id. -func WithChainID(chainID string) PublishOption { - return func(o *publishOptions) { - o.chainID = chainID - } -} - -// WithCustomGenesisURL enables using a custom genesis during publish. -func WithCustomGenesisURL(url string) PublishOption { - return func(o *publishOptions) { - o.genesisURL = url - } -} - -// WithCustomGenesisConfig enables using a custom genesis during publish. -func WithCustomGenesisConfig(configFile string) PublishOption { - return func(o *publishOptions) { - o.genesisConfig = configFile - } -} - -// WithMetadata provides a meta data proposal to update the project. -func WithMetadata(metadata string) PublishOption { - return func(c *publishOptions) { - c.metadata = metadata - } -} - -// WithTotalSupply provides a total supply proposal to update the project. -func WithTotalSupply(totalSupply sdk.Coins) PublishOption { - return func(c *publishOptions) { - c.totalSupply = totalSupply - } -} - -// WithPercentageShares enables minting vouchers for shares. -func WithPercentageShares(sharePercentages []SharePercent) PublishOption { - return func(c *publishOptions) { - c.sharePercentages = sharePercentages - } -} - -// WithAccountBalance set a balance used for all genesis account of the chain. -func WithAccountBalance(accountBalance sdk.Coins) PublishOption { - return func(c *publishOptions) { - c.accountBalance = accountBalance - } -} - -// Mainnet initialize a published chain into the mainnet. -func Mainnet() PublishOption { - return func(o *publishOptions) { - o.mainnet = true - } -} - -// Publish submits Genesis to SPN to announce a new network. -func (n Network) Publish(ctx context.Context, c Chain, options ...PublishOption) (launchID, projectID uint64, err error) { - o := publishOptions{} - for _, apply := range options { - apply(&o) - } - - var ( - genesisHash string - genesis *cosmosgenesis.Genesis - chainID string - ) - - // if the initial genesis is a genesis URL and no check are performed, we simply fetch it and get its hash. - if o.genesisURL != "" { - genesis, err = cosmosgenesis.FromURL(ctx, o.genesisURL, filepath.Join(os.TempDir(), "genesis.json")) - if err != nil { - return 0, 0, err - } - genesisHash, err = genesis.Hash() - if err != nil { - return 0, 0, err - } - chainID, err = genesis.ChainID() - if err != nil { - return 0, 0, err - } - } - - // use chain id flag always in the highest priority. - if o.chainID != "" { - chainID = o.chainID - } - // if the chain id is empty, use a default one. - if chainID == "" { - chainID, err = c.ChainID() - if err != nil { - return 0, 0, err - } - } - - coordinatorAddress, err := n.account.Address(networktypes.SPN) - if err != nil { - return 0, 0, err - } - projectID = o.projectID - - n.ev.Send("Publishing the network", events.ProgressStart()) - - // a coordinator profile is necessary to publish a chain - // if the user doesn't have an associated coordinator profile, we create one - if _, err := n.CoordinatorIDByAddress(ctx, coordinatorAddress); errors.Is(err, ErrObjectNotFound) { - msgCreateCoordinator := profiletypes.NewMsgCreateCoordinator( - coordinatorAddress, - "", - "", - "", - ) - if _, err := n.cosmos.BroadcastTx(ctx, n.account, msgCreateCoordinator); err != nil { - return 0, 0, err - } - } else if err != nil { - return 0, 0, err - } - - // check if a project associated to the chain is provided - if projectID != 0 { - _, err = n.campaignQuery. - Campaign(ctx, &campaigntypes.QueryGetCampaignRequest{ - CampaignID: o.projectID, - }) - if err != nil { - return 0, 0, err - } - } else if o.mainnet { - // a mainnet is always associated to a project - // if no project is provided, we create one, and we directly initialize the mainnet - projectID, err = n.CreateProject(ctx, c.Name(), o.metadata, o.totalSupply) - if err != nil { - return 0, 0, err - } - } - - // mint vouchers - if projectID != 0 && !o.sharePercentages.Empty() { - totalSharesResp, err := n.campaignQuery.TotalShares(ctx, &campaigntypes.QueryTotalSharesRequest{}) - if err != nil { - return 0, 0, err - } - - var coins []sdk.Coin - for _, percentage := range o.sharePercentages { - coin, err := percentage.Share(totalSharesResp.TotalShares) - if err != nil { - return 0, 0, err - } - coins = append(coins, coin) - } - // TODO consider moving to UpdateCampaign, but not sure, may not be relevant. - // It is better to send multiple message in a single tx too. - // consider ways to refactor to accomplish a better API and efficiency. - - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return 0, 0, err - } - - msgMintVouchers := campaigntypes.NewMsgMintVouchers( - addr, - projectID, - campaigntypes.NewSharesFromCoins(sdk.NewCoins(coins...)), - ) - _, err = n.cosmos.BroadcastTx(ctx, n.account, msgMintVouchers) - if err != nil { - return 0, 0, err - } - } - - // depending on mainnet flag initialize mainnet or testnet - if o.mainnet { - launchID, err = n.InitializeMainnet(ctx, projectID, c.SourceURL(), c.SourceHash(), chainID) - if err != nil { - return 0, 0, err - } - } else { - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return 0, 0, err - } - - // get initial genesis - initialGenesis := launchtypes.NewDefaultInitialGenesis() - switch { - case o.genesisURL != "": - initialGenesis = launchtypes.NewGenesisURL( - o.genesisURL, - genesisHash, - ) - case o.genesisConfig != "": - initialGenesis = launchtypes.NewGenesisConfig( - o.genesisConfig, - ) - } - - msgCreateChain := launchtypes.NewMsgCreateChain( - addr, - chainID, - c.SourceURL(), - c.SourceHash(), - initialGenesis, - projectID != 0, - projectID, - o.accountBalance, - nil, - ) - res, err := n.cosmos.BroadcastTx(ctx, n.account, msgCreateChain) - if err != nil { - return 0, 0, err - } - var createChainRes launchtypes.MsgCreateChainResponse - if err := res.Decode(&createChainRes); err != nil { - return 0, 0, err - } - launchID = createChainRes.LaunchID - } - if err := c.CacheBinary(launchID); err != nil { - return 0, 0, err - } - - return launchID, projectID, nil -} diff --git a/ignite/services/network/publish_test.go b/ignite/services/network/publish_test.go deleted file mode 100644 index 024a0efb8e..0000000000 --- a/ignite/services/network/publish_test.go +++ /dev/null @@ -1,958 +0,0 @@ -package network - -import ( - "context" - "errors" - "net/http" - "net/http/httptest" - "os" - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - campaigntypes "github.com/tendermint/spn/x/campaign/types" - launchtypes "github.com/tendermint/spn/x/launch/types" - profiletypes "github.com/tendermint/spn/x/profile/types" - - "github.com/ignite/cli/ignite/pkg/cosmoserror" - "github.com/ignite/cli/ignite/services/network/networktypes" - "github.com/ignite/cli/ignite/services/network/testutil" -) - -func startGenesisTestServer(filepath string) *httptest.Server { - return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - file, err := os.ReadFile(filepath) - if err != nil { - panic(err) - } - if _, err = w.Write(file); err != nil { - panic(err) - } - })) -} - -func startInvalidJSONServer() *httptest.Server { - return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("invalid json")) - })) -} - -func TestPublish(t *testing.T) { - t.Run("publish chain without project", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &launchtypes.MsgCreateChain{ - Coordinator: addr, - GenesisChainID: testutil.ChainID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - InitialGenesis: launchtypes.NewDefaultInitialGenesis(), - HasCampaign: false, - CampaignID: 0, - }, - ). - Return(testutil.NewResponse(&launchtypes.MsgCreateChainResponse{ - LaunchID: testutil.LaunchID, - }), nil). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("ChainID").Return(testutil.ChainID, nil).Once() - suite.ChainMock.On("CacheBinary", testutil.LaunchID).Return(nil).Once() - - launchID, projectID, publishError := network.Publish(context.Background(), suite.ChainMock) - require.NoError(t, publishError) - require.Equal(t, testutil.LaunchID, launchID) - require.Equal(t, uint64(0), projectID) - suite.AssertAllMocks(t) - }) - - t.Run("publish chain with custom account balance", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - ) - - accountBalance, err := sdk.ParseCoinsNormalized("1000foo,500bar") - require.NoError(t, err) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &launchtypes.MsgCreateChain{ - Coordinator: addr, - GenesisChainID: testutil.ChainID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - InitialGenesis: launchtypes.NewDefaultInitialGenesis(), - HasCampaign: false, - CampaignID: 0, - AccountBalance: accountBalance, - }, - ). - Return(testutil.NewResponse(&launchtypes.MsgCreateChainResponse{ - LaunchID: testutil.LaunchID, - }), nil). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("ChainID").Return(testutil.ChainID, nil).Once() - suite.ChainMock.On("CacheBinary", testutil.LaunchID).Return(nil).Once() - - launchID, projectID, publishError := network.Publish( - context.Background(), - suite.ChainMock, - WithAccountBalance(accountBalance), - ) - require.NoError(t, publishError) - require.Equal(t, testutil.LaunchID, launchID) - require.Equal(t, uint64(0), projectID) - suite.AssertAllMocks(t) - }) - - t.Run("publish chain with pre created project", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CampaignQueryMock. - On( - "Campaign", - context.Background(), - &campaigntypes.QueryGetCampaignRequest{ - CampaignID: testutil.ProjectID, - }, - ). - Return(nil, nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &launchtypes.MsgCreateChain{ - Coordinator: addr, - GenesisChainID: testutil.ChainID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - InitialGenesis: launchtypes.NewDefaultInitialGenesis(), - HasCampaign: true, - CampaignID: testutil.ProjectID, - }, - ). - Return(testutil.NewResponse(&launchtypes.MsgCreateChainResponse{ - LaunchID: testutil.LaunchID, - }), nil). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("ChainID").Return(testutil.ChainID, nil).Once() - suite.ChainMock.On("CacheBinary", testutil.LaunchID).Return(nil).Once() - - launchID, projectID, publishError := network.Publish(context.Background(), suite.ChainMock, WithProject(testutil.ProjectID)) - require.NoError(t, publishError) - require.Equal(t, testutil.LaunchID, launchID) - require.Equal(t, testutil.ProjectID, projectID) - suite.AssertAllMocks(t) - }) - - t.Run("publish chain with a pre created project with shares", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CampaignQueryMock. - On( - "Campaign", - context.Background(), - &campaigntypes.QueryGetCampaignRequest{ - CampaignID: testutil.ProjectID, - }, - ). - Return(nil, nil). - Once() - suite.CampaignQueryMock. - On( - "TotalShares", - context.Background(), - &campaigntypes.QueryTotalSharesRequest{}, - ). - Return(&campaigntypes.QueryTotalSharesResponse{ - TotalShares: 100000, - }, nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - campaigntypes.NewMsgMintVouchers( - addr, - testutil.ProjectID, - campaigntypes.NewSharesFromCoins(sdk.NewCoins(sdk.NewInt64Coin("foo", 2000), sdk.NewInt64Coin("staking", 50000))), - ), - ). - Return(testutil.NewResponse(&campaigntypes.MsgMintVouchersResponse{}), nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &launchtypes.MsgCreateChain{ - Coordinator: addr, - GenesisChainID: testutil.ChainID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - InitialGenesis: launchtypes.NewDefaultInitialGenesis(), - HasCampaign: true, - CampaignID: testutil.ProjectID, - }, - ). - Return(testutil.NewResponse(&launchtypes.MsgCreateChainResponse{ - LaunchID: testutil.LaunchID, - }), nil). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("ChainID").Return(testutil.ChainID, nil).Once() - suite.ChainMock.On("CacheBinary", testutil.LaunchID).Return(nil).Once() - - launchID, projectID, publishError := network.Publish(context.Background(), suite.ChainMock, WithProject(testutil.ProjectID), - WithPercentageShares([]SharePercent{ - SampleSharePercent(t, "foo", 2, 100), - SampleSharePercent(t, "staking", 50, 100), - }), - ) - require.NoError(t, publishError) - require.Equal(t, testutil.LaunchID, launchID) - require.Equal(t, testutil.ProjectID, projectID) - suite.AssertAllMocks(t) - }) - - t.Run("publish chain with custom genesis url", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - customGenesisChainID = "test-custom-1" - customGenesisHash = "86167654c1af18c801837d443563fd98b3fe5e8d337e70faad181cdf2100da52" - gts = startGenesisTestServer("mocks/data/genesis.json") - suite, network = newSuite(account) - ) - defer gts.Close() - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &launchtypes.MsgCreateChain{ - Coordinator: addr, - GenesisChainID: customGenesisChainID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - InitialGenesis: launchtypes.NewGenesisURL( - gts.URL, - customGenesisHash, - ), - HasCampaign: false, - CampaignID: 0, - }, - ). - Return(testutil.NewResponse(&launchtypes.MsgCreateChainResponse{ - LaunchID: testutil.LaunchID, - }), nil). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("CacheBinary", testutil.LaunchID).Return(nil).Once() - - launchID, projectID, publishError := network.Publish( - context.Background(), - suite.ChainMock, - WithCustomGenesisURL(gts.URL), - ) - require.NoError(t, publishError) - require.Equal(t, testutil.LaunchID, launchID) - require.Equal(t, uint64(0), projectID) - suite.AssertAllMocks(t) - }) - - t.Run("publish chain with custom chain id", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &launchtypes.MsgCreateChain{ - Coordinator: addr, - GenesisChainID: testutil.ChainID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - InitialGenesis: launchtypes.NewDefaultInitialGenesis(), - HasCampaign: false, - CampaignID: 0, - }, - ). - Return(testutil.NewResponse(&launchtypes.MsgCreateChainResponse{ - LaunchID: testutil.LaunchID, - }), nil). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("CacheBinary", testutil.LaunchID).Return(nil).Once() - - launchID, projectID, publishError := network.Publish(context.Background(), suite.ChainMock, WithChainID(testutil.ChainID)) - require.NoError(t, publishError) - require.Equal(t, testutil.LaunchID, launchID) - require.Equal(t, uint64(0), projectID) - suite.AssertAllMocks(t) - }) - - t.Run("publish chain with custom genesis config", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &launchtypes.MsgCreateChain{ - Coordinator: addr, - GenesisChainID: testutil.ChainID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - InitialGenesis: launchtypes.NewGenesisConfig( - testutil.ChainConfigYML, - ), - HasCampaign: false, - CampaignID: 0, - }, - ). - Return(testutil.NewResponse(&launchtypes.MsgCreateChainResponse{ - LaunchID: testutil.LaunchID, - }), nil). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("ChainID").Return(testutil.ChainID, nil).Once() - suite.ChainMock.On("CacheBinary", testutil.LaunchID).Return(nil).Once() - - launchID, projectID, publishError := network.Publish( - context.Background(), - suite.ChainMock, - WithCustomGenesisConfig(testutil.ChainConfigYML), - ) - require.NoError(t, publishError) - require.Equal(t, testutil.LaunchID, launchID) - require.Equal(t, uint64(0), projectID) - suite.AssertAllMocks(t) - }) - - t.Run("publish chain with custom chain id", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &launchtypes.MsgCreateChain{ - Coordinator: addr, - GenesisChainID: testutil.ChainID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - InitialGenesis: launchtypes.NewDefaultInitialGenesis(), - HasCampaign: false, - CampaignID: 0, - }, - ). - Return(testutil.NewResponse(&launchtypes.MsgCreateChainResponse{ - LaunchID: testutil.LaunchID, - }), nil). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("CacheBinary", testutil.LaunchID).Return(nil).Once() - - launchID, projectID, publishError := network.Publish(context.Background(), suite.ChainMock, WithChainID(testutil.ChainID)) - require.NoError(t, publishError) - require.Equal(t, testutil.LaunchID, launchID) - require.Equal(t, uint64(0), projectID) - suite.AssertAllMocks(t) - }) - - t.Run("publish chain with mainnet", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - gts = startGenesisTestServer("mocks/data/genesis.json") - suite, network = newSuite(account) - ) - defer gts.Close() - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &campaigntypes.MsgCreateCampaign{ - Coordinator: addr, - CampaignName: testutil.ChainName, - Metadata: []byte{}, - }, - ). - Return(testutil.NewResponse(&campaigntypes.MsgCreateCampaignResponse{ - CampaignID: testutil.ProjectID, - }), nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &campaigntypes.MsgInitializeMainnet{ - Coordinator: addr, - CampaignID: testutil.ProjectID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - MainnetChainID: testutil.ChainID, - }, - ). - Return(testutil.NewResponse(&campaigntypes.MsgInitializeMainnetResponse{ - MainnetID: testutil.MainnetID, - }), nil). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("Name").Return(testutil.ChainName).Once() - suite.ChainMock.On("ChainID").Return(testutil.ChainID, nil).Once() - suite.ChainMock.On("CacheBinary", testutil.LaunchID).Return(nil).Once() - - launchID, projectID, publishError := network.Publish(context.Background(), suite.ChainMock, Mainnet()) - require.NoError(t, publishError) - require.Equal(t, testutil.LaunchID, launchID) - require.Equal(t, testutil.ProjectID, projectID) - suite.AssertAllMocks(t) - }) - - t.Run("failed to publish chain with mainnet, failed to initialize mainnet", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - expectedError = errors.New("failed to initialize mainnet") - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &campaigntypes.MsgCreateCampaign{ - Coordinator: addr, - CampaignName: testutil.ChainName, - Metadata: []byte{}, - }, - ). - Return(testutil.NewResponse(&campaigntypes.MsgCreateCampaignResponse{ - CampaignID: testutil.ProjectID, - }), nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &campaigntypes.MsgInitializeMainnet{ - Coordinator: addr, - CampaignID: testutil.ProjectID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - MainnetChainID: testutil.ChainID, - }, - ). - Return(testutil.NewResponse(&campaigntypes.MsgInitializeMainnetResponse{ - MainnetID: testutil.MainnetID, - }), expectedError). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("Name").Return(testutil.ChainName).Once() - suite.ChainMock.On("ChainID").Return(testutil.ChainID, nil).Once() - - _, _, publishError := network.Publish(context.Background(), suite.ChainMock, Mainnet()) - require.Error(t, publishError) - require.ErrorIs(t, publishError, expectedError) - suite.AssertAllMocks(t) - }) - - t.Run("failed to publish chain with custom genesis, failed to parse custom genesis", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - gts = startInvalidJSONServer() - expectedError = errors.New("JSON field not found") - ) - defer gts.Close() - - _, _, publishError := network.Publish( - context.Background(), - suite.ChainMock, - WithCustomGenesisURL(gts.URL), - ) - require.Error(t, publishError) - require.Equal(t, expectedError.Error(), publishError.Error()) - suite.AssertAllMocks(t) - }) - - t.Run("publish chain with coordinator creation", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On("CoordinatorByAddress", mock.Anything, &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }). - Return(nil, cosmoserror.ErrNotFound). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &launchtypes.MsgCreateChain{ - Coordinator: addr, - GenesisChainID: testutil.ChainID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - InitialGenesis: launchtypes.NewDefaultInitialGenesis(), - HasCampaign: false, - CampaignID: 0, - }, - ). - Return(testutil.NewResponse(&launchtypes.MsgCreateChainResponse{ - LaunchID: testutil.LaunchID, - }), nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &profiletypes.MsgCreateCoordinator{ - Address: addr, - }, - ). - Return(testutil.NewResponse(&profiletypes.MsgCreateCoordinatorResponse{}), nil). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("ChainID").Return(testutil.ChainID, nil).Once() - suite.ChainMock.On("CacheBinary", testutil.LaunchID).Return(nil).Once() - - launchID, projectID, publishError := network.Publish(context.Background(), suite.ChainMock) - require.NoError(t, publishError) - require.Equal(t, testutil.LaunchID, launchID) - require.Equal(t, uint64(0), projectID) - suite.AssertAllMocks(t) - }) - - t.Run("failed to publish chain, failed to fetch coordinator profile", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - expectedError = errors.New("failed to fetch coordinator") - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On("CoordinatorByAddress", mock.Anything, &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }). - Return(nil, expectedError). - Once() - suite.ChainMock.On("ChainID").Return(testutil.ChainID, nil).Once() - - _, _, publishError := network.Publish(context.Background(), suite.ChainMock) - require.Error(t, publishError) - require.ErrorIs(t, publishError, expectedError) - suite.AssertAllMocks(t) - }) - - t.Run("failed to publish chain, failed to read chain id", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - expectedError = errors.New("failed to get chainID") - ) - - suite.ChainMock. - On("ChainID"). - Return("", expectedError). - Once() - - _, _, publishError := network.Publish(context.Background(), suite.ChainMock) - require.Error(t, publishError) - require.ErrorIs(t, publishError, expectedError) - suite.AssertAllMocks(t) - }) - - t.Run("failed to publish chain, failed to fetch existed project", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CampaignQueryMock. - On("Campaign", mock.Anything, &campaigntypes.QueryGetCampaignRequest{ - CampaignID: testutil.ProjectID, - }). - Return(nil, cosmoserror.ErrNotFound). - Once() - suite.ChainMock.On("ChainID").Return(testutil.ChainID, nil).Once() - - _, _, publishError := network.Publish(context.Background(), suite.ChainMock, WithProject(testutil.ProjectID)) - require.Error(t, publishError) - require.ErrorIs(t, publishError, cosmoserror.ErrNotFound) - suite.AssertAllMocks(t) - }) - - t.Run("failed to publish chain, failed to create chain", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - expectedError = errors.New("failed to create chain") - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &launchtypes.MsgCreateChain{ - Coordinator: addr, - GenesisChainID: testutil.ChainID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - InitialGenesis: launchtypes.NewDefaultInitialGenesis(), - HasCampaign: false, - CampaignID: 0, - }, - ). - Return(testutil.NewResponse(&launchtypes.MsgCreateChainResponse{ - LaunchID: testutil.LaunchID, - }), expectedError). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("ChainID").Return(testutil.ChainID, nil).Once() - - _, _, publishError := network.Publish(context.Background(), suite.ChainMock) - require.Error(t, publishError) - require.Equal(t, expectedError, publishError) - suite.AssertAllMocks(t) - }) - - t.Run("failed to publish chain, failed to cache binary", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - expectedError = errors.New("failed to cache binary") - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.ProfileQueryMock. - On( - "CoordinatorByAddress", - context.Background(), - &profiletypes.QueryGetCoordinatorByAddressRequest{ - Address: addr, - }, - ). - Return(&profiletypes.QueryGetCoordinatorByAddressResponse{ - CoordinatorByAddress: profiletypes.CoordinatorByAddress{ - Address: addr, - CoordinatorID: 1, - }, - }, nil). - Once() - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &launchtypes.MsgCreateChain{ - Coordinator: addr, - GenesisChainID: testutil.ChainID, - SourceURL: testutil.ChainSourceURL, - SourceHash: testutil.ChainSourceHash, - InitialGenesis: launchtypes.NewDefaultInitialGenesis(), - HasCampaign: false, - CampaignID: 0, - }, - ). - Return(testutil.NewResponse(&launchtypes.MsgCreateChainResponse{ - LaunchID: testutil.LaunchID, - }), nil). - Once() - suite.ChainMock.On("SourceHash").Return(testutil.ChainSourceHash).Once() - suite.ChainMock.On("SourceURL").Return(testutil.ChainSourceURL).Once() - suite.ChainMock.On("ChainID").Return(testutil.ChainID, nil).Once() - suite.ChainMock. - On("CacheBinary", testutil.LaunchID). - Return(expectedError). - Once() - - _, _, publishError := network.Publish(context.Background(), suite.ChainMock) - require.Error(t, publishError) - require.ErrorIs(t, publishError, expectedError) - suite.AssertAllMocks(t) - }) -} diff --git a/ignite/services/network/queries.go b/ignite/services/network/queries.go deleted file mode 100644 index 27275ce637..0000000000 --- a/ignite/services/network/queries.go +++ /dev/null @@ -1,307 +0,0 @@ -package network - -import ( - "context" - "fmt" - "sort" - "sync" - - "github.com/cosmos/cosmos-sdk/types/query" - - "github.com/pkg/errors" - campaigntypes "github.com/tendermint/spn/x/campaign/types" - launchtypes "github.com/tendermint/spn/x/launch/types" - rewardtypes "github.com/tendermint/spn/x/reward/types" - "golang.org/x/sync/errgroup" - - "github.com/ignite/cli/ignite/pkg/cosmoserror" - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// ErrObjectNotFound is returned when the query returns a not found error. -var ErrObjectNotFound = errors.New("query object not found") - -// ChainLaunch fetches the chain launch from Network by launch id. -func (n Network) ChainLaunch(ctx context.Context, id uint64) (networktypes.ChainLaunch, error) { - n.ev.Send("Fetching chain information", events.ProgressStart()) - - res, err := n.launchQuery. - Chain(ctx, - &launchtypes.QueryGetChainRequest{ - LaunchID: id, - }, - ) - if err != nil { - return networktypes.ChainLaunch{}, err - } - - return networktypes.ToChainLaunch(res.Chain), nil -} - -// ChainLaunchesWithReward fetches the chain launches with rewards from Network. -func (n Network) ChainLaunchesWithReward(ctx context.Context, pagination *query.PageRequest) ([]networktypes.ChainLaunch, error) { - g, ctx := errgroup.WithContext(ctx) - - n.ev.Send("Fetching chains information", events.ProgressStart()) - res, err := n.launchQuery. - ChainAll(ctx, &launchtypes.QueryAllChainRequest{ - Pagination: pagination, - }) - if err != nil { - return nil, err - } - - n.ev.Send("Fetching reward information", events.ProgressUpdate()) - var chainLaunches []networktypes.ChainLaunch - var mu sync.Mutex - - // Parse fetched chains and fetch rewards - for _, chain := range res.Chain { - chain := chain - g.Go(func() error { - chainLaunch := networktypes.ToChainLaunch(chain) - reward, err := n.ChainReward(ctx, chain.LaunchID) - if err != nil && !errors.Is(err, ErrObjectNotFound) { - return err - } - chainLaunch.Reward = reward.RemainingCoins.String() - mu.Lock() - chainLaunches = append(chainLaunches, chainLaunch) - mu.Unlock() - return nil - }) - } - if err := g.Wait(); err != nil { - return nil, err - } - // sort filenames by launch id - sort.Slice(chainLaunches, func(i, j int) bool { - return chainLaunches[i].ID > chainLaunches[j].ID - }) - return chainLaunches, nil -} - -// GenesisInformation returns all the information to construct the genesis from a chain ID. -func (n Network) GenesisInformation(ctx context.Context, launchID uint64) (gi networktypes.GenesisInformation, err error) { - genAccs, err := n.GenesisAccounts(ctx, launchID) - if err != nil { - return gi, fmt.Errorf("error querying genesis accounts: %w", err) - } - - vestingAccs, err := n.VestingAccounts(ctx, launchID) - if err != nil { - return gi, fmt.Errorf("error querying vesting accounts: %w", err) - } - - genVals, err := n.GenesisValidators(ctx, launchID) - if err != nil { - return gi, fmt.Errorf("error querying genesis validators: %w", err) - } - - paramChanges, err := n.ParamChanges(ctx, launchID) - if err != nil { - return gi, fmt.Errorf("error querying param changes: %w", err) - } - - return networktypes.NewGenesisInformation(genAccs, vestingAccs, genVals, paramChanges), nil -} - -// GenesisAccounts returns the list of approved genesis accounts for a launch from SPN. -func (n Network) GenesisAccounts(ctx context.Context, launchID uint64) (genAccs []networktypes.GenesisAccount, err error) { - n.ev.Send("Fetching genesis accounts", events.ProgressStart()) - res, err := n.launchQuery. - GenesisAccountAll(ctx, - &launchtypes.QueryAllGenesisAccountRequest{ - LaunchID: launchID, - }, - ) - if err != nil { - return genAccs, err - } - - for _, acc := range res.GenesisAccount { - genAccs = append(genAccs, networktypes.ToGenesisAccount(acc)) - } - - return genAccs, nil -} - -// VestingAccounts returns the list of approved genesis vesting accounts for a launch from SPN. -func (n Network) VestingAccounts(ctx context.Context, launchID uint64) (vestingAccs []networktypes.VestingAccount, err error) { - n.ev.Send("Fetching genesis vesting accounts", events.ProgressStart()) - res, err := n.launchQuery. - VestingAccountAll(ctx, - &launchtypes.QueryAllVestingAccountRequest{ - LaunchID: launchID, - }, - ) - if err != nil { - return vestingAccs, err - } - - for i, acc := range res.VestingAccount { - parsedAcc, err := networktypes.ToVestingAccount(acc) - if err != nil { - return vestingAccs, errors.Wrapf(err, "error parsing vesting account %d", i) - } - - vestingAccs = append(vestingAccs, parsedAcc) - } - - return vestingAccs, nil -} - -// GenesisValidators returns the list of approved genesis validators for a launch from SPN. -func (n Network) GenesisValidators(ctx context.Context, launchID uint64) (genVals []networktypes.GenesisValidator, err error) { - n.ev.Send("Fetching genesis validators", events.ProgressStart()) - res, err := n.launchQuery. - GenesisValidatorAll(ctx, - &launchtypes.QueryAllGenesisValidatorRequest{ - LaunchID: launchID, - }, - ) - if err != nil { - return genVals, err - } - - for _, acc := range res.GenesisValidator { - genVals = append(genVals, networktypes.ToGenesisValidator(acc)) - } - - return genVals, nil -} - -// ParamChanges returns the list of approved param changes for a launch from SPN. -func (n Network) ParamChanges(ctx context.Context, launchID uint64) (paramChanges []networktypes.ParamChange, err error) { - n.ev.Send("Fetching param changes", events.ProgressStart()) - res, err := n.launchQuery. - ParamChangeAll(ctx, - &launchtypes.QueryAllParamChangeRequest{ - LaunchID: launchID, - }, - ) - if err != nil { - return paramChanges, err - } - - for _, pc := range res.ParamChanges { - paramChanges = append(paramChanges, networktypes.ToParamChange(pc)) - } - - return paramChanges, nil -} - -// MainnetAccount returns the project mainnet account for a launch from SPN. -func (n Network) MainnetAccount( - ctx context.Context, - projectID uint64, - address string, -) (acc networktypes.MainnetAccount, err error) { - n.ev.Send( - fmt.Sprintf("Fetching project %d mainnet account %s", projectID, address), - events.ProgressStart(), - ) - res, err := n.campaignQuery. - MainnetAccount(ctx, - &campaigntypes.QueryGetMainnetAccountRequest{ - CampaignID: projectID, - Address: address, - }, - ) - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return networktypes.MainnetAccount{}, ErrObjectNotFound - } else if err != nil { - return acc, err - } - - return networktypes.ToMainnetAccount(res.MainnetAccount), nil -} - -// MainnetAccounts returns the list of project mainnet accounts for a launch from SPN. -func (n Network) MainnetAccounts(ctx context.Context, projectID uint64) (genAccs []networktypes.MainnetAccount, err error) { - n.ev.Send("Fetching project mainnet accounts", events.ProgressStart()) - res, err := n.campaignQuery. - MainnetAccountAll(ctx, - &campaigntypes.QueryAllMainnetAccountRequest{ - CampaignID: projectID, - }, - ) - if err != nil { - return genAccs, err - } - - for _, acc := range res.MainnetAccount { - genAccs = append(genAccs, networktypes.ToMainnetAccount(acc)) - } - - return genAccs, nil -} - -func (n Network) GenesisAccount(ctx context.Context, launchID uint64, address string) (networktypes.GenesisAccount, error) { - n.ev.Send("Fetching genesis accounts", events.ProgressStart()) - res, err := n.launchQuery.GenesisAccount(ctx, &launchtypes.QueryGetGenesisAccountRequest{ - LaunchID: launchID, - Address: address, - }) - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return networktypes.GenesisAccount{}, ErrObjectNotFound - } else if err != nil { - return networktypes.GenesisAccount{}, err - } - return networktypes.ToGenesisAccount(res.GenesisAccount), nil -} - -func (n Network) VestingAccount(ctx context.Context, launchID uint64, address string) (networktypes.VestingAccount, error) { - n.ev.Send("Fetching vesting accounts", events.ProgressStart()) - res, err := n.launchQuery.VestingAccount(ctx, &launchtypes.QueryGetVestingAccountRequest{ - LaunchID: launchID, - Address: address, - }) - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return networktypes.VestingAccount{}, ErrObjectNotFound - } else if err != nil { - return networktypes.VestingAccount{}, err - } - return networktypes.ToVestingAccount(res.VestingAccount) -} - -func (n Network) GenesisValidator(ctx context.Context, launchID uint64, address string) (networktypes.GenesisValidator, error) { - n.ev.Send("Fetching genesis validator", events.ProgressStart()) - res, err := n.launchQuery.GenesisValidator(ctx, &launchtypes.QueryGetGenesisValidatorRequest{ - LaunchID: launchID, - Address: address, - }) - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return networktypes.GenesisValidator{}, ErrObjectNotFound - } else if err != nil { - return networktypes.GenesisValidator{}, err - } - return networktypes.ToGenesisValidator(res.GenesisValidator), nil -} - -// ChainReward fetches the chain reward from SPN by launch id. -func (n Network) ChainReward(ctx context.Context, launchID uint64) (rewardtypes.RewardPool, error) { - res, err := n.rewardQuery. - RewardPool(ctx, - &rewardtypes.QueryGetRewardPoolRequest{ - LaunchID: launchID, - }, - ) - - if errors.Is(cosmoserror.Unwrap(err), cosmoserror.ErrNotFound) { - return rewardtypes.RewardPool{}, ErrObjectNotFound - } else if err != nil { - return rewardtypes.RewardPool{}, err - } - return res.RewardPool, nil -} - -// ChainID fetches the network chain id. -func (n Network) ChainID(ctx context.Context) (string, error) { - status, err := n.cosmos.Status(ctx) - if err != nil { - return "", err - } - return status.NodeInfo.Network, nil -} diff --git a/ignite/services/network/request.go b/ignite/services/network/request.go deleted file mode 100644 index 20ad4322c9..0000000000 --- a/ignite/services/network/request.go +++ /dev/null @@ -1,342 +0,0 @@ -package network - -import ( - "context" - "fmt" - - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/cosmosutil" - - sdk "github.com/cosmos/cosmos-sdk/types" - launchtypes "github.com/tendermint/spn/x/launch/types" - - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// Reviewal keeps a request's reviewal. -type Reviewal struct { - RequestID uint64 - IsApproved bool -} - -// ApproveRequest returns approval for a request with id. -func ApproveRequest(requestID uint64) Reviewal { - return Reviewal{ - RequestID: requestID, - IsApproved: true, - } -} - -// RejectRequest returns rejection for a request with id. -func RejectRequest(requestID uint64) Reviewal { - return Reviewal{ - RequestID: requestID, - IsApproved: false, - } -} - -// Requests fetches all the chain requests from SPN by launch id. -func (n Network) Requests(ctx context.Context, launchID uint64) ([]networktypes.Request, error) { - res, err := n.launchQuery.RequestAll(ctx, &launchtypes.QueryAllRequestRequest{ - LaunchID: launchID, - }) - if err != nil { - return nil, err - } - requests := make([]networktypes.Request, len(res.Request)) - for i, req := range res.Request { - requests[i] = networktypes.ToRequest(req) - } - return requests, nil -} - -// Request fetches the chain request from SPN by launch and request id. -func (n Network) Request(ctx context.Context, launchID, requestID uint64) (networktypes.Request, error) { - res, err := n.launchQuery.Request(ctx, &launchtypes.QueryGetRequestRequest{ - LaunchID: launchID, - RequestID: requestID, - }) - if err != nil { - return networktypes.Request{}, err - } - return networktypes.ToRequest(res.Request), nil -} - -// RequestFromIDs fetches the chain requested from SPN by launch and provided request IDs -// TODO: once implemented, use the SPN query from https://github.com/tendermint/spn/issues/420 -func (n Network) RequestFromIDs(ctx context.Context, launchID uint64, requestIDs ...uint64) (reqs []networktypes.Request, err error) { - for _, id := range requestIDs { - req, err := n.Request(ctx, launchID, id) - if err != nil { - return reqs, err - } - reqs = append(reqs, req) - } - return reqs, nil -} - -// SubmitRequest submits reviewals for proposals in batch for chain. -func (n Network) SubmitRequest(ctx context.Context, launchID uint64, reviewal ...Reviewal) error { - n.ev.Send("Submitting requests...", events.ProgressStart()) - - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - messages := make([]sdk.Msg, len(reviewal)) - for i, reviewal := range reviewal { - messages[i] = launchtypes.NewMsgSettleRequest( - addr, - launchID, - reviewal.RequestID, - reviewal.IsApproved, - ) - } - - res, err := n.cosmos.BroadcastTx(ctx, n.account, messages...) - if err != nil { - return err - } - - var requestRes launchtypes.MsgSettleRequestResponse - return res.Decode(&requestRes) -} - -// SendAccountRequest creates an add AddAccount request message. -func (n Network) SendAccountRequest( - ctx context.Context, - launchID uint64, - address string, - amount sdk.Coins, -) error { - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - msg := launchtypes.NewMsgSendRequest( - addr, - launchID, - launchtypes.NewGenesisAccount( - launchID, - address, - amount, - ), - ) - - n.ev.Send("Broadcasting account transactions", events.ProgressStart()) - - res, err := n.cosmos.BroadcastTx(ctx, n.account, msg) - if err != nil { - return err - } - - var requestRes launchtypes.MsgSendRequestResponse - if err := res.Decode(&requestRes); err != nil { - return err - } - - if requestRes.AutoApproved { - n.ev.Send( - "Account added to the network by the coordinator!", - events.Icon(icons.Bullet), - events.ProgressFinish(), - ) - } else { - n.ev.Send( - fmt.Sprintf("Request %d to add account to the network has been submitted!", requestRes.RequestID), - events.Icon(icons.Bullet), - events.ProgressFinish(), - ) - } - return nil -} - -// SendValidatorRequest creates the RequestAddValidator message into the SPN. -func (n Network) SendValidatorRequest( - ctx context.Context, - launchID uint64, - peer launchtypes.Peer, - valAddress string, - gentx []byte, - gentxInfo cosmosutil.GentxInfo, -) error { - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - msg := launchtypes.NewMsgSendRequest( - addr, - launchID, - launchtypes.NewGenesisValidator( - launchID, - valAddress, - gentx, - gentxInfo.PubKey, - gentxInfo.SelfDelegation, - peer, - ), - ) - - n.ev.Send("Broadcasting validator transaction", events.ProgressStart()) - - res, err := n.cosmos.BroadcastTx(ctx, n.account, msg) - if err != nil { - return err - } - - var requestRes launchtypes.MsgSendRequestResponse - if err := res.Decode(&requestRes); err != nil { - return err - } - - if requestRes.AutoApproved { - n.ev.Send("Validator added to the network by the coordinator!", events.ProgressFinish()) - } else { - n.ev.Send( - fmt.Sprintf("Request %d to join the network as a validator has been submitted!", requestRes.RequestID), - events.ProgressFinish(), - ) - } - return nil -} - -// SendValidatorRemoveRequest creates the RequestRemoveValidator message to SPN. -func (n Network) SendValidatorRemoveRequest( - ctx context.Context, - launchID uint64, - valAddress string, -) error { - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - msg := launchtypes.NewMsgSendRequest( - addr, - launchID, - launchtypes.NewValidatorRemoval( - valAddress, - ), - ) - - n.ev.Send("Broadcasting transaction", events.ProgressStart()) - - res, err := n.cosmos.BroadcastTx(ctx, n.account, msg) - if err != nil { - return err - } - - var requestRes launchtypes.MsgSendRequestResponse - if err := res.Decode(&requestRes); err != nil { - return err - } - - if requestRes.AutoApproved { - n.ev.Send("Validator removed from network by the coordinator!", events.ProgressFinish()) - } else { - n.ev.Send( - fmt.Sprintf( - "Request %d to remove validator from the network has been submitted!", requestRes.RequestID, - ), - events.ProgressFinish(), - ) - } - return nil -} - -// SendAccountRemoveRequest creates the RequestRemoveAccount message to SPN. -func (n Network) SendAccountRemoveRequest( - ctx context.Context, - launchID uint64, - address string, -) error { - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - msg := launchtypes.NewMsgSendRequest( - addr, - launchID, - launchtypes.NewAccountRemoval( - address, - ), - ) - - n.ev.Send("Broadcasting transaction", events.ProgressStart()) - - res, err := n.cosmos.BroadcastTx(ctx, n.account, msg) - if err != nil { - return err - } - - var requestRes launchtypes.MsgSendRequestResponse - if err := res.Decode(&requestRes); err != nil { - return err - } - - if requestRes.AutoApproved { - n.ev.Send("Account removed from network by the coordinator!", events.ProgressFinish()) - } else { - n.ev.Send( - fmt.Sprintf( - "Request %d to remove account from the network has been submitted!", requestRes.RequestID, - ), - events.ProgressFinish(), - ) - } - return nil -} - -// SendParamChangeRequest creates the RequestParamChange message to SPN. -func (n Network) SendParamChangeRequest( - ctx context.Context, - launchID uint64, - module, - param string, - value []byte, -) error { - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - msg := launchtypes.NewMsgSendRequest( - addr, - launchID, - launchtypes.NewParamChange( - launchID, - module, - param, - value, - ), - ) - - n.ev.Send("Broadcasting transaction", events.ProgressStart()) - - res, err := n.cosmos.BroadcastTx(ctx, n.account, msg) - if err != nil { - return err - } - - var requestRes launchtypes.MsgSendRequestResponse - if err := res.Decode(&requestRes); err != nil { - return err - } - - if requestRes.AutoApproved { - n.ev.Send("Param changed on network by the coordinator!", events.ProgressFinish()) - } else { - n.ev.Send( - fmt.Sprintf( - "Request %d to change param on the network has been submitted!", requestRes.RequestID, - ), - events.ProgressFinish(), - ) - } - return nil -} diff --git a/ignite/services/network/request_test.go b/ignite/services/network/request_test.go deleted file mode 100644 index 3c6a134c04..0000000000 --- a/ignite/services/network/request_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package network - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - launchtypes "github.com/tendermint/spn/x/launch/types" - - "github.com/ignite/cli/ignite/services/network/networktypes" - "github.com/ignite/cli/ignite/services/network/testutil" -) - -func TestRequestParamChange(t *testing.T) { - t.Run("successfully send request", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - module = "module" - param = "param" - value = []byte("value") - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - launchtypes.NewMsgSendRequest( - addr, - testutil.LaunchID, - launchtypes.NewParamChange( - testutil.LaunchID, - module, - param, - value, - ), - ), - ). - Return(testutil.NewResponse(&launchtypes.MsgSendRequestResponse{ - RequestID: 0, - AutoApproved: false, - }), nil). - Once() - - sendRequestError := network.SendParamChangeRequest(context.Background(), testutil.LaunchID, module, param, value) - require.NoError(t, sendRequestError) - suite.AssertAllMocks(t) - }) -} diff --git a/ignite/services/network/reward.go b/ignite/services/network/reward.go deleted file mode 100644 index 24c34cd5b5..0000000000 --- a/ignite/services/network/reward.go +++ /dev/null @@ -1,102 +0,0 @@ -package network - -import ( - "context" - "errors" - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" - rewardtypes "github.com/tendermint/spn/x/reward/types" - - "github.com/ignite/cli/ignite/pkg/cliui/icons" - "github.com/ignite/cli/ignite/pkg/events" - "github.com/ignite/cli/ignite/services/network/networktypes" -) - -// SetReward set a chain reward. -func (n Network) SetReward(ctx context.Context, launchID uint64, lastRewardHeight int64, coins sdk.Coins) error { - n.ev.Send( - fmt.Sprintf("Setting reward %s to the chain %d at height %d", coins, launchID, lastRewardHeight), - events.ProgressStart(), - ) - - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - msg := rewardtypes.NewMsgSetRewards( - addr, - launchID, - lastRewardHeight, - coins, - ) - res, err := n.cosmos.BroadcastTx(ctx, n.account, msg) - if err != nil { - return err - } - - var setRewardRes rewardtypes.MsgSetRewardsResponse - if err := res.Decode(&setRewardRes); err != nil { - return err - } - - if setRewardRes.PreviousCoins.Empty() { - n.ev.Send("The reward pool was empty", events.Icon(icons.Info), events.ProgressFinish()) - } else { - n.ev.Send( - fmt.Sprintf("Previous reward pool %s at height %d is overwritten", coins, lastRewardHeight), - events.Icon(icons.Info), - events.ProgressFinish(), - ) - } - - if setRewardRes.NewCoins.Empty() { - n.ev.Send("The reward pool is removed", events.ProgressFinish()) - } else { - n.ev.Send( - fmt.Sprintf( - "%s will be distributed to validators at height %d. The chain %d is now an incentivized testnet", - coins, - lastRewardHeight, - launchID, - ), - events.ProgressFinish(), - ) - } - return nil -} - -// RewardsInfo Fetches the consensus state with the validator set, -// the unbounding time, and the last block height from chain rewards. -func (n Network) RewardsInfo( - ctx context.Context, - launchID uint64, - height int64, -) ( - rewardsInfo networktypes.Reward, - lastRewardHeight int64, - unboundingTime int64, - err error, -) { - rewardsInfo, err = n.node.consensus(ctx, n.cosmos, height) - if err != nil { - return rewardsInfo, 0, 0, err - } - - stakingParams, err := n.node.stakingParams(ctx) - if err != nil { - return rewardsInfo, 0, 0, err - } - unboundingTime = int64(stakingParams.UnbondingTime.Seconds()) - - chainReward, err := n.ChainReward(ctx, launchID) - if errors.Is(err, ErrObjectNotFound) { - return rewardsInfo, 1, unboundingTime, nil - } else if err != nil { - return rewardsInfo, 0, 0, err - } - lastRewardHeight = chainReward.LastRewardHeight - - return -} diff --git a/ignite/services/network/reward_test.go b/ignite/services/network/reward_test.go deleted file mode 100644 index c9d02c4838..0000000000 --- a/ignite/services/network/reward_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package network - -import ( - "context" - "errors" - "testing" - - sdkmath "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - rewardtypes "github.com/tendermint/spn/x/reward/types" - - "github.com/ignite/cli/ignite/services/network/networktypes" - "github.com/ignite/cli/ignite/services/network/testutil" -) - -func TestSetReward(t *testing.T) { - t.Run("successfully set reward", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - coins = sdk.NewCoins(sdk.NewCoin(TestDenom, sdkmath.NewInt(TestAmountInt))) - lastRewardHeight = int64(10) - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &rewardtypes.MsgSetRewards{ - Provider: addr, - LaunchID: testutil.LaunchID, - Coins: coins, - LastRewardHeight: lastRewardHeight, - }, - ). - Return(testutil.NewResponse(&rewardtypes.MsgSetRewardsResponse{ - PreviousCoins: nil, - PreviousLastRewardHeight: lastRewardHeight - 1, - NewCoins: coins, - NewLastRewardHeight: lastRewardHeight, - }), nil). - Once() - - setRewardError := network.SetReward(context.Background(), testutil.LaunchID, lastRewardHeight, coins) - require.NoError(t, setRewardError) - suite.AssertAllMocks(t) - }) - t.Run("failed to set reward, failed to broadcast set reward tx", func(t *testing.T) { - var ( - account = testutil.NewTestAccount(t, testutil.TestAccountName) - suite, network = newSuite(account) - coins = sdk.NewCoins(sdk.NewCoin(TestDenom, sdkmath.NewInt(TestAmountInt))) - lastRewardHeight = int64(10) - expectedErr = errors.New("failed to set reward") - ) - - addr, err := account.Address(networktypes.SPN) - require.NoError(t, err) - - suite.CosmosClientMock. - On( - "BroadcastTx", - context.Background(), - account, - &rewardtypes.MsgSetRewards{ - Provider: addr, - LaunchID: testutil.LaunchID, - Coins: coins, - LastRewardHeight: lastRewardHeight, - }, - ). - Return(testutil.NewResponse(&rewardtypes.MsgSetRewardsResponse{}), expectedErr). - Once() - setRewardError := network.SetReward(context.Background(), testutil.LaunchID, lastRewardHeight, coins) - require.Error(t, setRewardError) - require.Equal(t, expectedErr, setRewardError) - suite.AssertAllMocks(t) - }) -} diff --git a/ignite/services/network/share_percent.go b/ignite/services/network/share_percent.go deleted file mode 100644 index 44d9b553ac..0000000000 --- a/ignite/services/network/share_percent.go +++ /dev/null @@ -1,114 +0,0 @@ -package network - -import ( - "fmt" - "regexp" - "strconv" - "strings" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -type SharePercents []SharePercent - -func (sp SharePercents) Empty() bool { - return len(sp) == 0 -} - -var rePercentageRequired = regexp.MustCompile(`^[0-9]+.[0-9]*%`) - -// SharePercent represent percent of total share. -type SharePercent struct { - denom string - // in order to avoid using numbers with floating point - // fractional representation is used: 297/10000 instead of 2.97% - nominator, denominator uint64 -} - -// NewSharePercent creates new share percent representation. -func NewSharePercent(denom string, nominator, denominator uint64) (SharePercent, error) { - if denominator < nominator { - return SharePercent{}, fmt.Errorf("%q can not be bigger than 100", denom) - } - return SharePercent{ - denom: denom, - nominator: nominator, - denominator: denominator, - }, nil -} - -// Share returns coin share of total according to underlying percent. -func (p SharePercent) Share(total uint64) (sdk.Coin, error) { - resultNominator := total * p.nominator - if resultNominator%p.denominator != 0 { - err := fmt.Errorf("%s share from total %d is not integer: %f", - p.denom, - total, - float64(resultNominator)/float64(p.denominator), - ) - return sdk.Coin{}, err - } - return sdk.NewInt64Coin(p.denom, int64(resultNominator/p.denominator)), nil -} - -// SharePercentFromString parses share percent from string -// format: 11.87%foo -func SharePercentFromString(str string) (SharePercent, error) { - // validate raw percentage format - if len(rePercentageRequired.FindStringIndex(str)) == 0 { - return SharePercent{}, newInvalidPercentageFormat(str) - } - var ( - foo = strings.Split(str, "%") - fractional = strings.Split(foo[0], ".") - denom = foo[1] - ) - - switch len(fractional) { - case 1: - nominator, err := strconv.ParseUint(fractional[0], 10, 64) - if err != nil { - return SharePercent{}, newInvalidPercentageFormat(str) - } - return NewSharePercent(denom, nominator, 100) - case 2: - trimmedFractionalPart := strings.TrimRight(fractional[1], "0") - nominator, err := strconv.ParseUint(fractional[0]+trimmedFractionalPart, 10, 64) - if err != nil { - return SharePercent{}, newInvalidPercentageFormat(str) - } - return NewSharePercent(denom, nominator, uintPow(10, uint64(len(trimmedFractionalPart)+2))) - - default: - return SharePercent{}, newInvalidPercentageFormat(str) - } -} - -// ParseSharePercents parses SharePercentage list from string -// format: 12.4%foo,10%bar,0.133%baz -func ParseSharePercents(percents string) (SharePercents, error) { - rawPercentages := strings.Split(percents, ",") - ps := make([]SharePercent, len(rawPercentages)) - for i, percentage := range rawPercentages { - sp, err := SharePercentFromString(percentage) - if err != nil { - return nil, err - } - ps[i] = sp - - } - - return ps, nil -} - -func uintPow(x, y uint64) uint64 { - result := x - for i := 1; uint64(i) < y; i++ { - result *= x - } - return result -} - -func newInvalidPercentageFormat(s string) error { - return fmt.Errorf("invalid percentage format %s", s) -} diff --git a/ignite/services/network/share_percent_test.go b/ignite/services/network/share_percent_test.go deleted file mode 100644 index 616baec65d..0000000000 --- a/ignite/services/network/share_percent_test.go +++ /dev/null @@ -1,134 +0,0 @@ -package network_test - -import ( - "errors" - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - - "github.com/ignite/cli/ignite/services/network" -) - -func TestParseSharePercentages(t *testing.T) { - tests := []struct { - name string - shareStr string - want network.SharePercents - err error - }{ - { - name: "valid share percentage", - shareStr: "12.333%def", - want: network.SharePercents{ - network.SampleSharePercent(t, "def", 12333, 100000), - }, - }, - { - name: "valid share percentage", - shareStr: "0.333%def", - want: network.SharePercents{ - network.SampleSharePercent(t, "def", 333, 100000), - }, - }, - { - name: "extra zeroes", - shareStr: "12.33300%def", - want: network.SharePercents{ - network.SampleSharePercent(t, "def", 12333, 100000), - }, - }, - { - name: "100% percentage", - shareStr: "100%def", - want: network.SharePercents{ - network.SampleSharePercent(t, "def", 100, 100), - }, - }, - { - name: "valid share percentages", - shareStr: "12%def,10.3%abc", - want: network.SharePercents{ - network.SampleSharePercent(t, "def", 12, 100), - network.SampleSharePercent(t, "abc", 103, 1000), - }, - }, - { - name: "share percentages greater than 100", - shareStr: "12%def,10.3abc", - err: errors.New("invalid percentage format 10.3abc"), - }, - { - name: "share percentages without % sign", - shareStr: "12%def,103%abc", - err: errors.New("\"abc\" can not be bigger than 100"), - }, - { - name: "invalid percent", - shareStr: "12.3d3%def", - err: errors.New("invalid percentage format 12.3d3%def"), - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := network.ParseSharePercents(tt.shareStr) - if tt.err != nil { - require.Error(t, err) - require.Equal(t, tt.err.Error(), err.Error()) - return - } - require.NoError(t, err) - require.Equal(t, tt.want, result) - }) - } -} - -func TestShare(t *testing.T) { - tests := []struct { - name string - percent network.SharePercent - total uint64 - want sdk.Coin - err error - }{ - { - name: "100 fraction", - percent: network.SampleSharePercent(t, "foo", 10, 100), - total: 10000, - want: sdk.NewInt64Coin("foo", 1000), - }, - { - name: "1000 fraction", - percent: network.SampleSharePercent(t, "foo", 133, 1000), - total: 10000, - want: sdk.NewInt64Coin("foo", 1330), - }, - { - name: "10000 fraction", - percent: network.SampleSharePercent(t, "foo", 297, 10000), - total: 10000, - want: sdk.NewInt64Coin("foo", 297), - }, - { - name: "non integer share", - percent: network.SampleSharePercent(t, "foo", 297, 10001), - total: 10000, - want: sdk.NewInt64Coin("foo", 297), - err: errors.New("foo share from total 10000 is not integer: 296.970303"), - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.percent.Share(tt.total) - if tt.err != nil { - require.Error(t, err) - require.Equal(t, tt.err.Error(), err.Error()) - return - } - require.NoError(t, err) - require.Equal(t, tt.want, result) - }) - } -} diff --git a/ignite/services/network/testutil/account.go b/ignite/services/network/testutil/account.go deleted file mode 100644 index 6f62caf0b0..0000000000 --- a/ignite/services/network/testutil/account.go +++ /dev/null @@ -1,23 +0,0 @@ -package testutil - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/ignite/cli/ignite/pkg/cosmosaccount" -) - -const ( - TestAccountName = "test" -) - -// NewTestAccount creates an account for test purposes using in-memory keyring backend. -func NewTestAccount(t *testing.T, name string) cosmosaccount.Account { - t.Helper() - r, err := cosmosaccount.NewInMemory() - assert.NoError(t, err) - account, _, err := r.Create(name) - assert.NoError(t, err) - return account -} diff --git a/ignite/services/network/testutil/chain.go b/ignite/services/network/testutil/chain.go deleted file mode 100644 index 38da361f21..0000000000 --- a/ignite/services/network/testutil/chain.go +++ /dev/null @@ -1,18 +0,0 @@ -package testutil - -const ( - ChainSourceHash = "testhash" - ChainSourceURL = "http://example.com/test" - ChainConfigYML = "config.yml" - ChainName = "test" - ChainID = "test-1" - TCPAddress = "1.2.3.4" - NodeID = "9b1f4adbfb0c0b513040d914bfb717303c0eaa71" - PeerAddress = "9b1f4adbfb0c0b513040d914bfb717303c0eaa71@1.2.3.4" -) - -const ( - LaunchID = uint64(1) - ProjectID = uint64(1) - MainnetID = uint64(1) -) diff --git a/ignite/services/network/testutil/genesis.go b/ignite/services/network/testutil/genesis.go deleted file mode 100644 index 3173fdac1a..0000000000 --- a/ignite/services/network/testutil/genesis.go +++ /dev/null @@ -1,60 +0,0 @@ -package testutil - -import ( - "encoding/json" - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" -) - -type ( - Genesis struct { - ChainID string `json:"chain_id"` - AppState AppState `json:"app_state"` - } - - AppState struct { - Auth Auth `json:"auth"` - Staking Staking `json:"staking"` - } - - Auth struct { - Accounts []GenesisAccount `json:"accounts"` - } - - GenesisAccount struct { - Address string `json:"address"` - } - - Staking struct { - Params StakingParams `json:"params"` - } - - StakingParams struct { - BondDenom string `json:"bond_denom"` - } -) - -// NewGenesis creates easily modifiable genesis object for testing purposes. -func NewGenesis(chainID string) *Genesis { - return &Genesis{ChainID: chainID} -} - -// AddAccount adds account to the genesis. -func (g *Genesis) AddAccount(address string) *Genesis { - g.AppState.Auth.Accounts = append(g.AppState.Auth.Accounts, GenesisAccount{Address: address}) - return g -} - -// SaveTo saves genesis json representation to the specified directory and returns full path. -func (g *Genesis) SaveTo(t *testing.T, dir string) string { - t.Helper() - encoded, err := json.Marshal(g) - assert.NoError(t, err) - savePath := filepath.Join(dir, "genesis.json") - err = os.WriteFile(savePath, encoded, 0o666) - assert.NoError(t, err) - return savePath -} diff --git a/ignite/services/network/testutil/gentx.go b/ignite/services/network/testutil/gentx.go deleted file mode 100644 index d48633a600..0000000000 --- a/ignite/services/network/testutil/gentx.go +++ /dev/null @@ -1,70 +0,0 @@ -package testutil - -import ( - "encoding/json" - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" -) - -type ( - Gentx struct { - Body Body `json:"body"` - } - - Body struct { - Messages []Message `json:"messages"` - Memo string `json:"memo"` - } - - Message struct { - DelegatorAddress string `json:"delegator_address"` - ValidatorAddress string `json:"validator_address"` - PubKey MessagePubKey `json:"pubkey"` - Value MessageValue `json:"value"` - } - - MessageValue struct { - Denom string `json:"denom"` - Amount string `json:"amount"` - } - - MessagePubKey struct { - Key string `json:"key"` - } -) - -// NewGentx creates easily modifiable gentx object for testing purposes. -func NewGentx(address, denom, amount, pubkey, memo string) *Gentx { - return &Gentx{Body: Body{ - Memo: memo, - Messages: []Message{ - { - DelegatorAddress: address, - PubKey: MessagePubKey{Key: pubkey}, - Value: MessageValue{Denom: denom, Amount: amount}, - }, - }, - }} -} - -// SaveTo saves gentx json representation to the specified directory and returns full path. -func (g *Gentx) SaveTo(t *testing.T, dir string) string { - t.Helper() - encoded, err := json.Marshal(g) - assert.NoError(t, err) - savePath := filepath.Join(dir, "gentx0.json") - err = os.WriteFile(savePath, encoded, 0o666) - assert.NoError(t, err) - return savePath -} - -// JSON returns json representation of the gentx. -func (g *Gentx) JSON(t *testing.T) []byte { - t.Helper() - data, err := json.Marshal(g) - assert.NoError(t, err) - return data -} diff --git a/ignite/services/network/testutil/mocks.go b/ignite/services/network/testutil/mocks.go deleted file mode 100644 index 3ffc90bf25..0000000000 --- a/ignite/services/network/testutil/mocks.go +++ /dev/null @@ -1,46 +0,0 @@ -package testutil - -import ( - "github.com/cosmos/cosmos-sdk/crypto/keyring" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - campaigntypes "github.com/tendermint/spn/x/campaign/types" - launchtypes "github.com/tendermint/spn/x/launch/types" - profiletypes "github.com/tendermint/spn/x/profile/types" - rewardtypes "github.com/tendermint/spn/x/reward/types" -) - -//go:generate mockery --name CampaignClient --case underscore --output ../mocks -type CampaignClient interface { - campaigntypes.QueryClient -} - -//go:generate mockery --name ProfileClient --case underscore --output ../mocks -type ProfileClient interface { - profiletypes.QueryClient -} - -//go:generate mockery --name LaunchClient --case underscore --output ../mocks -type LaunchClient interface { - launchtypes.QueryClient -} - -//go:generate mockery --name RewardClient --case underscore --output ../mocks -type RewardClient interface { - rewardtypes.QueryClient -} - -//go:generate mockery --name BankClient --case underscore --output ../mocks -type BankClient interface { - banktypes.QueryClient -} - -//go:generate mockery --name StakingClient --case underscore --output ../mocks -type StakingClient interface { - stakingtypes.QueryClient -} - -//go:generate mockery --name AccountInfo --case underscore --output ../mocks -type AccountInfo interface { - keyring.Record -} diff --git a/ignite/services/network/testutil/response.go b/ignite/services/network/testutil/response.go deleted file mode 100644 index 8224db9b6f..0000000000 --- a/ignite/services/network/testutil/response.go +++ /dev/null @@ -1,30 +0,0 @@ -package testutil - -import ( - "encoding/hex" - - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "google.golang.org/protobuf/runtime/protoiface" - - "github.com/ignite/cli/ignite/pkg/cosmosclient" -) - -// NewResponse creates cosmosclient.Response object from proto struct -// for using as a return result for a cosmosclient mock. -func NewResponse(data protoiface.MessageV1) cosmosclient.Response { - marshaler := codec.NewProtoCodec(codectypes.NewInterfaceRegistry()) - anyEncoded, _ := codectypes.NewAnyWithValue(data) - - txData := &sdk.TxMsgData{MsgResponses: []*codectypes.Any{anyEncoded}} - - encodedTxData, _ := marshaler.Marshal(txData) - resp := cosmosclient.Response{ - Codec: marshaler, - TxResponse: &sdk.TxResponse{ - Data: hex.EncodeToString(encodedTxData), - }, - } - return resp -} diff --git a/ignite/services/network/testutil/suite.go b/ignite/services/network/testutil/suite.go deleted file mode 100644 index 1c60448568..0000000000 --- a/ignite/services/network/testutil/suite.go +++ /dev/null @@ -1,53 +0,0 @@ -package testutil - -import ( - "testing" - - "github.com/cosmos/cosmos-sdk/client" - - "github.com/ignite/cli/ignite/services/network/mocks" -) - -// Suite is a mocks container, used to write less code for tests setup. -type Suite struct { - ChainMock *mocks.Chain - CosmosClientMock *mocks.CosmosClient - LaunchQueryMock *mocks.LaunchClient - CampaignQueryMock *mocks.CampaignClient - ProfileQueryMock *mocks.ProfileClient - RewardClient *mocks.RewardClient - StakingClient *mocks.StakingClient - BankClient *mocks.BankClient - MonitoringConsumerClient *mocks.MonitoringcClient -} - -// AssertAllMocks asserts all suite mocks expectations. -func (s *Suite) AssertAllMocks(t *testing.T) { - t.Helper() - s.ChainMock.AssertExpectations(t) - s.ProfileQueryMock.AssertExpectations(t) - s.LaunchQueryMock.AssertExpectations(t) - s.CosmosClientMock.AssertExpectations(t) - s.CampaignQueryMock.AssertExpectations(t) - s.RewardClient.AssertExpectations(t) - s.StakingClient.AssertExpectations(t) - s.MonitoringConsumerClient.AssertExpectations(t) - s.BankClient.AssertExpectations(t) -} - -// NewSuite creates new suite with mocks. -func NewSuite() Suite { - cosmos := new(mocks.CosmosClient) - cosmos.On("Context").Return(client.Context{}) - return Suite{ - ChainMock: new(mocks.Chain), - CosmosClientMock: cosmos, - LaunchQueryMock: new(mocks.LaunchClient), - CampaignQueryMock: new(mocks.CampaignClient), - ProfileQueryMock: new(mocks.ProfileClient), - RewardClient: new(mocks.RewardClient), - StakingClient: new(mocks.StakingClient), - BankClient: new(mocks.BankClient), - MonitoringConsumerClient: new(mocks.MonitoringcClient), - } -} diff --git a/ignite/services/plugin/interface.go b/ignite/services/plugin/interface.go index e47c357fa4..86dba9d1ee 100644 --- a/ignite/services/plugin/interface.go +++ b/ignite/services/plugin/interface.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/hashicorp/go-plugin" + "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -74,10 +75,32 @@ type Manifest struct { SharedHost bool `yaml:"shared_host"` } +// ImportCobraCommand allows to hydrate m with a standard root cobra commands. +func (m *Manifest) ImportCobraCommand(c *cobra.Command, placeCommandUnder string) { + m.Commands = append(m.Commands, convertCobraCommand(c, placeCommandUnder)) +} + +func convertCobraCommand(c *cobra.Command, placeCommandUnder string) Command { + cmd := Command{ + Use: c.Use, + Aliases: c.Aliases, + Short: c.Short, + Long: c.Long, + PlaceCommandUnder: placeCommandUnder, + Flags: convertPFlags(c), + } + for _, c := range c.Commands() { + cmd.Commands = append(cmd.Commands, convertCobraCommand(c, "")) + } + return cmd +} + // Command represents a plugin command. type Command struct { // Same as cobra.Command.Use Use string + // Same as cobra.Command.Aliases + Aliases []string // Same as cobra.Command.Short Short string // Same as cobra.Command.Long @@ -93,6 +116,24 @@ type Command struct { Commands []Command } +// ToCobraCommand turns Command into a cobra.Command so it can be added to a +// parent command. +func (c Command) ToCobraCommand() (*cobra.Command, error) { + cmd := &cobra.Command{ + Use: c.Use, + Aliases: c.Aliases, + Short: c.Short, + Long: c.Long, + } + for _, f := range c.Flags { + err := f.feedFlagSet(cmd) + if err != nil { + return nil, err + } + } + return cmd, nil +} + // Hook represents a user defined action within a plugin. type Hook struct { // Name identifies the hook for the client to invoke the correct hook @@ -110,10 +151,13 @@ type ExecutedCommand struct { Path string // Args are the command arguments Args []string + // Full list of args taken from os.Args + OSArgs []string // With contains the plugin config parameters With map[string]string - flags *pflag.FlagSet + flags *pflag.FlagSet + pflags *pflag.FlagSet } // ExecutedHook represents a plugin hook under execution. @@ -132,13 +176,23 @@ func (c *ExecutedCommand) Flags() *pflag.FlagSet { return c.flags } +// PersistentFlags gives access to the commands' persistent flags, like +// cobra.Command.PersistentFlags. +func (c *ExecutedCommand) PersistentFlags() *pflag.FlagSet { + if c.pflags == nil { + c.pflags = pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError) + } + return c.pflags +} + // SetFlags set the flags. // As a plugin developer, you probably don't need to use it. -func (c *ExecutedCommand) SetFlags(fs *pflag.FlagSet) { - c.flags = fs +func (c *ExecutedCommand) SetFlags(cmd *cobra.Command) { + c.flags = cmd.Flags() + c.pflags = cmd.PersistentFlags() } -// Flag is a exportable representation of pflag.Flag. +// Flag is a serializable representation of pflag.Flag. type Flag struct { Name string // name as it appears on command line Shorthand string // one-letter abbreviated flag @@ -146,7 +200,9 @@ type Flag struct { DefValue string // default value (as text); for usage message Type FlagType Value string - // TODO add Persistent field ? + // Persistent indicates wether or not the flag is propagated on children + // commands + Persistent bool } // FlagType represents the pflag.Flag.Value.Type(). @@ -164,9 +220,12 @@ const ( FlagTypeStringSlice FlagType = "stringSlice" ) -// FeedFlagSet fills fs with f. -// As a plugin developer, you probably don't need to use it. -func (f Flag) FeedFlagSet(fs *pflag.FlagSet) error { +// feedFlagSet fills flagger with f. +func (f Flag) feedFlagSet(fgr flagger) error { + fs := fgr.Flags() + if f.Persistent { + fs = fgr.PersistentFlags() + } switch f.Type { case FlagTypeBool: defVal, _ := strconv.ParseBool(f.DefValue) @@ -212,14 +271,31 @@ type gobCommandContextFlags struct { Flags []Flag } +// gobCommandContext is the same as ExecutedCommand but without GobDecode +// attached, which avoids infinite loops. type gobCommandContext ExecutedCommand // GobEncode implements gob.Encoder. // It actually encodes a gobCommandContext struct built from c. func (c ExecutedCommand) GobEncode() ([]byte, error) { + var b bytes.Buffer + err := gob.NewEncoder(&b).Encode(gobCommandContextFlags{ + CommandContext: gobCommandContext(c), + Flags: convertPFlags(&c), + }) + return b.Bytes(), err +} + +// flagger matches both cobra.Command and Command. +type flagger interface { + Flags() *pflag.FlagSet + PersistentFlags() *pflag.FlagSet +} + +func convertPFlags(fgr flagger) []Flag { var ff []Flag - if c.flags != nil { - c.flags.VisitAll(func(pf *pflag.Flag) { + if fgr.Flags() != nil { + fgr.Flags().VisitAll(func(pf *pflag.Flag) { ff = append(ff, Flag{ Name: pf.Name, Shorthand: pf.Shorthand, @@ -230,12 +306,20 @@ func (c ExecutedCommand) GobEncode() ([]byte, error) { }) }) } - var b bytes.Buffer - err := gob.NewEncoder(&b).Encode(gobCommandContextFlags{ - CommandContext: gobCommandContext(c), - Flags: ff, - }) - return b.Bytes(), err + if fgr.PersistentFlags() != nil { + fgr.PersistentFlags().VisitAll(func(pf *pflag.Flag) { + ff = append(ff, Flag{ + Name: pf.Name, + Shorthand: pf.Shorthand, + Usage: pf.Usage, + DefValue: pf.DefValue, + Value: pf.Value.String(), + Type: FlagType(pf.Value.Type()), + Persistent: true, + }) + }) + } + return ff } // GobDecode implements gob.Decoder. @@ -248,7 +332,7 @@ func (c *ExecutedCommand) GobDecode(bz []byte) error { } *c = ExecutedCommand(gb.CommandContext) for _, f := range gb.Flags { - err := f.FeedFlagSet(c.Flags()) + err := f.feedFlagSet(c) if err != nil { return err } diff --git a/ignite/services/plugin/interface_test.go b/ignite/services/plugin/interface_test.go new file mode 100644 index 0000000000..6dd9fb1c0c --- /dev/null +++ b/ignite/services/plugin/interface_test.go @@ -0,0 +1,165 @@ +package plugin_test + +import ( + "testing" + + "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/ignite/cli/ignite/services/plugin" +) + +func TestCommandToCobraCommand(t *testing.T) { + var ( + require = require.New(t) + assert = assert.New(t) + pcmd = plugin.Command{ + Use: "new", + Aliases: []string{"n"}, + Short: "short", + Long: "long", + Flags: []plugin.Flag{ + { + Name: "bool", + Shorthand: "b", + DefValue: "true", + Value: "true", + Usage: "a bool", + Type: plugin.FlagTypeBool, + }, + { + Name: "string", + DefValue: "hello", + Value: "hello", + Usage: "a string", + Type: plugin.FlagTypeString, + Persistent: true, + }, + }, + Commands: []plugin.Command{ + { + Use: "sub", + Aliases: []string{"s"}, + Short: "sub short", + Long: "sub long", + }, + }, + } + ) + + cmd, err := pcmd.ToCobraCommand() + + require.NoError(err) + require.NotNil(cmd) + assert.Empty(cmd.Commands()) // subcommands aren't converted + assert.Equal(pcmd.Use, cmd.Use) + assert.Equal(pcmd.Short, cmd.Short) + assert.Equal(pcmd.Long, cmd.Long) + assert.Equal(pcmd.Aliases, cmd.Aliases) + for _, f := range pcmd.Flags { + if f.Persistent { + assert.NotNil(cmd.PersistentFlags().Lookup(f.Name), "missing pflag %s", f.Name) + } else { + assert.NotNil(cmd.Flags().Lookup(f.Name), "missing flag %s", f.Name) + } + } +} + +func TestManifestImportCobraCommand(t *testing.T) { + manifest := plugin.Manifest{ + Name: "hey", + Commands: []plugin.Command{ + {Use: "existing"}, + }, + } + cmd := &cobra.Command{ + Use: "new", + Aliases: []string{"n"}, + Short: "short", + Long: "long", + } + cmd.Flags().BoolP("bool", "b", true, "a bool") + cmd.Flags().String("string", "hello", "a string") + cmd.PersistentFlags().String("persistent", "hello", "a persistent string") + subcmd := &cobra.Command{ + Use: "sub", + Aliases: []string{"s"}, + Short: "sub short", + Long: "sub long", + } + subcmd.Flags().BoolP("subbool", "b", true, "a bool") + subcmd.Flags().String("substring", "hello", "a string") + subcmd.AddCommand(&cobra.Command{ + Use: "subsub", + }) + cmd.AddCommand(subcmd) + + manifest.ImportCobraCommand(cmd, "under") + + expectedManifest := plugin.Manifest{ + Name: "hey", + Commands: []plugin.Command{ + {Use: "existing"}, + { + Use: "new", + Aliases: []string{"n"}, + Short: "short", + Long: "long", + PlaceCommandUnder: "under", + Flags: []plugin.Flag{ + { + Name: "bool", + Shorthand: "b", + DefValue: "true", + Value: "true", + Usage: "a bool", + Type: plugin.FlagTypeBool, + }, + { + Name: "string", + DefValue: "hello", + Value: "hello", + Usage: "a string", + Type: plugin.FlagTypeString, + }, + { + Name: "persistent", + DefValue: "hello", + Value: "hello", + Usage: "a persistent string", + Type: plugin.FlagTypeString, + Persistent: true, + }, + }, + Commands: []plugin.Command{ + { + Use: "sub", + Aliases: []string{"s"}, + Short: "sub short", + Long: "sub long", + Flags: []plugin.Flag{ + { + Name: "subbool", + Shorthand: "b", + DefValue: "true", + Value: "true", + Usage: "a bool", + Type: plugin.FlagTypeBool, + }, + { + Name: "substring", + DefValue: "hello", + Value: "hello", + Usage: "a string", + Type: plugin.FlagTypeString, + }, + }, + Commands: []plugin.Command{{Use: "subsub"}}, + }, + }, + }, + }, + } + assert.Equal(t, expectedManifest, manifest) +} diff --git a/ignite/services/plugin/plugin.go b/ignite/services/plugin/plugin.go index d1ced5a970..46b2ccb69d 100644 --- a/ignite/services/plugin/plugin.go +++ b/ignite/services/plugin/plugin.go @@ -186,15 +186,6 @@ func (p *Plugin) KillClient() { } } -// IsGlobal returns whether the plugin is installed globally or locally for a chain. -func (p *Plugin) IsGlobal() bool { - return p.Plugin.Global -} - -func (p *Plugin) isLocal() bool { - return p.cloneURL == "" -} - func (p *Plugin) binaryPath() string { return path.Join(p.srcPath, p.binaryName) } @@ -213,7 +204,7 @@ func (p *Plugin) load(ctx context.Context) { } } - if p.isLocal() { + if p.IsLocalPath() { // trigger rebuild for local plugin if binary is outdated if p.outdatedBinary() { p.build(ctx) @@ -315,7 +306,7 @@ func (p *Plugin) load(ctx context.Context) { // fetch clones the plugin repository at the expected reference. func (p *Plugin) fetch() { - if p.isLocal() { + if p.IsLocalPath() { return } if p.Error != nil { @@ -346,7 +337,7 @@ func (p *Plugin) build(ctx context.Context) { p.Error = errors.Wrapf(err, "go mod tidy") return } - if err := gocmd.BuildAll(ctx, p.binaryName, p.srcPath, nil); err != nil { + if err := gocmd.Build(ctx, p.binaryName, p.srcPath, nil); err != nil { p.Error = errors.Wrapf(err, "go build") return } @@ -358,7 +349,7 @@ func (p *Plugin) clean() error { // Dont try to clean plugins with error return nil } - if p.isLocal() { + if p.IsLocalPath() { // Not a remote plugin, nothing to clean return nil } diff --git a/ignite/services/plugin/plugin_test.go b/ignite/services/plugin/plugin_test.go index b92328dbea..1b056cb2cf 100644 --- a/ignite/services/plugin/plugin_test.go +++ b/ignite/services/plugin/plugin_test.go @@ -182,14 +182,13 @@ func TestPluginLoad(t *testing.T) { binaryName: "testdata", } }, - expectedError: `no packages to build`, + expectedError: `no Go files in`, }, { name: "ok: from local", buildPlugin: func(t *testing.T) Plugin { path := scaffoldPlugin(t, t.TempDir(), "github.com/foo/bar", false) return Plugin{ - Plugin: pluginsconfig.Plugin{Path: path}, srcPath: path, binaryName: "bar", } @@ -202,7 +201,6 @@ func TestPluginLoad(t *testing.T) { cloneDir := t.TempDir() return Plugin{ - Plugin: pluginsconfig.Plugin{Path: path.Join(cloneDir, "remote")}, cloneURL: repoDir, cloneDir: cloneDir, srcPath: path.Join(cloneDir, "remote"), @@ -216,7 +214,6 @@ func TestPluginLoad(t *testing.T) { cloneDir := t.TempDir() return Plugin{ - Plugin: pluginsconfig.Plugin{Path: path.Join(cloneDir, "plugin")}, repoPath: "/xxxx/yyyy", cloneURL: "/xxxx/yyyy", cloneDir: cloneDir, @@ -240,7 +237,6 @@ func TestPluginLoad(t *testing.T) { cloneDir := t.TempDir() return Plugin{ - Plugin: pluginsconfig.Plugin{Path: path.Join(cloneDir, "remote-tag")}, cloneURL: repoDir, reference: "v1", cloneDir: cloneDir, @@ -264,7 +260,6 @@ func TestPluginLoad(t *testing.T) { cloneDir := t.TempDir() return Plugin{ - Plugin: pluginsconfig.Plugin{Path: path.Join(cloneDir, "remote-branch")}, cloneURL: repoDir, reference: "branch1", cloneDir: cloneDir, @@ -283,7 +278,6 @@ func TestPluginLoad(t *testing.T) { cloneDir := t.TempDir() return Plugin{ - Plugin: pluginsconfig.Plugin{Path: path.Join(cloneDir, "remote-branch")}, cloneURL: repoDir, reference: h.Hash().String(), cloneDir: cloneDir, @@ -300,7 +294,6 @@ func TestPluginLoad(t *testing.T) { cloneDir := t.TempDir() return Plugin{ - Plugin: pluginsconfig.Plugin{Path: path.Join(cloneDir, "remote-no-ref")}, cloneURL: repoDir, reference: "doesnt_exists", cloneDir: cloneDir, diff --git a/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush b/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush index a29f9c3857..e4b8051092 100644 --- a/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush +++ b/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush @@ -26,7 +26,6 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - "github.com/ignite/cli/ignite/services/network" "github.com/spf13/cast" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -141,7 +140,6 @@ func initRootCmd( queryCommand(), txCommand(), keys.Commands(app.DefaultNodeHome), - startWithTunnelingCommand(a, app.DefaultNodeHome), ) } @@ -197,29 +195,6 @@ func txCommand() *cobra.Command { return cmd } -// startWithTunnelingCommand returns a new start command with http tunneling -// enabled. -func startWithTunnelingCommand(appCreator appCreator, defaultNodeHome string) *cobra.Command { - startCmd := server.StartCmd(appCreator.newApp, defaultNodeHome) - startCmd.Use = "start-with-http-tunneling" - startCmd.Short = "Run the full node with http tunneling" - // Backup existing PreRunE, since we'll override it. - startPreRunE := startCmd.PreRunE - startCmd.PreRunE = func(cmd *cobra.Command, args []string) error { - var ( - ctx = cmd.Context() - clientCtx = client.GetClientContextFromCmd(cmd) - serverCtx = server.GetServerContextFromCmd(cmd) - ) - network.StartProxyForTunneledPeers(ctx, clientCtx, serverCtx) - if startPreRunE == nil { - return nil - } - return startPreRunE(cmd, args) - } - return startCmd -} - func addModuleInitFlags(startCmd *cobra.Command) { crisis.AddModuleInitFlags(startCmd) // this line is used by starport scaffolding # root/arguments @@ -302,7 +277,7 @@ func (a appCreator) newApp( baseapp.SetTrace(cast.ToBool(appOpts.Get(server.FlagTrace))), baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(server.FlagIndexEvents))), baseapp.SetSnapshot(snapshotStore, snapshotOptions), - baseapp.SetIAVLCacheSize(cast.ToInt(appOpts.Get(server.FlagIAVLCacheSize))), + baseapp.SetIAVLCacheSize(cast.ToInt(appOpts.Get(server.FlagIAVLCacheSize))), baseapp.SetIAVLDisableFastNode(cast.ToBool(appOpts.Get(server.FlagDisableIAVLFastNode))), ) } diff --git a/integration/env.go b/integration/env.go index f653bbdbd5..95b241bdfa 100644 --- a/integration/env.go +++ b/integration/env.go @@ -110,7 +110,7 @@ func (e Env) IsAppServed(ctx context.Context, apiAddr string) error { ok, err := httpstatuschecker.Check(ctx, fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/node_info", addr)) if err == nil && !ok { - err = errors.New("app is not online") + err = errors.New("waiting for app") } if HasTestVerboseFlag() { fmt.Printf("IsAppServed at %s: %v\n", addr, err) diff --git a/integration/network/network_test.go b/integration/network/network_test.go index 23e5a5523d..45f45ac4fa 100644 --- a/integration/network/network_test.go +++ b/integration/network/network_test.go @@ -14,30 +14,53 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/stretchr/testify/require" + ignitecmd "github.com/ignite/cli/ignite/cmd" chainconfig "github.com/ignite/cli/ignite/config/chain" "github.com/ignite/cli/ignite/pkg/cmdrunner/step" "github.com/ignite/cli/ignite/pkg/gomodule" + "github.com/ignite/cli/ignite/pkg/xgit" envtest "github.com/ignite/cli/integration" ) const ( - spnModule = "github.com/tendermint/spn" - spnRepoURL = "https://" + spnModule - spnConfigFile = "config_2.yml" + spnModule = "github.com/tendermint/spn" + spnRepoURL = "https://" + spnModule + spnConfigFile = "config_2.yml" + pluginNetworkRepoURL = "https://" + ignitecmd.PluginNetworkPath ) -func cloneSPN(t *testing.T) string { - path := t.TempDir() - repo, err := git.PlainClone(path, false, &git.CloneOptions{ - URL: spnRepoURL, - Progress: os.Stdout, - }) - require.NoError(t, err) - - // Read spn version from go.mod - gm, err := gomodule.ParseAt("../..") - require.NoError(t, err) - var spnVersion string +// setupSPN executes the following tasks: +// - clone cli-plugin-network to get the SPN version from go.mod +// - add the cloned cli-plugin-network as a global plugin +// - clone SPN to the expected version +// - returns the path of the cloned SPN. +func setupSPN(env envtest.Env) string { + var ( + t = env.T() + require = require.New(t) + path = t.TempDir() + pluginPath = filepath.Join(path, "cli-plugin-network") + spnPath = filepath.Join(path, "spn") + spnVersion string + ) + // Clone the cli-plugin-network with the expected version + err := xgit.Clone(context.Background(), pluginNetworkRepoURL, pluginPath) + require.NoError(err) + t.Logf("Checkout cli-plugin-revision to ref %q", ignitecmd.PluginNetworkPath) + // Add plugin to config + env.Must(env.Exec("add plugin network", + step.NewSteps(step.New( + // NOTE(tb): to test cli-plugin-network locally (can happen during dev) + // comment the first line below and uncomment the second, with the + // correct path to the plugin. + step.Exec(envtest.IgniteApp, "plugin", "add", "-g", pluginPath), + // step.Exec(envtest.IgniteApp, "plugin", "add", "-g", "/home/tom/src/ignite/cli-plugin-network"), + )), + )) + + // Read spn version from plugin's go.mod + gm, err := gomodule.ParseAt(pluginPath) + require.NoError(err) for _, r := range gm.Require { if r.Mod.Path == spnModule { spnVersion = r.Mod.Version @@ -51,22 +74,29 @@ func cloneSPN(t *testing.T) string { // Check if spnVersion is a tag or a pseudo-version v, err := semver.ParseTolerant(spnVersion) - require.NoError(t, err) + require.NoError(err) if n := len(v.Pre); n > 0 { // pseudo version, need to extract hash spnVersion = strings.Split(v.Pre[n-1].VersionStr, "-")[1] } - rev, err := repo.ResolveRevision(plumbing.Revision(spnVersion)) - require.NoError(t, err) - w, err := repo.Worktree() - require.NoError(t, err) + + // Clone spn + spnRepo, err := git.PlainClone(spnPath, false, &git.CloneOptions{ + URL: spnRepoURL, + }) + require.NoError(err) + // Checkout expected version + rev, err := spnRepo.ResolveRevision(plumbing.Revision(spnVersion)) + require.NoError(err, spnVersion) + w, err := spnRepo.Worktree() + require.NoError(err) err = w.Checkout(&git.CheckoutOptions{ Hash: *rev, }) - require.NoError(t, err) + require.NoError(err, rev) t.Logf("Checkout spn to ref %q", rev) - return path + return spnPath } func migrateSPNConfig(t *testing.T, spnPath string) { @@ -91,8 +121,8 @@ func migrateSPNConfig(t *testing.T, spnPath string) { func TestNetworkPublish(t *testing.T) { var ( - spnPath = cloneSPN(t) env = envtest.New(t) + spnPath = setupSPN(env) spn = env.App( spnPath, envtest.AppHomePath(t.TempDir()), @@ -145,8 +175,8 @@ func TestNetworkPublish(t *testing.T) { func TestNetworkPublishGenesisConfig(t *testing.T) { var ( - spnPath = cloneSPN(t) env = envtest.New(t) + spnPath = setupSPN(env) spn = env.App( spnPath, envtest.AppHomePath(t.TempDir()), diff --git a/integration/network/request_test.go b/integration/network/request_test.go index b1057fd91c..f7abf73261 100644 --- a/integration/network/request_test.go +++ b/integration/network/request_test.go @@ -14,8 +14,8 @@ import ( func TestNetworkRequestParam(t *testing.T) { var ( - spnPath = cloneSPN(t) env = envtest.New(t) + spnPath = setupSPN(env) spn = env.App( spnPath, envtest.AppHomePath(t.TempDir()),