From 47493692c55b18f84bac67ed7b2c58fbda0fbca3 Mon Sep 17 00:00:00 2001 From: Hariom Verma Date: Mon, 6 Nov 2023 22:07:47 +0530 Subject: [PATCH 01/25] feat: implement `gno mod tidy` (#1035) Contains initial implementation of `gno mod tidy`
Contributors' checklist... - [ ] Added new tests, or not needed, or not feasible - [ ] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [ ] Updated the official documentation or not needed - [ ] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [ ] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--------- Co-authored-by: Manfred Touron <94029+moul@users.noreply.github.com> Co-authored-by: Morgan --- .github/workflows/examples.yml | 19 ++ examples/Makefile | 4 + examples/gno.land/p/demo/acl/gno.mod | 4 +- examples/gno.land/p/demo/blog/gno.mod | 6 +- examples/gno.land/p/demo/dom/gno.mod | 4 +- examples/gno.land/p/demo/flow/gno.mod | 2 +- examples/gno.land/p/demo/gnode/gno.mod | 2 +- .../gno.land/p/demo/grc/exts/vault/gno.mod | 4 +- examples/gno.land/p/demo/grc/grc1155/gno.mod | 6 +- examples/gno.land/p/demo/grc/grc20/gno.mod | 6 +- examples/gno.land/p/demo/grc/grc721/gno.mod | 6 +- examples/gno.land/p/demo/grc/grc777/gno.mod | 4 +- examples/gno.land/p/demo/groups/gno.mod | 5 +- .../gno.land/p/demo/math_eval/int32/gno.mod | 4 +- examples/gno.land/p/demo/microblog/gno.mod | 7 +- examples/gno.land/p/demo/mux/gno.mod | 2 +- examples/gno.land/p/demo/rand/gno.mod | 2 +- examples/gno.land/p/demo/svg/gno.mod | 4 +- examples/gno.land/p/demo/tests/gno.mod | 4 +- .../gno.land/p/demo/tests/subtests/gno.mod | 2 +- examples/gno.land/p/demo/ui/gno.mod | 2 +- examples/gno.land/r/demo/art/gnoface/gno.mod | 4 +- .../gno.land/r/demo/art/millipede/gno.mod | 4 +- examples/gno.land/r/demo/boards/gno.mod | 4 +- examples/gno.land/r/demo/foo1155/gno.mod | 6 +- examples/gno.land/r/demo/foo20/gno.mod | 6 +- examples/gno.land/r/demo/foo721/gno.mod | 6 +- examples/gno.land/r/demo/groups/gno.mod | 4 +- examples/gno.land/r/demo/keystore/gno.mod | 5 +- examples/gno.land/r/demo/math_eval/gno.mod | 4 +- examples/gno.land/r/demo/microblog/gno.mod | 4 +- examples/gno.land/r/demo/nft/gno.mod | 4 +- .../gno.land/r/demo/releases_example/gno.mod | 4 +- examples/gno.land/r/demo/tests/gno.mod | 4 +- .../gno.land/r/demo/tests/subtests/gno.mod | 2 +- examples/gno.land/r/demo/tests_foo/gno.mod | 4 +- examples/gno.land/r/demo/types/gno.mod | 4 +- examples/gno.land/r/demo/ui/gno.mod | 4 +- examples/gno.land/r/demo/users/gno.mod | 5 +- examples/gno.land/r/gnoland/blog/gno.mod | 4 +- examples/gno.land/r/gnoland/faucet/gno.mod | 6 +- examples/gno.land/r/gnoland/pages/gno.mod | 4 +- examples/gno.land/r/system/names/gno.mod | 4 +- examples/gno.land/r/x/manfred_outfmt/gno.mod | 4 +- gnovm/cmd/gno/mod.go | 105 +++++++++++ gnovm/cmd/gno/mod_test.go | 173 +++++++++++++++++- gnovm/pkg/doc/dirs.go | 31 +--- gnovm/pkg/gnomod/parse.go | 28 +++ gnovm/pkg/gnomod/parse_test.go | 57 ++++++ gnovm/tests/integ/invalid-gno-file/gno.mod | 1 + .../tests/integ/invalid-gno-file/invalid.gno | 1 + gnovm/tests/integ/valid2/gno.mod | 3 + gnovm/tests/integ/valid2/valid.gno | 11 ++ gnovm/tests/integ/valid2/valid_test.gno | 11 ++ gnovm/tests/integ/valid2/z_0_filetest.gno | 1 + 55 files changed, 488 insertions(+), 133 deletions(-) create mode 100644 gnovm/tests/integ/invalid-gno-file/gno.mod create mode 100644 gnovm/tests/integ/invalid-gno-file/invalid.gno create mode 100644 gnovm/tests/integ/valid2/gno.mod create mode 100644 gnovm/tests/integ/valid2/valid.gno create mode 100644 gnovm/tests/integ/valid2/valid_test.gno create mode 100644 gnovm/tests/integ/valid2/z_0_filetest.gno diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index b17c66d8e5a..d52ed5c0ba6 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -73,3 +73,22 @@ jobs: - run: go run ./gnovm/cmd/gno lint --verbose ./examples/gno.land/r/gnoland - run: go run ./gnovm/cmd/gno lint --verbose ./examples/gno.land/r/system # TODO: track coverage + mod-tidy: + strategy: + fail-fast: false + matrix: + go-version: [ "1.21.x" ] + # unittests: TODO: matrix with contracts + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/setup-go@v4 + with: + go-version: ${{ matrix.go-version }} + - uses: actions/checkout@v3 + - run: | + GNO_CMD="$(pwd)/gnovm/cmd/gno" + # Find all directories containing gno.mod file + find ./examples -name "gno.mod" -execdir go run "$GNO_CMD" mod tidy \; + # Check if there are changes after running gno mod tidy + git diff --exit-code || (echo "Some gno.mod files are not tidy, please run 'make tidy'." && exit 1) diff --git a/examples/Makefile b/examples/Makefile index f20072d9df2..9b628e01ce5 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -37,3 +37,7 @@ clean: GOFMT_FLAGS ?= -w fmt: go run -modfile ../misc/devdeps/go.mod mvdan.cc/gofumpt $(GOFMT_FLAGS) `find . -name "*.gno"` + +.PHONY: tidy +tidy: + find . -name "gno.mod" -execdir go run github.com/gnolang/gno/gnovm/cmd/gno mod tidy \; diff --git a/examples/gno.land/p/demo/acl/gno.mod b/examples/gno.land/p/demo/acl/gno.mod index 2aabe3a5645..176cde637bd 100644 --- a/examples/gno.land/p/demo/acl/gno.mod +++ b/examples/gno.land/p/demo/acl/gno.mod @@ -1,6 +1,6 @@ module gno.land/p/demo/acl require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/p/demo/testutils" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/testutils v0.0.0-latest ) diff --git a/examples/gno.land/p/demo/blog/gno.mod b/examples/gno.land/p/demo/blog/gno.mod index c8437af1732..65f58e7a0f6 100644 --- a/examples/gno.land/p/demo/blog/gno.mod +++ b/examples/gno.land/p/demo/blog/gno.mod @@ -1,7 +1,7 @@ module gno.land/p/demo/blog require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/p/demo/ufmt" v0.0.0-latest - "gno.land/p/demo/mux" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/mux v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest ) diff --git a/examples/gno.land/p/demo/dom/gno.mod b/examples/gno.land/p/demo/dom/gno.mod index e7d0e5a9e75..83ca827cf66 100644 --- a/examples/gno.land/p/demo/dom/gno.mod +++ b/examples/gno.land/p/demo/dom/gno.mod @@ -1,5 +1,3 @@ module gno.land/p/demo/dom -require ( - "gno.land/p/demo/avl" v0.0.0-latest -) +require gno.land/p/demo/avl v0.0.0-latest diff --git a/examples/gno.land/p/demo/flow/gno.mod b/examples/gno.land/p/demo/flow/gno.mod index 4a4d4fb4d82..5adddbfe021 100644 --- a/examples/gno.land/p/demo/flow/gno.mod +++ b/examples/gno.land/p/demo/flow/gno.mod @@ -1 +1 @@ -module "gno.land/p/demo/flow" +module gno.land/p/demo/flow diff --git a/examples/gno.land/p/demo/gnode/gno.mod b/examples/gno.land/p/demo/gnode/gno.mod index e922821f7fd..a93c2051830 100644 --- a/examples/gno.land/p/demo/gnode/gno.mod +++ b/examples/gno.land/p/demo/gnode/gno.mod @@ -1 +1 @@ -module "gno.land/p/demo/gnode" +module gno.land/p/demo/gnode diff --git a/examples/gno.land/p/demo/grc/exts/vault/gno.mod b/examples/gno.land/p/demo/grc/exts/vault/gno.mod index 8b4d4524366..2720bf09d95 100644 --- a/examples/gno.land/p/demo/grc/exts/vault/gno.mod +++ b/examples/gno.land/p/demo/grc/exts/vault/gno.mod @@ -1,6 +1,6 @@ module gno.land/p/demo/grc/exts/vault require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/p/demo/grc/grc20" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/grc/grc20 v0.0.0-latest ) diff --git a/examples/gno.land/p/demo/grc/grc1155/gno.mod b/examples/gno.land/p/demo/grc/grc1155/gno.mod index 33a8e55be71..0b2b85d8e86 100644 --- a/examples/gno.land/p/demo/grc/grc1155/gno.mod +++ b/examples/gno.land/p/demo/grc/grc1155/gno.mod @@ -1,7 +1,7 @@ module gno.land/p/demo/grc/grc1155 require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/r/demo/users" v0.0.0-latest - "gno.land/p/demo/ufmt" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest + gno.land/r/demo/users v0.0.0-latest ) diff --git a/examples/gno.land/p/demo/grc/grc20/gno.mod b/examples/gno.land/p/demo/grc/grc20/gno.mod index 5e6e13f834c..fd80766a956 100644 --- a/examples/gno.land/p/demo/grc/grc20/gno.mod +++ b/examples/gno.land/p/demo/grc/grc20/gno.mod @@ -1,7 +1,7 @@ module gno.land/p/demo/grc/grc20 require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/p/demo/ufmt" v0.0.0-latest - "gno.land/p/demo/grc/exts" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/grc/exts v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest ) diff --git a/examples/gno.land/p/demo/grc/grc721/gno.mod b/examples/gno.land/p/demo/grc/grc721/gno.mod index 229fc3f739c..ea8c9c9e52e 100644 --- a/examples/gno.land/p/demo/grc/grc721/gno.mod +++ b/examples/gno.land/p/demo/grc/grc721/gno.mod @@ -1,7 +1,7 @@ module gno.land/p/demo/grc/grc721 require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/r/demo/users" v0.0.0-latest - "gno.land/p/demo/ufmt" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest + gno.land/r/demo/users v0.0.0-latest ) diff --git a/examples/gno.land/p/demo/grc/grc777/gno.mod b/examples/gno.land/p/demo/grc/grc777/gno.mod index 2fddce3f8f8..9fbf2f2b7cd 100644 --- a/examples/gno.land/p/demo/grc/grc777/gno.mod +++ b/examples/gno.land/p/demo/grc/grc777/gno.mod @@ -1,5 +1,3 @@ module gno.land/p/demo/grc/grc777 -require ( - "gno.land/p/demo/grc/exts" v0.0.0-latest -) +require gno.land/p/demo/grc/exts v0.0.0-latest diff --git a/examples/gno.land/p/demo/groups/gno.mod b/examples/gno.land/p/demo/groups/gno.mod index b52ad8b05b1..0e9f7cf2a7c 100644 --- a/examples/gno.land/p/demo/groups/gno.mod +++ b/examples/gno.land/p/demo/groups/gno.mod @@ -1,7 +1,6 @@ module gno.land/p/demo/groups require ( - "gno.land/r/demo/boards" v0.0.0-latest - "gno.land/p/demo/maths" v0.0.0-latest - "gno.land/p/demo/testutils" v0.0.0-latest + gno.land/p/demo/maths v0.0.0-latest + gno.land/r/demo/boards v0.0.0-latest ) diff --git a/examples/gno.land/p/demo/math_eval/int32/gno.mod b/examples/gno.land/p/demo/math_eval/int32/gno.mod index 9a1e634447c..de57497a699 100644 --- a/examples/gno.land/p/demo/math_eval/int32/gno.mod +++ b/examples/gno.land/p/demo/math_eval/int32/gno.mod @@ -1,5 +1,3 @@ module gno.land/p/demo/math_eval/int32 -require ( - "gno.land/p/demo/ufmt" v0.0.0-latest -) +require gno.land/p/demo/ufmt v0.0.0-latest diff --git a/examples/gno.land/p/demo/microblog/gno.mod b/examples/gno.land/p/demo/microblog/gno.mod index fe19b89f777..5964679efa6 100644 --- a/examples/gno.land/p/demo/microblog/gno.mod +++ b/examples/gno.land/p/demo/microblog/gno.mod @@ -1,7 +1,8 @@ module gno.land/p/demo/microblog require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/p/demo/ufmt" v0.0.0-latest - "gno.land/r/demo/users" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/testutils v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest + gno.land/r/demo/users v0.0.0-latest ) diff --git a/examples/gno.land/p/demo/mux/gno.mod b/examples/gno.land/p/demo/mux/gno.mod index 13e4736bea8..972a531e14c 100644 --- a/examples/gno.land/p/demo/mux/gno.mod +++ b/examples/gno.land/p/demo/mux/gno.mod @@ -1 +1 @@ -module "gno.land/p/demo/mux" +module gno.land/p/demo/mux diff --git a/examples/gno.land/p/demo/rand/gno.mod b/examples/gno.land/p/demo/rand/gno.mod index 66082ea873e..098af152648 100644 --- a/examples/gno.land/p/demo/rand/gno.mod +++ b/examples/gno.land/p/demo/rand/gno.mod @@ -1,3 +1,3 @@ // Draft -module gno.land/p/demo/rand +module gno.land/p/demo/rand diff --git a/examples/gno.land/p/demo/svg/gno.mod b/examples/gno.land/p/demo/svg/gno.mod index adb2acf1350..0af7ba0636d 100644 --- a/examples/gno.land/p/demo/svg/gno.mod +++ b/examples/gno.land/p/demo/svg/gno.mod @@ -1,5 +1,3 @@ module gno.land/p/demo/svg -require ( - "gno.land/p/demo/ufmt" v0.0.0-latest -) +require gno.land/p/demo/ufmt v0.0.0-latest diff --git a/examples/gno.land/p/demo/tests/gno.mod b/examples/gno.land/p/demo/tests/gno.mod index 229c2f62d9c..5d80e106567 100644 --- a/examples/gno.land/p/demo/tests/gno.mod +++ b/examples/gno.land/p/demo/tests/gno.mod @@ -1,6 +1,6 @@ module gno.land/p/demo/tests require ( - "gno.land/p/demo/tests/subtests" v0.0.0-latest - "gno.land/r/demo/tests" v0.0.0-latest + gno.land/p/demo/tests/subtests v0.0.0-latest + gno.land/r/demo/tests v0.0.0-latest ) diff --git a/examples/gno.land/p/demo/tests/subtests/gno.mod b/examples/gno.land/p/demo/tests/subtests/gno.mod index 26ec7c4879a..c8333722809 100644 --- a/examples/gno.land/p/demo/tests/subtests/gno.mod +++ b/examples/gno.land/p/demo/tests/subtests/gno.mod @@ -1,4 +1,4 @@ module gno.land/p/demo/tests/subtests -// TODO: this file should not exist. +// TODO: this file should not exist. // This is a temporary workaround. Until https://github.com/gnolang/gno/issues/852 diff --git a/examples/gno.land/p/demo/ui/gno.mod b/examples/gno.land/p/demo/ui/gno.mod index e71ee2d1ab1..41f5cb78d83 100644 --- a/examples/gno.land/p/demo/ui/gno.mod +++ b/examples/gno.land/p/demo/ui/gno.mod @@ -1 +1 @@ -module "gno.land/p/demo/ui" +module gno.land/p/demo/ui diff --git a/examples/gno.land/r/demo/art/gnoface/gno.mod b/examples/gno.land/r/demo/art/gnoface/gno.mod index 33d644206d6..bc17ee9df3b 100644 --- a/examples/gno.land/r/demo/art/gnoface/gno.mod +++ b/examples/gno.land/r/demo/art/gnoface/gno.mod @@ -1,6 +1,6 @@ module gno.land/r/demo/art/gnoface require ( - "gno.land/p/demo/rand" v0.0.0-latest - "gno.land/p/demo/ufmt" v0.0.0-latest + gno.land/p/demo/rand v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest ) diff --git a/examples/gno.land/r/demo/art/millipede/gno.mod b/examples/gno.land/r/demo/art/millipede/gno.mod index 10e3d2f1474..346e3a1673c 100644 --- a/examples/gno.land/r/demo/art/millipede/gno.mod +++ b/examples/gno.land/r/demo/art/millipede/gno.mod @@ -1,5 +1,3 @@ module gno.land/r/demo/art/millipede -require ( - "gno.land/p/demo/ufmt" v0.0.0-latest -) +require gno.land/p/demo/ufmt v0.0.0-latest diff --git a/examples/gno.land/r/demo/boards/gno.mod b/examples/gno.land/r/demo/boards/gno.mod index 882d97fec83..434ad019883 100644 --- a/examples/gno.land/r/demo/boards/gno.mod +++ b/examples/gno.land/r/demo/boards/gno.mod @@ -1,6 +1,6 @@ module gno.land/r/demo/boards require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/r/demo/users" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/r/demo/users v0.0.0-latest ) diff --git a/examples/gno.land/r/demo/foo1155/gno.mod b/examples/gno.land/r/demo/foo1155/gno.mod index 07c05ff5ef3..6fdf18a1658 100644 --- a/examples/gno.land/r/demo/foo1155/gno.mod +++ b/examples/gno.land/r/demo/foo1155/gno.mod @@ -1,7 +1,7 @@ module gno.land/r/demo/foo1155 require ( - "gno.land/p/demo/ufmt" v0.0.0-latest - "gno.land/p/demo/grc/grc1155" v0.0.0-latest - "gno.land/r/demo/users" v0.0.0-latest + gno.land/p/demo/grc/grc1155 v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest + gno.land/r/demo/users v0.0.0-latest ) diff --git a/examples/gno.land/r/demo/foo20/gno.mod b/examples/gno.land/r/demo/foo20/gno.mod index 1dbe9e01e4f..516690ee66c 100644 --- a/examples/gno.land/r/demo/foo20/gno.mod +++ b/examples/gno.land/r/demo/foo20/gno.mod @@ -1,7 +1,7 @@ module gno.land/r/demo/foo20 require ( - "gno.land/p/demo/ufmt" v0.0.0-latest - "gno.land/p/demo/grc/grc20" v0.0.0-latest - "gno.land/r/demo/users" v0.0.0-latest + gno.land/p/demo/grc/grc20 v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest + gno.land/r/demo/users v0.0.0-latest ) diff --git a/examples/gno.land/r/demo/foo721/gno.mod b/examples/gno.land/r/demo/foo721/gno.mod index b34ffd2b3fe..46c19e6ae55 100644 --- a/examples/gno.land/r/demo/foo721/gno.mod +++ b/examples/gno.land/r/demo/foo721/gno.mod @@ -1,7 +1,7 @@ module gno.land/r/demo/foo721 require ( - "gno.land/p/demo/ufmt" v0.0.0-latest - "gno.land/p/demo/grc/grc721" v0.0.0-latest - "gno.land/r/demo/users" v0.0.0-latest + gno.land/p/demo/grc/grc721 v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest + gno.land/r/demo/users v0.0.0-latest ) diff --git a/examples/gno.land/r/demo/groups/gno.mod b/examples/gno.land/r/demo/groups/gno.mod index d97acbecc7a..fc6756e13e2 100644 --- a/examples/gno.land/r/demo/groups/gno.mod +++ b/examples/gno.land/r/demo/groups/gno.mod @@ -1,6 +1,6 @@ module gno.land/r/demo/groups require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/r/demo/users" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/r/demo/users v0.0.0-latest ) diff --git a/examples/gno.land/r/demo/keystore/gno.mod b/examples/gno.land/r/demo/keystore/gno.mod index 88d59c9ccd6..af0b907c259 100644 --- a/examples/gno.land/r/demo/keystore/gno.mod +++ b/examples/gno.land/r/demo/keystore/gno.mod @@ -1,6 +1,7 @@ module gno.land/r/demo/keystore require ( - "gno.land/p/demo/ufmt" v0.0.0-latest - "gno.land/p/demo/avl" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/testutils v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest ) diff --git a/examples/gno.land/r/demo/math_eval/gno.mod b/examples/gno.land/r/demo/math_eval/gno.mod index 69d4e8c459b..0e3fcfe6e9b 100644 --- a/examples/gno.land/r/demo/math_eval/gno.mod +++ b/examples/gno.land/r/demo/math_eval/gno.mod @@ -1,6 +1,6 @@ module gno.land/r/demo/math_eval require ( - "gno.land/p/demo/ufmt" v0.0.0-latest - "gno.land/p/demo/math_eval/int32" v0.0.0-latest + gno.land/p/demo/math_eval/int32 v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest ) diff --git a/examples/gno.land/r/demo/microblog/gno.mod b/examples/gno.land/r/demo/microblog/gno.mod index 3d79a38d5fd..f496b1008ce 100644 --- a/examples/gno.land/r/demo/microblog/gno.mod +++ b/examples/gno.land/r/demo/microblog/gno.mod @@ -1,6 +1,6 @@ module gno.land/r/demo/microblog require ( - "gno.land/p/demo/microblog" v0.0.0-latest - "gno.land/r/demo/users" v0.0.0-latest + gno.land/p/demo/microblog v0.0.0-latest + gno.land/r/demo/users v0.0.0-latest ) diff --git a/examples/gno.land/r/demo/nft/gno.mod b/examples/gno.land/r/demo/nft/gno.mod index 2fefdbd1907..89e0055be51 100644 --- a/examples/gno.land/r/demo/nft/gno.mod +++ b/examples/gno.land/r/demo/nft/gno.mod @@ -1,6 +1,6 @@ module gno.land/r/demo/nft require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/p/demo/grc/grc721" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/grc/grc721 v0.0.0-latest ) diff --git a/examples/gno.land/r/demo/releases_example/gno.mod b/examples/gno.land/r/demo/releases_example/gno.mod index 85bcd07f232..22f640fe797 100644 --- a/examples/gno.land/r/demo/releases_example/gno.mod +++ b/examples/gno.land/r/demo/releases_example/gno.mod @@ -1,5 +1,3 @@ module gno.land/r/demo/releases_example -require ( - "gno.land/p/demo/releases" v0.0.0-latest -) +require gno.land/p/demo/releases v0.0.0-latest diff --git a/examples/gno.land/r/demo/tests/gno.mod b/examples/gno.land/r/demo/tests/gno.mod index 23dd3760157..9c5162f848e 100644 --- a/examples/gno.land/r/demo/tests/gno.mod +++ b/examples/gno.land/r/demo/tests/gno.mod @@ -1,6 +1,6 @@ module gno.land/r/demo/tests require ( - "gno.land/p/demo/testutils" v0.0.0-latest - "gno.land/r/demo/tests/subtests" v0.0.0-latest + gno.land/p/demo/testutils v0.0.0-latest + gno.land/r/demo/tests/subtests v0.0.0-latest ) diff --git a/examples/gno.land/r/demo/tests/subtests/gno.mod b/examples/gno.land/r/demo/tests/subtests/gno.mod index 80db73b4c15..9f466ff77b9 100644 --- a/examples/gno.land/r/demo/tests/subtests/gno.mod +++ b/examples/gno.land/r/demo/tests/subtests/gno.mod @@ -1,4 +1,4 @@ module gno.land/r/demo/tests/subtests -// TODO: this file should not exist. +// TODO: this file should not exist. // This is a temporary workaround. Until https://github.com/gnolang/gno/issues/852 diff --git a/examples/gno.land/r/demo/tests_foo/gno.mod b/examples/gno.land/r/demo/tests_foo/gno.mod index b19d8a21de1..226271ae4b0 100644 --- a/examples/gno.land/r/demo/tests_foo/gno.mod +++ b/examples/gno.land/r/demo/tests_foo/gno.mod @@ -1,5 +1,3 @@ module gno.land/r/demo/tests_foo -require ( - "gno.land/r/demo/tests" v0.0.0-latest -) +require gno.land/r/demo/tests v0.0.0-latest diff --git a/examples/gno.land/r/demo/types/gno.mod b/examples/gno.land/r/demo/types/gno.mod index 5709668ef2a..0e86e5d5676 100644 --- a/examples/gno.land/r/demo/types/gno.mod +++ b/examples/gno.land/r/demo/types/gno.mod @@ -1,5 +1,3 @@ module gno.land/r/demo/types -require ( - "gno.land/p/demo/avl" v0.0.0-latest -) +require gno.land/p/demo/avl v0.0.0-latest diff --git a/examples/gno.land/r/demo/ui/gno.mod b/examples/gno.land/r/demo/ui/gno.mod index 597c0f388a4..42be8cec3f0 100644 --- a/examples/gno.land/r/demo/ui/gno.mod +++ b/examples/gno.land/r/demo/ui/gno.mod @@ -1,5 +1,3 @@ module gno.land/r/demo/ui -require ( - "gno.land/p/demo/ui" v0.0.0-latest -) +require gno.land/p/demo/ui v0.0.0-latest diff --git a/examples/gno.land/r/demo/users/gno.mod b/examples/gno.land/r/demo/users/gno.mod index 055b5816871..edd20eb2721 100644 --- a/examples/gno.land/r/demo/users/gno.mod +++ b/examples/gno.land/r/demo/users/gno.mod @@ -1,6 +1,3 @@ module gno.land/r/demo/users -require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/p/demo/testutils" v0.0.0-latest -) +require gno.land/p/demo/avl v0.0.0-latest diff --git a/examples/gno.land/r/gnoland/blog/gno.mod b/examples/gno.land/r/gnoland/blog/gno.mod index a8b4f3ceaa9..1d64238cdc8 100644 --- a/examples/gno.land/r/gnoland/blog/gno.mod +++ b/examples/gno.land/r/gnoland/blog/gno.mod @@ -1,6 +1,6 @@ module gno.land/r/gnoland/blog require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/p/demo/blog" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/blog v0.0.0-latest ) diff --git a/examples/gno.land/r/gnoland/faucet/gno.mod b/examples/gno.land/r/gnoland/faucet/gno.mod index 75e85df326b..693b0e795cf 100644 --- a/examples/gno.land/r/gnoland/faucet/gno.mod +++ b/examples/gno.land/r/gnoland/faucet/gno.mod @@ -1,7 +1,7 @@ module gno.land/r/gnoland/faucet require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/p/demo/testutils" v0.0.0-latest - "gno.land/p/demo/ufmt" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/testutils v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest ) diff --git a/examples/gno.land/r/gnoland/pages/gno.mod b/examples/gno.land/r/gnoland/pages/gno.mod index 0f5c4076509..31e9ad2c85b 100644 --- a/examples/gno.land/r/gnoland/pages/gno.mod +++ b/examples/gno.land/r/gnoland/pages/gno.mod @@ -1,6 +1,6 @@ module gno.land/r/gnoland/pages require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/p/demo/blog" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/blog v0.0.0-latest ) diff --git a/examples/gno.land/r/system/names/gno.mod b/examples/gno.land/r/system/names/gno.mod index 31c456f90e0..cd4fd0aae4a 100644 --- a/examples/gno.land/r/system/names/gno.mod +++ b/examples/gno.land/r/system/names/gno.mod @@ -1,5 +1,3 @@ module gno.land/r/system/names -require ( - "gno.land/p/demo/avl" v0.0.0-latest -) +require gno.land/p/demo/avl v0.0.0-latest diff --git a/examples/gno.land/r/x/manfred_outfmt/gno.mod b/examples/gno.land/r/x/manfred_outfmt/gno.mod index eef8ec5956e..e6f705c46b9 100644 --- a/examples/gno.land/r/x/manfred_outfmt/gno.mod +++ b/examples/gno.land/r/x/manfred_outfmt/gno.mod @@ -1,6 +1,6 @@ module gno.land/r/x/manfred_outfmt require ( - "gno.land/p/demo/rand" v0.0.0-latest - "gno.land/p/demo/ufmt" v0.0.0-latest + gno.land/p/demo/rand v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest ) diff --git a/gnovm/cmd/gno/mod.go b/gnovm/cmd/gno/mod.go index 267b7d99237..9fb5dd704ce 100644 --- a/gnovm/cmd/gno/mod.go +++ b/gnovm/cmd/gno/mod.go @@ -4,8 +4,12 @@ import ( "context" "flag" "fmt" + "go/parser" + "go/token" "os" "path/filepath" + "sort" + "strings" "github.com/gnolang/gno/gnovm/pkg/gnomod" "github.com/gnolang/gno/tm2/pkg/commands" @@ -31,6 +35,7 @@ func newModCmd(io *commands.IO) *commands.Command { cmd.AddSubCommands( newModDownloadCmd(io), newModInitCmd(), + newModTidy(io), ) return cmd @@ -66,6 +71,20 @@ func newModInitCmd() *commands.Command { ) } +func newModTidy(io *commands.IO) *commands.Command { + return commands.NewCommand( + commands.Metadata{ + Name: "tidy", + ShortUsage: "tidy", + ShortHelp: "Add missing and remove unused modules", + }, + commands.NewEmptyConfig(), + func(_ context.Context, args []string) error { + return execModTidy(args, io) + }, + ) +} + func (c *modDownloadCfg) RegisterFlags(fs *flag.FlagSet) { fs.StringVar( &c.remote, @@ -152,3 +171,89 @@ func execModInit(args []string) error { return nil } + +func execModTidy(args []string, io *commands.IO) error { + if len(args) > 0 { + return flag.ErrHelp + } + + wd, err := os.Getwd() + if err != nil { + return err + } + fname := filepath.Join(wd, "gno.mod") + gm, err := gnomod.ParseGnoMod(fname) + if err != nil { + return err + } + + // Drop all existing requires + for _, r := range gm.Require { + gm.DropRequire(r.Mod.Path) + } + + imports, err := getGnoImports(wd) + if err != nil { + return err + } + for _, im := range imports { + // skip if importpath is modulepath + if im == gm.Module.Mod.Path { + continue + } + gm.AddRequire(im, "v0.0.0-latest") + } + + gm.Write(fname) + return nil +} + +// getGnoImports returns the list of gno imports from a given path. +// Note: It ignores subdirs. Since right now we are still deciding on +// how to handle subdirs. +// See: +// - https://github.com/gnolang/gno/issues/1024 +// - https://github.com/gnolang/gno/issues/852 +// +// TODO: move this to better location. +func getGnoImports(path string) ([]string, error) { + entries, err := os.ReadDir(path) + if err != nil { + return nil, err + } + + allImports := make([]string, 0) + seen := make(map[string]struct{}) + for _, e := range entries { + filename := e.Name() + if ext := filepath.Ext(filename); ext != ".gno" { + continue + } + if strings.HasSuffix(filename, "_filetest.gno") { + continue + } + data, err := os.ReadFile(filepath.Join(path, filename)) + if err != nil { + return nil, err + } + fs := token.NewFileSet() + f, err := parser.ParseFile(fs, filename, data, parser.ImportsOnly) + if err != nil { + return nil, err + } + for _, imp := range f.Imports { + importPath := strings.TrimPrefix(strings.TrimSuffix(imp.Path.Value, `"`), `"`) + if !strings.HasPrefix(importPath, "gno.land/") { + continue + } + if _, ok := seen[importPath]; ok { + continue + } + allImports = append(allImports, importPath) + seen[importPath] = struct{}{} + } + } + sort.Strings(allImports) + + return allImports, nil +} diff --git a/gnovm/cmd/gno/mod_test.go b/gnovm/cmd/gno/mod_test.go index fdae3d12c7a..bbf106c8960 100644 --- a/gnovm/cmd/gno/mod_test.go +++ b/gnovm/cmd/gno/mod_test.go @@ -1,6 +1,13 @@ package main -import "testing" +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) func TestModApp(t *testing.T) { tc := []testMainCase{ @@ -9,7 +16,7 @@ func TestModApp(t *testing.T) { errShouldBe: "flag: help requested", }, - // test gno.mod download + // test `gno mod download` { args: []string{"mod", "download"}, testDir: "../../tests/integ/empty-dir", @@ -73,7 +80,7 @@ func TestModApp(t *testing.T) { errShouldContain: "fetch: writepackage: querychain", }, - // test gno.mod init with no module name + // test `gno mod init` with no module name { args: []string{"mod", "init"}, testDir: "../../tests/integ/valid1", @@ -110,7 +117,7 @@ func TestModApp(t *testing.T) { errShouldBe: "create gno.mod file: gno.mod file already exists", }, - // test gno.mod init with module name + // test `gno mod init` with module name { args: []string{"mod", "init", "gno.land/p/demo/foo"}, testDir: "../../tests/integ/empty-dir", @@ -137,6 +144,164 @@ func TestModApp(t *testing.T) { simulateExternalRepo: true, errShouldBe: "create gno.mod file: gno.mod file already exists", }, + + // test `gno mod tidy` with module name + { + args: []string{"mod", "tidy", "arg1"}, + testDir: "../../tests/integ/minimalist-gnomod", + simulateExternalRepo: true, + errShouldContain: "flag: help requested", + }, + { + args: []string{"mod", "tidy"}, + testDir: "../../tests/integ/empty-dir", + simulateExternalRepo: true, + errShouldContain: "could not read gno.mod file", + }, + { + args: []string{"mod", "tidy"}, + testDir: "../../tests/integ/invalid-module-version1", + simulateExternalRepo: true, + errShouldContain: "error parsing gno.mod file at", + }, + { + args: []string{"mod", "tidy"}, + testDir: "../../tests/integ/minimalist-gnomod", + simulateExternalRepo: true, + }, + { + args: []string{"mod", "tidy"}, + testDir: "../../tests/integ/require-remote-module", + simulateExternalRepo: true, + }, + { + args: []string{"mod", "tidy"}, + testDir: "../../tests/integ/valid2", + simulateExternalRepo: true, + }, + { + args: []string{"mod", "tidy"}, + testDir: "../../tests/integ/invalid-gno-file", + simulateExternalRepo: true, + errShouldContain: "expected 'package', found packag", + }, } testMainCaseRun(t, tc) } + +func TestGetGnoImports(t *testing.T) { + workingDir, err := os.Getwd() + require.NoError(t, err) + + // create external dir + tmpDir, cleanUpFn := createTmpDir(t) + defer cleanUpFn() + + // cd to tmp directory + os.Chdir(tmpDir) + defer os.Chdir(workingDir) + + files := []struct { + name, data string + }{ + { + name: "file1.gno", + data: ` + package tmp + + import ( + "std" + + "gno.land/p/demo/pkg1" + ) + `, + }, + { + name: "file2.gno", + data: ` + package tmp + + import ( + "gno.land/p/demo/pkg1" + "gno.land/p/demo/pkg2" + ) + `, + }, + { + name: "file1_test.gno", + data: ` + package tmp + + import ( + "testing" + + "gno.land/p/demo/testpkg" + ) + `, + }, + { + name: "z_0_filetest.gno", + data: ` + package main + + import ( + "gno.land/p/demo/filetestpkg" + ) + `, + }, + + // subpkg files + { + name: filepath.Join("subtmp", "file1.gno"), + data: ` + package subtmp + + import ( + "std" + + "gno.land/p/demo/subpkg1" + ) + `, + }, + { + name: filepath.Join("subtmp", "file2.gno"), + data: ` + package subtmp + + import ( + "gno.land/p/demo/subpkg1" + "gno.land/p/demo/subpkg2" + ) + `, + }, + } + + // Expected list of imports + // - ignore subdirs + // - ignore duplicate + // - ignore *_filetest.gno + // - should be sorted + expected := []string{ + "gno.land/p/demo/pkg1", + "gno.land/p/demo/pkg2", + "gno.land/p/demo/testpkg", + } + + // Create subpkg dir + err = os.Mkdir("subtmp", 0o700) + require.NoError(t, err) + + // Create files + for _, f := range files { + err = os.WriteFile(f.name, []byte(f.data), 0o644) + require.NoError(t, err) + } + + imports, err := getGnoImports(tmpDir) + require.NoError(t, err) + + require.Equal(t, len(expected), len(imports)) + for i := range imports { + assert.Equal(t, expected[i], imports[i]) + } +} diff --git a/gnovm/pkg/doc/dirs.go b/gnovm/pkg/doc/dirs.go index 21216828ce4..19d312f6826 100644 --- a/gnovm/pkg/doc/dirs.go +++ b/gnovm/pkg/doc/dirs.go @@ -5,7 +5,6 @@ package doc import ( - "fmt" "log" "os" "path" @@ -52,7 +51,7 @@ func newDirs(dirs []string, modDirs []string) *bfsDirs { } for _, mdir := range modDirs { - gm, err := parseGnoMod(filepath.Join(mdir, "gno.mod")) + gm, err := gnomod.ParseGnoMod(filepath.Join(mdir, "gno.mod")) if err != nil { log.Printf("%v", err) continue @@ -68,34 +67,6 @@ func newDirs(dirs []string, modDirs []string) *bfsDirs { return d } -// tries to parse gno mod file given the filename, using Parse and Validate from -// the gnomod package -// -// TODO(tb): replace by `gnomod.ParseAt` ? The key difference is the latter -// looks for gno.mod in parent directories, while this function doesn't. -func parseGnoMod(fname string) (*gnomod.File, error) { - file, err := os.Stat(fname) - if err != nil { - return nil, fmt.Errorf("could not read gno.mod file: %w", err) - } - if file.IsDir() { - return nil, fmt.Errorf("invalid gno.mod at %q: is a directory", fname) - } - - b, err := os.ReadFile(fname) - if err != nil { - return nil, fmt.Errorf("could not read gno.mod file: %w", err) - } - gm, err := gnomod.Parse(fname, b) - if err != nil { - return nil, fmt.Errorf("error parsing gno.mod file at %q: %w", fname, err) - } - if err := gm.Validate(); err != nil { - return nil, fmt.Errorf("error validating gno.mod file at %q: %w", fname, err) - } - return gm, nil -} - func getGnoModDirs(gm *gnomod.File) []bfsDir { // cmd/go makes use of the go list command, we don't have that here. diff --git a/gnovm/pkg/gnomod/parse.go b/gnovm/pkg/gnomod/parse.go index 5bda3c31f70..a6314d5729f 100644 --- a/gnovm/pkg/gnomod/parse.go +++ b/gnovm/pkg/gnomod/parse.go @@ -42,6 +42,34 @@ func ParseAt(dir string) (*File, error) { return gm, nil } +// tries to parse gno mod file given the filename, using Parse and Validate from +// the gnomod package +// +// TODO(tb): replace by `gnomod.ParseAt` ? The key difference is the latter +// looks for gno.mod in parent directories, while this function doesn't. +func ParseGnoMod(fname string) (*File, error) { + file, err := os.Stat(fname) + if err != nil { + return nil, fmt.Errorf("could not read gno.mod file: %w", err) + } + if file.IsDir() { + return nil, fmt.Errorf("invalid gno.mod at %q: is a directory", fname) + } + + b, err := os.ReadFile(fname) + if err != nil { + return nil, fmt.Errorf("could not read gno.mod file: %w", err) + } + gm, err := Parse(fname, b) + if err != nil { + return nil, fmt.Errorf("error parsing gno.mod file at %q: %w", fname, err) + } + if err := gm.Validate(); err != nil { + return nil, fmt.Errorf("error validating gno.mod file at %q: %w", fname, err) + } + return gm, nil +} + // Parse parses and returns a gno.mod file. // // - file is the name of the file, used in positions and errors. diff --git a/gnovm/pkg/gnomod/parse_test.go b/gnovm/pkg/gnomod/parse_test.go index 934531e69c7..61aaa83482b 100644 --- a/gnovm/pkg/gnomod/parse_test.go +++ b/gnovm/pkg/gnomod/parse_test.go @@ -1,9 +1,12 @@ package gnomod import ( + "path/filepath" "testing" + "github.com/gnolang/gno/tm2/pkg/testutils" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestModuleDeprecated(t *testing.T) { @@ -167,3 +170,57 @@ func TestParseDraft(t *testing.T) { }) } } + +func TestParseGnoMod(t *testing.T) { + pkgDir := "bar" + for _, tc := range []struct { + desc, modData, modPath, errShouldContain string + }{ + { + desc: "file not exists", + modData: `module foo`, + modPath: filepath.Join(pkgDir, "mod.gno"), + errShouldContain: "could not read gno.mod file:", + }, + { + desc: "file path is dir", + modData: `module foo`, + modPath: pkgDir, + errShouldContain: "is a directory", + }, + { + desc: "valid gno.mod file", + modData: `module foo`, + modPath: filepath.Join(pkgDir, "gno.mod"), + }, + { + desc: "error parsing gno.mod", + modData: `module foo v0.0.0`, + modPath: filepath.Join(pkgDir, "gno.mod"), + errShouldContain: "error parsing gno.mod file at", + }, + { + desc: "error validating gno.mod", + modData: `require bar v0.0.0`, + modPath: filepath.Join(pkgDir, "gno.mod"), + errShouldContain: "error validating gno.mod file at", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + // Create test dir + tempDir, cleanUpFn := testutils.NewTestCaseDir(t) + require.NotNil(t, tempDir) + defer cleanUpFn() + + // Create gno package + createGnoModPkg(t, tempDir, pkgDir, tc.modData) + + _, err := ParseGnoMod(filepath.Join(tempDir, tc.modPath)) + if tc.errShouldContain != "" { + assert.ErrorContains(t, err, tc.errShouldContain) + } else { + assert.NoError(t, err) + } + }) + } +} diff --git a/gnovm/tests/integ/invalid-gno-file/gno.mod b/gnovm/tests/integ/invalid-gno-file/gno.mod new file mode 100644 index 00000000000..060e28b9dc4 --- /dev/null +++ b/gnovm/tests/integ/invalid-gno-file/gno.mod @@ -0,0 +1 @@ +module test diff --git a/gnovm/tests/integ/invalid-gno-file/invalid.gno b/gnovm/tests/integ/invalid-gno-file/invalid.gno new file mode 100644 index 00000000000..1e4ff406ada --- /dev/null +++ b/gnovm/tests/integ/invalid-gno-file/invalid.gno @@ -0,0 +1 @@ +packag invalid diff --git a/gnovm/tests/integ/valid2/gno.mod b/gnovm/tests/integ/valid2/gno.mod new file mode 100644 index 00000000000..98a5a0dacc1 --- /dev/null +++ b/gnovm/tests/integ/valid2/gno.mod @@ -0,0 +1,3 @@ +module gno.land/p/integ/valid + +require gno.land/p/demo/avl v0.0.0-latest diff --git a/gnovm/tests/integ/valid2/valid.gno b/gnovm/tests/integ/valid2/valid.gno new file mode 100644 index 00000000000..4de283f5d87 --- /dev/null +++ b/gnovm/tests/integ/valid2/valid.gno @@ -0,0 +1,11 @@ +package valid + +import ( + "gno.land/p/demo/avl" +) + +const Foo = "foo" + +func DoNothing(t *avl.Tree) { + // noop +} diff --git a/gnovm/tests/integ/valid2/valid_test.gno b/gnovm/tests/integ/valid2/valid_test.gno new file mode 100644 index 00000000000..2394da5c5ae --- /dev/null +++ b/gnovm/tests/integ/valid2/valid_test.gno @@ -0,0 +1,11 @@ +package valid + +import ( + "testing" + + "gno.land/p/integ/valid" +) + +func TestAlwaysValid(t *testing.T) { + _ = valid.Foo +} diff --git a/gnovm/tests/integ/valid2/z_0_filetest.gno b/gnovm/tests/integ/valid2/z_0_filetest.gno new file mode 100644 index 00000000000..06ab7d0f9a3 --- /dev/null +++ b/gnovm/tests/integ/valid2/z_0_filetest.gno @@ -0,0 +1 @@ +package main From ce7a7c66dc637364e5b0abab8eb037cfbea44ce3 Mon Sep 17 00:00:00 2001 From: Morgan Date: Mon, 6 Nov 2023 18:57:57 +0100 Subject: [PATCH 02/25] fix(misc/list-gnophers): make script work when called from any directory (#1308) \+ use a tmpdir for the csv file. @moul
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [x ] Added references to related issues and PRs - [x] Provided any useful hints for running manual tests - [x] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--- misc/list-gnophers/main.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/misc/list-gnophers/main.sh b/misc/list-gnophers/main.sh index beb90d4c767..0b230e97948 100755 --- a/misc/list-gnophers/main.sh +++ b/misc/list-gnophers/main.sh @@ -1,12 +1,13 @@ #!/bin/sh main() { + cd "$(dirname "$0")" cd ../.. + fname="$(mktemp --tmpdir gno_file_commits.XXXXXXXXXX.csv)" for file in $(list_gno_files); do extract_file_metadata $file - done > gno_file_commits.csv - echo - cat gno_file_commits.csv | sort_by_date | unique_by_author + done > "$fname" + cat "$fname" | sort_by_date | unique_by_author } list_gno_files() { From 4c7f93c46a54c469f1f0d1ca1d1fb7a8ca1cb3d9 Mon Sep 17 00:00:00 2001 From: Hariom Verma Date: Tue, 7 Nov 2023 00:42:57 +0530 Subject: [PATCH 03/25] ci(fix): tidy remaining gno.mod files (#1338) CI failing after merging #1035 Seems like some mod files are not tidy. --- examples/gno.land/r/gnoland/home/gno.mod | 7 +++---- examples/gno.land/r/manfred/present/gno.mod | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/gno.land/r/gnoland/home/gno.mod b/examples/gno.land/r/gnoland/home/gno.mod index 9192b4364d0..2864958930c 100644 --- a/examples/gno.land/r/gnoland/home/gno.mod +++ b/examples/gno.land/r/gnoland/home/gno.mod @@ -1,8 +1,7 @@ module gno.land/r/gnoland/home require ( - "gno.land/r/gnoland/blog" v0.0.0-latest - "gno.land/p/demo/ufmt" v0.0.0-latest - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/p/demo/ui" v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest + gno.land/p/demo/ui v0.0.0-latest + gno.land/r/gnoland/blog v0.0.0-latest ) diff --git a/examples/gno.land/r/manfred/present/gno.mod b/examples/gno.land/r/manfred/present/gno.mod index 9d1ab5b0e56..5d50447e0e0 100644 --- a/examples/gno.land/r/manfred/present/gno.mod +++ b/examples/gno.land/r/manfred/present/gno.mod @@ -1,6 +1,6 @@ module gno.land/r/manfred/present require ( - "gno.land/p/demo/avl" v0.0.0-latest - "gno.land/p/demo/blog" v0.0.0-latest + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/blog v0.0.0-latest ) From 42c013248e52807bff2712a86f86993b7765c462 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Tue, 7 Nov 2023 09:07:01 +0100 Subject: [PATCH 04/25] feat(repl): improve support of multi-line statements (#1129) ![demo](https://github.com/gnolang/gno/assets/5792239/308e61bc-bdf9-498b-9fa7-cd756835f774) This is a followup of #978. Instead of starting in multi-line mode prior to submit, the line is parsed, and new inputs are appended to it as long as the statment is not complete, as detected by the Go scanner. This is simpler and more general than previous attempt. The secondary prompt is "...", different from primary "gno>", similarly to many REPL programs (node, python, bash, ...). The "/editor" command is removed as not useful anymore. Note also that it is now possible to exit using Ctrl-D. Related issues: #446 #950
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [x] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--------- Co-authored-by: Manfred Touron <94029+moul@users.noreply.github.com> --- gnovm/cmd/gno/repl.go | 101 ++++++++++++++++++++--------------------- gnovm/pkg/repl/repl.go | 2 +- 2 files changed, 49 insertions(+), 54 deletions(-) diff --git a/gnovm/cmd/gno/repl.go b/gnovm/cmd/gno/repl.go index 1acb96c3cb9..0a9d4934ce3 100644 --- a/gnovm/cmd/gno/repl.go +++ b/gnovm/cmd/gno/repl.go @@ -2,10 +2,11 @@ package main import ( "bufio" - "bytes" "context" + "errors" "flag" "fmt" + "go/scanner" "os" "strings" @@ -88,10 +89,10 @@ func execRepl(cfg *replCfg, args []string) error { // gno> import "gno.land/p/demo/avl" // import the p/demo/avl package // gno> func a() string { return "a" } // declare a new function named a // gno> /src // print current generated source -// gno> /editor // enter in editor mode to add several lines +// gno> /editor // enter in multi-line mode, end with ';' // gno> /reset // remove all previously inserted code // gno> println(a()) // print the result of calling a() -// gno> /exit +// gno> /exit // alternative to `) } @@ -99,30 +100,59 @@ func execRepl(cfg *replCfg, args []string) error { } func runRepl(cfg *replCfg) error { - // init repl state r := repl.NewRepl() if cfg.initialCommand != "" { handleInput(r, cfg.initialCommand) } - var multiline bool - for { - fmt.Fprint(os.Stdout, "gno> ") + fmt.Fprint(os.Stdout, "gno> ") - input, err := getInput(multiline) - if err != nil { - return err + inEdit := false + prev := "" + liner := bufio.NewScanner(os.Stdin) + + for liner.Scan() { + line := liner.Text() + + if l := strings.TrimSpace(line); l == ";" { + line, inEdit = "", false + } else if l == "/editor" { + line, inEdit = "", true + fmt.Fprintln(os.Stdout, "// enter a single ';' to quit and commit") + } + if prev != "" { + line = prev + "\n" + line + prev = "" + } + if inEdit { + fmt.Fprint(os.Stdout, "... ") + prev = line + continue } - multiline = handleInput(r, input) + if err := handleInput(r, line); err != nil { + var goScanError scanner.ErrorList + if errors.As(err, &goScanError) { + // We assune that a Go scanner error indicates an incomplete Go statement. + // Append next line and retry. + prev = line + } else { + fmt.Fprintln(os.Stderr, err) + } + } + + if prev == "" { + fmt.Fprint(os.Stdout, "gno> ") + } else { + fmt.Fprint(os.Stdout, "... ") + } } + return nil } -// handleInput reads the input string and parses it depending if it -// is a specific command, or source code. It returns true if the following -// input is expected to be on more than one line. -func handleInput(r *repl.Repl, input string) bool { +// handleInput executes specific "/" commands, or evaluates input as Gno source code. +func handleInput(r *repl.Repl, input string) error { switch strings.TrimSpace(input) { case "/reset": r.Reset() @@ -130,49 +160,14 @@ func handleInput(r *repl.Repl, input string) bool { fmt.Fprintln(os.Stdout, r.Src()) case "/exit": os.Exit(0) - case "/editor": - fmt.Fprintln(os.Stdout, "// Entering editor mode (^D to finish)") - return true case "": - // avoid to increase the repl execution counter if sending empty content - fmt.Fprintln(os.Stdout, "") - return false + // Avoid to increase the repl execution counter if no input. default: out, err := r.Process(input) if err != nil { - fmt.Fprintln(os.Stderr, err) + return err } fmt.Fprintln(os.Stdout, out) } - - return false -} - -const ( - inputBreaker = "^D" - nl = "\n" -) - -func getInput(ml bool) (string, error) { - s := bufio.NewScanner(os.Stdin) - var mlOut bytes.Buffer - for s.Scan() { - line := s.Text() - if !ml { - return line, nil - } - - if line == inputBreaker { - break - } - - mlOut.WriteString(line) - mlOut.WriteString(nl) - } - - if err := s.Err(); err != nil { - return "", err - } - - return mlOut.String(), nil + return nil } diff --git a/gnovm/pkg/repl/repl.go b/gnovm/pkg/repl/repl.go index 0f60b948f39..c7786cf08b0 100644 --- a/gnovm/pkg/repl/repl.go +++ b/gnovm/pkg/repl/repl.go @@ -161,7 +161,7 @@ func (r *Repl) Process(input string) (out string, err error) { return r.handleExpression(exp) } - return "", fmt.Errorf("error parsing code:\n\t- as expression (error: %q)\n\t- as declarations (error: %q)", expErr.Error(), declErr.Error()) + return "", fmt.Errorf("error parsing code:\n\t- as expression: %w\n\t- as declarations: %w", expErr, declErr) } func (r *Repl) handleExpression(e *ast.File) (string, error) { From a90a273e0f1a573d04da782d3b0c064d98f8bb24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 11:58:59 +0100 Subject: [PATCH 05/25] chore(deps): bump actions/checkout from 3 to 4 (#1339) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
Release notes

Sourced from actions/checkout's releases.

v4.0.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v4.0.0

v3.6.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3.5.3...v3.6.0

v3.5.3

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v3.5.3

v3.5.2

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v3.5.1...v3.5.2

v3.5.1

What's Changed

New Contributors

... (truncated)

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3&new-version=4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/examples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index d52ed5c0ba6..f69a27d15b6 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -85,7 +85,7 @@ jobs: - uses: actions/setup-go@v4 with: go-version: ${{ matrix.go-version }} - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: | GNO_CMD="$(pwd)/gnovm/cmd/gno" # Find all directories containing gno.mod file From 23c5b3bd29f4f99e90c358a92a52ca614fc5ed4a Mon Sep 17 00:00:00 2001 From: Manfred Touron <94029+moul@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:00:41 +0100 Subject: [PATCH 06/25] chore(ci): update tm2 timeout on CI (#1337) It should prevent certain flaky tests from failing on GH. In any case, it increases the high-level timeout to be greater than the timeout for running 'go test'. Related to issue #1320. --- .github/workflows/tm2.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tm2.yml b/.github/workflows/tm2.yml index 7b78ccb1e0f..d5c6d9ddda6 100644 --- a/.github/workflows/tm2.yml +++ b/.github/workflows/tm2.yml @@ -55,7 +55,7 @@ jobs: - _test.pkg.bft - _test.pkg.others runs-on: ubuntu-latest - timeout-minutes: 15 + timeout-minutes: 21 steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v4 @@ -65,7 +65,7 @@ jobs: working-directory: tm2 run: | export GOPATH=$HOME/go - export GOTEST_FLAGS="-v -p 1 -timeout=30m -coverprofile=coverage.out -covermode=atomic" + export GOTEST_FLAGS="-v -p 1 -timeout=20m -coverprofile=coverage.out -covermode=atomic" make ${{ matrix.args }} touch coverage.out - uses: actions/upload-artifact@v3 From e6b4890af8462ca07658a7db815f66721a3aa15d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:11:09 +0100 Subject: [PATCH 07/25] chore(deps): bump github.com/gorilla/websocket from 1.5.0 to 1.5.1 (#1335) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/gorilla/websocket](https://github.com/gorilla/websocket) from 1.5.0 to 1.5.1.
Release notes

Sourced from github.com/gorilla/websocket's releases.

Release v1.5.1

What's Changed

New Contributors

Full Changelog: https://github.com/gorilla/websocket/compare/v1.5.0...v1.5.1

Commits
  • ac0789b update GitHub workflows (#857)
  • 78c3487 update golang.org/x/net (#856)
  • 666c197 Update go version & add verification/testing tools (#840)
  • 8039329 Correct way to save memory using write buffer pool and freeing net.http defau...
  • 8983b96 Merge pull request #839 from gorilla/coreydaley-patch-1
  • 931041c Update README.md
  • 76ecc29 archive mode
  • af47554 check error before GotConn for trace
  • bc7ce89 Check for and report bad protocol in TLSClientConfig.NextProtos (#788)
  • 27d91a9 drop the versions of go that are no longer supported + add 1.18 to ci
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/gorilla/websocket&package-manager=go_modules&previous-version=1.5.0&new-version=1.5.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5cc274f82b4..0a120db3e96 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/golang/protobuf v1.5.3 github.com/google/gofuzz v1.2.0 github.com/gorilla/mux v1.8.0 - github.com/gorilla/websocket v1.5.0 + github.com/gorilla/websocket v1.5.1 github.com/gotuna/gotuna v0.6.0 github.com/jaekwon/testify v1.6.1 github.com/jmhodges/levigo v1.0.0 diff --git a/go.sum b/go.sum index 0be3496a422..009a75c6a46 100644 --- a/go.sum +++ b/go.sum @@ -91,8 +91,8 @@ github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyC github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gotuna/gotuna v0.6.0 h1:N1lQKXEi/lwRp8u3sccTYLhzOffA4QasExz/1M5Riws= github.com/gotuna/gotuna v0.6.0/go.mod h1:F/ecRt29ChB6Ycy1AFIBpBiMNK0j7Heq+gFbLWquhjc= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= From eab86e82f0bf6d01c583fb96eef5e323a54ecaa0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:19:37 +0100 Subject: [PATCH 08/25] chore(deps): bump github.com/gorilla/mux from 1.8.0 to 1.8.1 (#1334) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/gorilla/mux](https://github.com/gorilla/mux) from 1.8.0 to 1.8.1.
Release notes

Sourced from github.com/gorilla/mux's releases.

Release v1.8.1

What's Changed

New Contributors

Full Changelog: https://github.com/gorilla/mux/compare/v1.8.0...v1.8.1

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/gorilla/mux&package-manager=go_modules&previous-version=1.8.0&new-version=1.8.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 0a120db3e96..772ada62749 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 github.com/golang/protobuf v1.5.3 github.com/google/gofuzz v1.2.0 - github.com/gorilla/mux v1.8.0 + github.com/gorilla/mux v1.8.1 github.com/gorilla/websocket v1.5.1 github.com/gotuna/gotuna v0.6.0 github.com/jaekwon/testify v1.6.1 diff --git a/go.sum b/go.sum index 009a75c6a46..94b02ca7a7c 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,9 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/csrf v1.7.0/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= From fa7b4c2b53264173d1dc19c832525925cb6c3f1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 17:36:31 +0530 Subject: [PATCH 09/25] chore(deps): bump golang.org/x/mod from 0.13.0 to 0.14.0 (#1336) Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.13.0 to 0.14.0.
Commits
  • 6e58e47 modfile: improve directory path detection and error text consistency
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=golang.org/x/mod&package-manager=go_modules&previous-version=0.13.0&new-version=0.14.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Hariom Verma --- gnovm/pkg/gnomod/read.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gnovm/pkg/gnomod/read.go b/gnovm/pkg/gnomod/read.go index 9bbed3c4651..e279d66344d 100644 --- a/gnovm/pkg/gnomod/read.go +++ b/gnovm/pkg/gnomod/read.go @@ -774,7 +774,7 @@ func parseReplace(filename string, line *modfile.Line, verb string, args []strin if strings.Contains(ns, "@") { return nil, errorf("replacement module must match format 'path version', not 'path@version'") } - return nil, errorf("replacement module without version must be directory path (rooted or starting with ./ or ../)") + return nil, errorf("replacement module without version must be directory path (rooted or starting with . or ..)") } if filepath.Separator == '/' && strings.Contains(ns, `\`) { return nil, errorf("replacement directory appears to be Windows path (on a non-windows system)") diff --git a/go.mod b/go.mod index 772ada62749..b627bea1ce1 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( go.etcd.io/bbolt v1.3.7 go.uber.org/multierr v1.9.0 golang.org/x/crypto v0.14.0 - golang.org/x/mod v0.13.0 + golang.org/x/mod v0.14.0 golang.org/x/net v0.17.0 golang.org/x/term v0.13.0 golang.org/x/tools v0.13.0 diff --git a/go.sum b/go.sum index 94b02ca7a7c..2bbff44d4d1 100644 --- a/go.sum +++ b/go.sum @@ -202,8 +202,8 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= From fb06d0a2b470f7895e8acf7ceb6cdf8bc4b2953c Mon Sep 17 00:00:00 2001 From: Guilhem Fanton <8671905+gfanton@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:49:09 +0100 Subject: [PATCH 10/25] feat: add InMemory `gnoland` node (#1241) Co-authored-by: Manfred Touron <94029+moul@users.noreply.github.com> --- .github/workflows/gnoland.yml | 8 +- gno.land/Makefile | 4 +- gno.land/cmd/genesis/balances_add.go | 131 ++----- gno.land/cmd/genesis/balances_add_test.go | 107 +++--- gno.land/cmd/genesis/balances_export_test.go | 31 +- gno.land/cmd/genesis/balances_remove.go | 2 +- gno.land/cmd/genesis/balances_remove_test.go | 15 +- gno.land/cmd/genesis/types.go | 22 +- gno.land/cmd/genesis/verify.go | 5 +- gno.land/cmd/genesis/verify_test.go | 8 +- gno.land/cmd/gnoland/root.go | 3 +- gno.land/cmd/gnoland/start.go | 294 +++++---------- gno.land/cmd/gnoland/testdata/addpkg.txtar | 11 +- gno.land/cmd/gnoweb/main.go | 8 +- gno.land/cmd/gnoweb/main_test.go | 34 +- gno.land/pkg/gnoland/app.go | 47 ++- gno.land/pkg/gnoland/genesis.go | 126 +++++++ gno.land/pkg/gnoland/node_inmemory.go | 147 ++++++++ gno.land/pkg/gnoland/types.go | 65 +++- gno.land/pkg/gnoland/types_test.go | 98 +++++ gno.land/pkg/integration/gnoland.go | 334 ------------------ gno.land/pkg/integration/testing.go | 39 ++ .../pkg/integration/testing_integration.go | 174 ++++----- gno.land/pkg/integration/testing_node.go | 184 ++++++++++ 24 files changed, 1010 insertions(+), 887 deletions(-) create mode 100644 gno.land/pkg/gnoland/genesis.go create mode 100644 gno.land/pkg/gnoland/node_inmemory.go create mode 100644 gno.land/pkg/gnoland/types_test.go delete mode 100644 gno.land/pkg/integration/gnoland.go create mode 100644 gno.land/pkg/integration/testing.go create mode 100644 gno.land/pkg/integration/testing_node.go diff --git a/.github/workflows/gnoland.yml b/.github/workflows/gnoland.yml index 95cb5fa8ce0..d305bed2dcd 100644 --- a/.github/workflows/gnoland.yml +++ b/.github/workflows/gnoland.yml @@ -60,9 +60,7 @@ jobs: - _test.gnoland - _test.gnokey - _test.pkgs - # XXX: test broken, should be rewritten to run an inmemory localnode - # Re-add to makefile when fixed. Tracked here: https://github.com/gnolang/gno/issues/1222 - #- _test.gnoweb + - _test.gnoweb runs-on: ubuntu-latest timeout-minutes: 15 steps: @@ -78,7 +76,7 @@ jobs: export LOG_DIR="${{ runner.temp }}/logs/test-${{ matrix.goversion }}-gnoland" make ${{ matrix.args }} - name: Upload Test Log - if: always() + if: always() uses: actions/upload-artifact@v3 with: name: logs-test-gnoland-go${{ matrix.goversion }} @@ -101,7 +99,7 @@ jobs: uses: codecov/codecov-action@v3 with: directory: ${{ runner.temp }}/coverage - token: ${{ secrets.CODECOV_TOKEN }} + token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: ${{ github.repository == 'gnolang/gno' }} docker-integration: diff --git a/gno.land/Makefile b/gno.land/Makefile index 22b9ec24650..29c192e9987 100644 --- a/gno.land/Makefile +++ b/gno.land/Makefile @@ -48,9 +48,7 @@ fmt: ######################################## # Test suite .PHONY: test -test: _test.gnoland _test.gnokey _test.pkgs -# XXX: _test.gnoweb is currently disabled. If fixed, re-enable here and in CI. -# https://github.com/gnolang/gno/issues/1222 +test: _test.gnoland _test.gnoweb _test.gnokey _test.pkgs GOTEST_FLAGS ?= -v -p 1 -timeout=30m diff --git a/gno.land/cmd/genesis/balances_add.go b/gno.land/cmd/genesis/balances_add.go index 276e48690a8..8df193c770c 100644 --- a/gno.land/cmd/genesis/balances_add.go +++ b/gno.land/cmd/genesis/balances_add.go @@ -8,32 +8,22 @@ import ( "fmt" "io" "os" - "regexp" - "strconv" "strings" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/tm2/pkg/amino" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/commands" - "github.com/gnolang/gno/tm2/pkg/crypto" "github.com/gnolang/gno/tm2/pkg/sdk/bank" "github.com/gnolang/gno/tm2/pkg/std" _ "github.com/gnolang/gno/gno.land/pkg/sdk/vm" ) -var ( - balanceRegex = regexp.MustCompile(`^(\w+)=(\d+)ugnot$`) - amountRegex = regexp.MustCompile(`^(\d+)ugnot$`) -) - var ( errNoBalanceSource = errors.New("at least one balance source must be set") errBalanceParsingAborted = errors.New("balance parsing aborted") - errInvalidBalanceFormat = errors.New("invalid balance format encountered") errInvalidAddress = errors.New("invalid address encountered") - errInvalidAmount = errors.New("invalid amount encountered") ) type balancesAddCfg struct { @@ -152,7 +142,7 @@ func execBalancesAdd(ctx context.Context, cfg *balancesAddCfg, io *commands.IO) // Construct the initial genesis balance sheet state := genesis.AppState.(gnoland.GnoGenesisState) - genesisBalances, err := extractGenesisBalances(state) + genesisBalances, err := mapGenesisBalancesFromState(state) if err != nil { return err } @@ -190,12 +180,11 @@ func getBalancesFromEntries(entries []string) (accountBalances, error) { balances := make(accountBalances) for _, entry := range entries { - accountBalance, err := getBalanceFromEntry(entry) - if err != nil { - return nil, fmt.Errorf("unable to extract balance data, %w", err) + var balance gnoland.Balance + if err := balance.Parse(entry); err != nil { + return nil, fmt.Errorf("unable to parse balance entry: %w", err) } - - balances[accountBalance.address] = accountBalance.amount + balances[balance.Address] = balance } return balances, nil @@ -220,12 +209,12 @@ func getBalancesFromSheet(sheet io.Reader) (accountBalances, error) { continue } - accountBalance, err := getBalanceFromEntry(entry) - if err != nil { + var balance gnoland.Balance + if err := balance.Parse(entry); err != nil { return nil, fmt.Errorf("unable to extract balance data, %w", err) } - balances[accountBalance.address] = accountBalance.amount + balances[balance.Address] = balance } if err := scanner.Err(); err != nil { @@ -262,21 +251,19 @@ func getBalancesFromTransactions( if err := amino.UnmarshalJSON(line, &tx); err != nil { io.ErrPrintfln( - "invalid amino JSON encountered: %s", + "invalid amino JSON encountered: %q", string(line), ) continue } - feeAmount, err := getAmountFromEntry(tx.Fee.GasFee.String()) - if err != nil { + feeAmount := std.NewCoins(tx.Fee.GasFee) + if feeAmount.AmountOf("ugnot") <= 0 { io.ErrPrintfln( - "invalid gas fee amount encountered: %s", + "invalid gas fee amount encountered: %q", tx.Fee.GasFee.String(), ) - - continue } for _, msg := range tx.Msgs { @@ -286,13 +273,12 @@ func getBalancesFromTransactions( msgSend := msg.(bank.MsgSend) - sendAmount, err := getAmountFromEntry(msgSend.Amount.String()) - if err != nil { + sendAmount := msgSend.Amount + if sendAmount.AmountOf("ugnot") <= 0 { io.ErrPrintfln( "invalid send amount encountered: %s", msgSend.Amount.String(), ) - continue } @@ -304,27 +290,35 @@ func getBalancesFromTransactions( // causes an accounts balance to go < 0. In these cases, // we initialize the account (it is present in the balance sheet), but // with the balance of 0 - from := balances[msgSend.FromAddress] - to := balances[msgSend.ToAddress] - to += sendAmount + from := balances[msgSend.FromAddress].Amount + to := balances[msgSend.ToAddress].Amount + + to = to.Add(sendAmount) - if from < sendAmount || from < feeAmount { + if from.IsAllLT(sendAmount) || from.IsAllLT(feeAmount) { // Account cannot cover send amount / fee // (see message above) - from = 0 + from = std.NewCoins(std.NewCoin("ugnot", 0)) } - if from > sendAmount { - from -= sendAmount + if from.IsAllGT(sendAmount) { + from = from.Sub(sendAmount) } - if from > feeAmount { - from -= feeAmount + if from.IsAllGT(feeAmount) { + from = from.Sub(feeAmount) } - balances[msgSend.FromAddress] = from - balances[msgSend.ToAddress] = to + // Set new balance + balances[msgSend.FromAddress] = gnoland.Balance{ + Address: msgSend.FromAddress, + Amount: from, + } + balances[msgSend.ToAddress] = gnoland.Balance{ + Address: msgSend.ToAddress, + Amount: to, + } } } } @@ -340,65 +334,14 @@ func getBalancesFromTransactions( return balances, nil } -// getAmountFromEntry -func getAmountFromEntry(entry string) (int64, error) { - matches := amountRegex.FindStringSubmatch(entry) - - // Check if there is a match - if len(matches) != 2 { - return 0, fmt.Errorf( - "invalid amount, %s", - entry, - ) - } - - amount, err := strconv.ParseInt(matches[1], 10, 64) - if err != nil { - return 0, fmt.Errorf("invalid amount, %s", matches[1]) - } - - return amount, nil -} - -// getBalanceFromEntry extracts the account balance information -// from a single line in the form of:
=ugnot -func getBalanceFromEntry(entry string) (*accountBalance, error) { - matches := balanceRegex.FindStringSubmatch(entry) - if len(matches) != 3 { - return nil, fmt.Errorf("%w, %s", errInvalidBalanceFormat, entry) - } - - // Validate the address - address, err := crypto.AddressFromString(matches[1]) - if err != nil { - return nil, fmt.Errorf("%w, %w", errInvalidAddress, err) - } - - // Validate the amount - amount, err := strconv.ParseInt(matches[2], 10, 64) - if err != nil { - return nil, fmt.Errorf("%w, %w", errInvalidAmount, err) - } - - return &accountBalance{ - address: address, - amount: amount, - }, nil -} - -// extractGenesisBalances extracts the initial account balances from the +// mapGenesisBalancesFromState extracts the initial account balances from the // genesis app state -func extractGenesisBalances(state gnoland.GnoGenesisState) (accountBalances, error) { +func mapGenesisBalancesFromState(state gnoland.GnoGenesisState) (accountBalances, error) { // Construct the initial genesis balance sheet genesisBalances := make(accountBalances) - for _, entry := range state.Balances { - accountBalance, err := getBalanceFromEntry(entry) - if err != nil { - return nil, fmt.Errorf("invalid genesis balance entry, %w", err) - } - - genesisBalances[accountBalance.address] = accountBalance.amount + for _, balance := range state.Balances { + genesisBalances[balance.Address] = balance } return genesisBalances, nil diff --git a/gno.land/cmd/genesis/balances_add_test.go b/gno.land/cmd/genesis/balances_add_test.go index f986ee85274..73e2fe148a2 100644 --- a/gno.land/cmd/genesis/balances_add_test.go +++ b/gno.land/cmd/genesis/balances_add_test.go @@ -98,7 +98,7 @@ func TestGenesis_Balances_Add(t *testing.T) { tempGenesis.Name(), } - amount := int64(10) + amount := std.NewCoins(std.NewCoin("ugnot", 10)) for _, dummyKey := range dummyKeys { args = append(args, "--single") @@ -107,7 +107,7 @@ func TestGenesis_Balances_Add(t *testing.T) { fmt.Sprintf( "%s=%dugnot", dummyKey.Address().String(), - amount, + amount.AmountOf("ugnot"), ), ) } @@ -127,16 +127,13 @@ func TestGenesis_Balances_Add(t *testing.T) { require.Equal(t, len(dummyKeys), len(state.Balances)) - for _, entry := range state.Balances { - accountBalance, err := getBalanceFromEntry(entry) - require.NoError(t, err) - + for _, balance := range state.Balances { // Find the appropriate key // (the genesis is saved with randomized balance order) found := false for _, dummyKey := range dummyKeys { - if dummyKey.Address().String() == accountBalance.address.String() { - assert.Equal(t, amount, accountBalance.amount) + if dummyKey.Address().String() == balance.Address.String() { + assert.Equal(t, amount, balance.Amount) found = true break @@ -144,7 +141,7 @@ func TestGenesis_Balances_Add(t *testing.T) { } if !found { - t.Fatalf("unexpected entry with address %s found", accountBalance.address.String()) + t.Fatalf("unexpected entry with address %s found", balance.Address.String()) } } }) @@ -159,7 +156,7 @@ func TestGenesis_Balances_Add(t *testing.T) { require.NoError(t, genesis.SaveAs(tempGenesis.Name())) dummyKeys := getDummyKeys(t, 10) - amount := int64(10) + amount := std.NewCoins(std.NewCoin("ugnot", 10)) balances := make([]string, len(dummyKeys)) @@ -170,7 +167,7 @@ func TestGenesis_Balances_Add(t *testing.T) { balances[index] = fmt.Sprintf( "%s=%dugnot", key.Address().String(), - amount, + amount.AmountOf("ugnot"), ) } @@ -207,16 +204,13 @@ func TestGenesis_Balances_Add(t *testing.T) { require.Equal(t, len(dummyKeys), len(state.Balances)) - for _, entry := range state.Balances { - accountBalance, err := getBalanceFromEntry(entry) - require.NoError(t, err) - + for _, balance := range state.Balances { // Find the appropriate key // (the genesis is saved with randomized balance order) found := false for _, dummyKey := range dummyKeys { - if dummyKey.Address().String() == accountBalance.address.String() { - assert.Equal(t, amount, accountBalance.amount) + if dummyKey.Address().String() == balance.Address.String() { + assert.Equal(t, amount, balance.Amount) found = true break @@ -224,7 +218,7 @@ func TestGenesis_Balances_Add(t *testing.T) { } if !found { - t.Fatalf("unexpected entry with address %s found", accountBalance.address.String()) + t.Fatalf("unexpected entry with address %s found", balance.Address.String()) } } }) @@ -240,8 +234,8 @@ func TestGenesis_Balances_Add(t *testing.T) { var ( dummyKeys = getDummyKeys(t, 10) - amount = int64(10) - amountCoins = std.NewCoins(std.NewCoin("ugnot", amount)) + amount = std.NewCoins(std.NewCoin("ugnot", 10)) + amountCoins = std.NewCoins(std.NewCoin("ugnot", 10)) gasFee = std.NewCoin("ugnot", 1000000) txs = make([]std.Tx, 0) ) @@ -309,10 +303,7 @@ func TestGenesis_Balances_Add(t *testing.T) { require.Equal(t, len(dummyKeys), len(state.Balances)) - for _, entry := range state.Balances { - accountBalance, err := getBalanceFromEntry(entry) - require.NoError(t, err) - + for _, balance := range state.Balances { // Find the appropriate key // (the genesis is saved with randomized balance order) found := false @@ -321,11 +312,11 @@ func TestGenesis_Balances_Add(t *testing.T) { if index == 0 { // the first address should // have a balance of 0 - checkAmount = 0 + checkAmount = std.NewCoins(std.NewCoin("ugnot", 0)) } - if dummyKey.Address().String() == accountBalance.address.String() { - assert.Equal(t, checkAmount, accountBalance.amount) + if dummyKey.Address().String() == balance.Address.String() { + assert.True(t, balance.Amount.IsEqual(checkAmount)) found = true break @@ -333,7 +324,7 @@ func TestGenesis_Balances_Add(t *testing.T) { } if !found { - t.Fatalf("unexpected entry with address %s found", accountBalance.address.String()) + t.Fatalf("unexpected entry with address %s found", balance.Address.String()) } } }) @@ -349,12 +340,11 @@ func TestGenesis_Balances_Add(t *testing.T) { genesis := getDefaultGenesis() state := gnoland.GnoGenesisState{ // Set an initial balance value - Balances: []string{ - fmt.Sprintf( - "%s=%dugnot", - dummyKeys[0].Address().String(), - 100, - ), + Balances: []gnoland.Balance{ + { + Address: dummyKeys[0].Address(), + Amount: std.NewCoins(std.NewCoin("ugnot", 100)), + }, }, } genesis.AppState = state @@ -369,7 +359,7 @@ func TestGenesis_Balances_Add(t *testing.T) { tempGenesis.Name(), } - amount := int64(10) + amount := std.NewCoins(std.NewCoin("ugnot", 10)) for _, dummyKey := range dummyKeys { args = append(args, "--single") @@ -378,7 +368,7 @@ func TestGenesis_Balances_Add(t *testing.T) { fmt.Sprintf( "%s=%dugnot", dummyKey.Address().String(), - amount, + amount.AmountOf("ugnot"), ), ) } @@ -398,16 +388,13 @@ func TestGenesis_Balances_Add(t *testing.T) { require.Equal(t, len(dummyKeys), len(state.Balances)) - for _, entry := range state.Balances { - accountBalance, err := getBalanceFromEntry(entry) - require.NoError(t, err) - + for _, balance := range state.Balances { // Find the appropriate key // (the genesis is saved with randomized balance order) found := false for _, dummyKey := range dummyKeys { - if dummyKey.Address().String() == accountBalance.address.String() { - assert.Equal(t, amount, accountBalance.amount) + if dummyKey.Address().String() == balance.Address.String() { + assert.Equal(t, amount, balance.Amount) found = true break @@ -415,7 +402,7 @@ func TestGenesis_Balances_Add(t *testing.T) { } if !found { - t.Fatalf("unexpected entry with address %s found", accountBalance.address.String()) + t.Fatalf("unexpected entry with address %s found", balance.Address.String()) } } }) @@ -429,7 +416,7 @@ func TestBalances_GetBalancesFromEntries(t *testing.T) { // Generate dummy keys dummyKeys := getDummyKeys(t, 2) - amount := int64(10) + amount := std.NewCoins(std.NewCoin("ugnot", 10)) balances := make([]string, len(dummyKeys)) @@ -437,7 +424,7 @@ func TestBalances_GetBalancesFromEntries(t *testing.T) { balances[index] = fmt.Sprintf( "%s=%dugnot", key.Address().String(), - amount, + amount.AmountOf("ugnot"), ) } @@ -447,7 +434,7 @@ func TestBalances_GetBalancesFromEntries(t *testing.T) { // Validate the balance map assert.Len(t, balanceMap, len(dummyKeys)) for _, key := range dummyKeys { - assert.Equal(t, amount, balanceMap[key.Address()]) + assert.Equal(t, amount, balanceMap[key.Address()].Amount) } }) @@ -461,7 +448,7 @@ func TestBalances_GetBalancesFromEntries(t *testing.T) { balanceMap, err := getBalancesFromEntries(balances) assert.Nil(t, balanceMap) - assert.ErrorContains(t, err, errInvalidBalanceFormat.Error()) + assert.ErrorContains(t, err, "malformed entry") }) t.Run("malformed balance, invalid address", func(t *testing.T) { @@ -474,7 +461,7 @@ func TestBalances_GetBalancesFromEntries(t *testing.T) { balanceMap, err := getBalancesFromEntries(balances) assert.Nil(t, balanceMap) - assert.ErrorContains(t, err, errInvalidAddress.Error()) + assert.ErrorContains(t, err, "invalid address") }) t.Run("malformed balance, invalid amount", func(t *testing.T) { @@ -493,7 +480,7 @@ func TestBalances_GetBalancesFromEntries(t *testing.T) { balanceMap, err := getBalancesFromEntries(balances) assert.Nil(t, balanceMap) - assert.ErrorContains(t, err, errInvalidAmount.Error()) + assert.ErrorContains(t, err, "invalid amount") }) } @@ -505,7 +492,7 @@ func TestBalances_GetBalancesFromSheet(t *testing.T) { // Generate dummy keys dummyKeys := getDummyKeys(t, 2) - amount := int64(10) + amount := std.NewCoins(std.NewCoin("ugnot", 10)) balances := make([]string, len(dummyKeys)) @@ -513,7 +500,7 @@ func TestBalances_GetBalancesFromSheet(t *testing.T) { balances[index] = fmt.Sprintf( "%s=%dugnot", key.Address().String(), - amount, + amount.AmountOf("ugnot"), ) } @@ -524,7 +511,7 @@ func TestBalances_GetBalancesFromSheet(t *testing.T) { // Validate the balance map assert.Len(t, balanceMap, len(dummyKeys)) for _, key := range dummyKeys { - assert.Equal(t, amount, balanceMap[key.Address()]) + assert.Equal(t, amount, balanceMap[key.Address()].Amount) } }) @@ -546,7 +533,7 @@ func TestBalances_GetBalancesFromSheet(t *testing.T) { balanceMap, err := getBalancesFromSheet(reader) assert.Nil(t, balanceMap) - assert.ErrorContains(t, err, errInvalidAmount.Error()) + assert.ErrorContains(t, err, "invalid amount") }) } @@ -558,8 +545,8 @@ func TestBalances_GetBalancesFromTransactions(t *testing.T) { var ( dummyKeys = getDummyKeys(t, 10) - amount = int64(10) - amountCoins = std.NewCoins(std.NewCoin("ugnot", amount)) + amount = std.NewCoins(std.NewCoin("ugnot", 10)) + amountCoins = std.NewCoins(std.NewCoin("ugnot", 10)) gasFee = std.NewCoin("ugnot", 1000000) txs = make([]std.Tx, 0) ) @@ -605,10 +592,10 @@ func TestBalances_GetBalancesFromTransactions(t *testing.T) { // Validate the balance map assert.Len(t, balanceMap, len(dummyKeys)) for _, key := range dummyKeys[1:] { - assert.Equal(t, amount, balanceMap[key.Address()]) + assert.Equal(t, amount, balanceMap[key.Address()].Amount) } - assert.Equal(t, int64(0), balanceMap[sender.Address()]) + assert.Equal(t, std.Coins{}, balanceMap[sender.Address()].Amount) }) t.Run("malformed transaction, invalid fee amount", func(t *testing.T) { @@ -616,8 +603,7 @@ func TestBalances_GetBalancesFromTransactions(t *testing.T) { var ( dummyKeys = getDummyKeys(t, 10) - amount = int64(10) - amountCoins = std.NewCoins(std.NewCoin("ugnot", amount)) + amountCoins = std.NewCoins(std.NewCoin("ugnot", 10)) gasFee = std.NewCoin("gnos", 1) // invalid fee txs = make([]std.Tx, 0) ) @@ -669,8 +655,7 @@ func TestBalances_GetBalancesFromTransactions(t *testing.T) { var ( dummyKeys = getDummyKeys(t, 10) - amount = int64(10) - amountCoins = std.NewCoins(std.NewCoin("gnogno", amount)) // invalid send amount + amountCoins = std.NewCoins(std.NewCoin("gnogno", 10)) // invalid send amount gasFee = std.NewCoin("ugnot", 1) txs = make([]std.Tx, 0) ) diff --git a/gno.land/cmd/genesis/balances_export_test.go b/gno.land/cmd/genesis/balances_export_test.go index 33e4f7bc800..d7441fd438f 100644 --- a/gno.land/cmd/genesis/balances_export_test.go +++ b/gno.land/cmd/genesis/balances_export_test.go @@ -3,31 +3,30 @@ package main import ( "bufio" "context" - "fmt" "testing" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/tm2/pkg/commands" + "github.com/gnolang/gno/tm2/pkg/std" "github.com/gnolang/gno/tm2/pkg/testutils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -// getDummyBalanceLines generates dummy balance lines -func getDummyBalanceLines(t *testing.T, count int) []string { +// getDummyBalances generates dummy balance lines +func getDummyBalances(t *testing.T, count int) []gnoland.Balance { t.Helper() dummyKeys := getDummyKeys(t, count) - amount := int64(10) + amount := std.NewCoins(std.NewCoin("ugnot", 10)) - balances := make([]string, len(dummyKeys)) + balances := make([]gnoland.Balance, len(dummyKeys)) for index, key := range dummyKeys { - balances[index] = fmt.Sprintf( - "%s=%dugnot", - key.Address().String(), - amount, - ) + balances[index] = gnoland.Balance{ + Address: key.Address(), + Amount: amount, + } } return balances @@ -85,7 +84,7 @@ func TestGenesis_Balances_Export(t *testing.T) { genesis := getDefaultGenesis() genesis.AppState = gnoland.GnoGenesisState{ - Balances: getDummyBalanceLines(t, 1), + Balances: getDummyBalances(t, 1), } require.NoError(t, genesis.SaveAs(tempGenesis.Name())) @@ -107,7 +106,7 @@ func TestGenesis_Balances_Export(t *testing.T) { t.Parallel() // Generate dummy balances - balances := getDummyBalanceLines(t, 10) + balances := getDummyBalances(t, 10) tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) @@ -139,9 +138,13 @@ func TestGenesis_Balances_Export(t *testing.T) { // Validate the transactions were written down scanner := bufio.NewScanner(outputFile) - outputBalances := make([]string, 0) + outputBalances := make([]gnoland.Balance, 0) for scanner.Scan() { - outputBalances = append(outputBalances, scanner.Text()) + var balance gnoland.Balance + err := balance.Parse(scanner.Text()) + require.NoError(t, err) + + outputBalances = append(outputBalances, balance) } require.NoError(t, scanner.Err()) diff --git a/gno.land/cmd/genesis/balances_remove.go b/gno.land/cmd/genesis/balances_remove.go index f7e9092dc3b..f4286d95ad2 100644 --- a/gno.land/cmd/genesis/balances_remove.go +++ b/gno.land/cmd/genesis/balances_remove.go @@ -71,7 +71,7 @@ func execBalancesRemove(cfg *balancesRemoveCfg, io *commands.IO) error { // Construct the initial genesis balance sheet state := genesis.AppState.(gnoland.GnoGenesisState) - genesisBalances, err := extractGenesisBalances(state) + genesisBalances, err := mapGenesisBalancesFromState(state) if err != nil { return err } diff --git a/gno.land/cmd/genesis/balances_remove_test.go b/gno.land/cmd/genesis/balances_remove_test.go index 29179c43604..b9d10d0db08 100644 --- a/gno.land/cmd/genesis/balances_remove_test.go +++ b/gno.land/cmd/genesis/balances_remove_test.go @@ -2,12 +2,12 @@ package main import ( "context" - "fmt" "testing" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/commands" + "github.com/gnolang/gno/tm2/pkg/std" "github.com/gnolang/gno/tm2/pkg/testutils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -70,12 +70,11 @@ func TestGenesis_Balances_Remove(t *testing.T) { genesis := getDefaultGenesis() state := gnoland.GnoGenesisState{ // Set an initial balance value - Balances: []string{ - fmt.Sprintf( - "%s=%dugnot", - dummyKey.Address().String(), - 100, - ), + Balances: []gnoland.Balance{ + { + Address: dummyKey.Address(), + Amount: std.NewCoins(std.NewCoin("ugnot", 100)), + }, }, } genesis.AppState = state @@ -118,7 +117,7 @@ func TestGenesis_Balances_Remove(t *testing.T) { genesis := getDefaultGenesis() state := gnoland.GnoGenesisState{ - Balances: []string{}, // Empty initial balance + Balances: []gnoland.Balance{}, // Empty initial balance } genesis.AppState = state require.NoError(t, genesis.SaveAs(tempGenesis.Name())) diff --git a/gno.land/cmd/genesis/types.go b/gno.land/cmd/genesis/types.go index 208eaddb6da..dba39ea8ec1 100644 --- a/gno.land/cmd/genesis/types.go +++ b/gno.land/cmd/genesis/types.go @@ -1,8 +1,7 @@ package main import ( - "fmt" - + "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/std" ) @@ -39,23 +38,14 @@ func (i *txStore) leftMerge(b txStore) error { return nil } -type ( - accountBalances map[types.Address]int64 // address -> balance (ugnot) - accountBalance struct { - address types.Address - amount int64 - } -) +type accountBalances map[types.Address]gnoland.Balance // address -> balance (ugnot) // toList linearizes the account balances map -func (a accountBalances) toList() []string { - balances := make([]string, 0, len(a)) +func (a accountBalances) toList() []gnoland.Balance { + balances := make([]gnoland.Balance, 0, len(a)) - for address, balance := range a { - balances = append( - balances, - fmt.Sprintf("%s=%dugnot", address, balance), - ) + for _, balance := range a { + balances = append(balances, balance) } return balances diff --git a/gno.land/cmd/genesis/verify.go b/gno.land/cmd/genesis/verify.go index ba51f5801f6..6c877ca51ec 100644 --- a/gno.land/cmd/genesis/verify.go +++ b/gno.land/cmd/genesis/verify.go @@ -9,7 +9,6 @@ import ( "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/commands" - "github.com/gnolang/gno/tm2/pkg/std" ) var errInvalidGenesisState = errors.New("invalid genesis state type") @@ -68,8 +67,8 @@ func execVerify(cfg *verifyCfg, io *commands.IO) error { // Validate the initial balances for _, balance := range state.Balances { - if _, parseErr := std.ParseCoins(balance); parseErr != nil { - return fmt.Errorf("invalid balance %s, %w", balance, parseErr) + if err := balance.Verify(); err != nil { + return fmt.Errorf("invalid balance: %w", err) } } } diff --git a/gno.land/cmd/genesis/verify_test.go b/gno.land/cmd/genesis/verify_test.go index fcc5305b9d0..8388949898b 100644 --- a/gno.land/cmd/genesis/verify_test.go +++ b/gno.land/cmd/genesis/verify_test.go @@ -44,7 +44,7 @@ func TestGenesis_Verify(t *testing.T) { g := getValidTestGenesis() g.AppState = gnoland.GnoGenesisState{ - Balances: []string{}, + Balances: []gnoland.Balance{}, Txs: []std.Tx{ {}, }, @@ -74,8 +74,8 @@ func TestGenesis_Verify(t *testing.T) { g := getValidTestGenesis() g.AppState = gnoland.GnoGenesisState{ - Balances: []string{ - "dummybalance", + Balances: []gnoland.Balance{ + {}, }, Txs: []std.Tx{}, } @@ -103,7 +103,7 @@ func TestGenesis_Verify(t *testing.T) { g := getValidTestGenesis() g.AppState = gnoland.GnoGenesisState{ - Balances: []string{}, + Balances: []gnoland.Balance{}, Txs: []std.Tx{}, } diff --git a/gno.land/cmd/gnoland/root.go b/gno.land/cmd/gnoland/root.go index cf2a6252478..5b2cbe0e4fe 100644 --- a/gno.land/cmd/gnoland/root.go +++ b/gno.land/cmd/gnoland/root.go @@ -11,8 +11,7 @@ import ( ) func main() { - io := commands.NewDefaultIO() - cmd := newRootCmd(io) + cmd := newRootCmd(commands.NewDefaultIO()) if err := cmd.ParseAndRun(context.Background(), os.Args[1:]); err != nil { _, _ = fmt.Fprintf(os.Stderr, "%+v\n", err) diff --git a/gno.land/cmd/gnoland/start.go b/gno.land/cmd/gnoland/start.go index a42e1df1bf0..618f4f87a09 100644 --- a/gno.land/cmd/gnoland/start.go +++ b/gno.land/cmd/gnoland/start.go @@ -1,21 +1,15 @@ package main import ( - "bufio" "context" "errors" "flag" "fmt" - "os" "path/filepath" "strings" "time" "github.com/gnolang/gno/gno.land/pkg/gnoland" - vmm "github.com/gnolang/gno/gno.land/pkg/sdk/vm" - gno "github.com/gnolang/gno/gnovm/pkg/gnolang" - "github.com/gnolang/gno/gnovm/pkg/gnomod" - "github.com/gnolang/gno/tm2/pkg/amino" abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types" "github.com/gnolang/gno/tm2/pkg/bft/config" "github.com/gnolang/gno/tm2/pkg/bft/node" @@ -32,13 +26,14 @@ import ( ) type startCfg struct { + gnoRootDir string skipFailingGenesisTxs bool skipStart bool genesisBalancesFile string genesisTxsFile string chainID string genesisRemote string - rootDir string + dataDir string genesisMaxVMCycles int64 config string @@ -64,6 +59,10 @@ func newStartCmd(io *commands.IO) *commands.Command { } func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { + gnoroot := gnoland.MustGuessGnoRootDir() + defaultGenesisBalancesFile := filepath.Join(gnoroot, "gno.land", "genesis", "genesis_balances.txt") + defaultGenesisTxsFile := filepath.Join(gnoroot, "gno.land", "genesis", "genesis_txs.txt") + fs.BoolVar( &c.skipFailingGenesisTxs, "skip-failing-genesis-txs", @@ -81,14 +80,14 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { fs.StringVar( &c.genesisBalancesFile, "genesis-balances-file", - "./genesis/genesis_balances.txt", + defaultGenesisBalancesFile, "initial distribution file", ) fs.StringVar( &c.genesisTxsFile, "genesis-txs-file", - "./genesis/genesis_txs.txt", + defaultGenesisTxsFile, "initial txs to replay", ) @@ -100,8 +99,16 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { ) fs.StringVar( - &c.rootDir, - "root-dir", + &c.gnoRootDir, + "gnoroot-dir", + gnoroot, + "the root directory of the gno repository", + ) + + // XXX: Use home directory for this + fs.StringVar( + &c.dataDir, + "data-dir", "testdir", "directory for config and data", ) @@ -156,11 +163,19 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { "", fmt.Sprintf("path for the file tx event store (required if event store is '%s')", file.EventStoreType), ) + + // XXX(deprecated): use data-dir instead + fs.StringVar( + &c.dataDir, + "root-dir", + "testdir", + "deprecated: use data-dir instead - directory for config and data", + ) } func execStart(c *startCfg, io *commands.IO) error { logger := log.NewTMLogger(log.NewSyncWriter(io.Out)) - rootDir := c.rootDir + dataDir := c.dataDir var ( cfg *config.Config @@ -174,39 +189,28 @@ func execStart(c *startCfg, io *commands.IO) error { cfg, loadCfgErr = config.LoadConfigFile(c.nodeConfigPath) } else { // Load the default node configuration - cfg, loadCfgErr = config.LoadOrMakeConfigWithOptions(rootDir, nil) + cfg, loadCfgErr = config.LoadOrMakeConfigWithOptions(dataDir, nil) } if loadCfgErr != nil { return fmt.Errorf("unable to load node configuration, %w", loadCfgErr) } - // create priv validator first. - // need it to generate genesis.json - newPrivValKey := cfg.PrivValidatorKeyFile() - newPrivValState := cfg.PrivValidatorStateFile() - priv := privval.LoadOrGenFilePV(newPrivValKey, newPrivValState) - - // write genesis file if missing. - genesisFilePath := filepath.Join(rootDir, cfg.Genesis) - - genesisTxs, genesisTxsErr := loadGenesisTxs(c.genesisTxsFile, c.chainID, c.genesisRemote) - if genesisTxsErr != nil { - return fmt.Errorf("unable to load genesis txs, %w", genesisTxsErr) - } + // Write genesis file if missing. + genesisFilePath := filepath.Join(dataDir, cfg.Genesis) if !osm.FileExists(genesisFilePath) { - genDoc, err := makeGenesisDoc( - priv.GetPubKey(), - c.chainID, - c.genesisBalancesFile, - genesisTxs, - ) - if err != nil { - return fmt.Errorf("unable to generate genesis.json, %w", err) + // Create priv validator first. + // Need it to generate genesis.json + newPrivValKey := cfg.PrivValidatorKeyFile() + newPrivValState := cfg.PrivValidatorStateFile() + priv := privval.LoadOrGenFilePV(newPrivValKey, newPrivValState) + pk := priv.GetPubKey() + + // Generate genesis.json file + if err := generateGenesisFile(genesisFilePath, pk, c); err != nil { + return fmt.Errorf("unable to generate genesis file: %w", err) } - - writeGenesisFile(genDoc, genesisFilePath) } // Initialize the indexer config @@ -214,15 +218,13 @@ func execStart(c *startCfg, io *commands.IO) error { if err != nil { return fmt.Errorf("unable to parse indexer config, %w", err) } - cfg.TxEventStore = txEventStoreCfg - // create application and node. - gnoApp, err := gnoland.NewApp(rootDir, c.skipFailingGenesisTxs, logger, c.genesisMaxVMCycles) + // Create application and node. + gnoApp, err := gnoland.NewApp(dataDir, c.skipFailingGenesisTxs, logger, c.genesisMaxVMCycles) if err != nil { return fmt.Errorf("error in creating new app: %w", err) } - cfg.LocalApp = gnoApp gnoNode, err := node.DefaultNewNode(cfg, logger) @@ -233,8 +235,7 @@ func execStart(c *startCfg, io *commands.IO) error { fmt.Fprintln(io.Err, "Node created.") if c.skipStart { - fmt.Fprintln(io.Err, "'--skip-start' is set. Exiting.") - + io.ErrPrintln("'--skip-start' is set. Exiting.") return nil } @@ -242,215 +243,96 @@ func execStart(c *startCfg, io *commands.IO) error { return fmt.Errorf("error in start node: %w", err) } - // run forever osm.TrapSignal(func() { if gnoNode.IsRunning() { _ = gnoNode.Stop() } }) - select {} // run forever + // Run forever + select {} } -// getTxEventStoreConfig constructs an event store config from provided user options -func getTxEventStoreConfig(c *startCfg) (*eventstorecfg.Config, error) { - var cfg *eventstorecfg.Config - - switch c.txEventStoreType { - case file.EventStoreType: - if c.txEventStorePath == "" { - return nil, errors.New("unspecified file transaction indexer path") - } - - // Fill out the configuration - cfg = &eventstorecfg.Config{ - EventStoreType: file.EventStoreType, - Params: map[string]any{ - file.Path: c.txEventStorePath, - }, - } - default: - cfg = eventstorecfg.DefaultEventStoreConfig() - } - - return cfg, nil -} - -// Makes a local test genesis doc with local privValidator. -func makeGenesisDoc( - pvPub crypto.PubKey, - chainID string, - genesisBalancesFile string, - genesisTxs []std.Tx, -) (*bft.GenesisDoc, error) { +func generateGenesisFile(genesisFile string, pk crypto.PubKey, c *startCfg) error { gen := &bft.GenesisDoc{} - gen.GenesisTime = time.Now() - gen.ChainID = chainID + gen.ChainID = c.chainID gen.ConsensusParams = abci.ConsensusParams{ Block: &abci.BlockParams{ // TODO: update limits. - MaxTxBytes: 1000000, // 1MB, - MaxDataBytes: 2000000, // 2MB, - MaxGas: 10000000, // 10M gas - TimeIotaMS: 100, // 100ms + MaxTxBytes: 1_000_000, // 1MB, + MaxDataBytes: 2_000_000, // 2MB, + MaxGas: 10_0000_00, // 10M gas + TimeIotaMS: 100, // 100ms }, } + gen.Validators = []bft.GenesisValidator{ { - Address: pvPub.Address(), - PubKey: pvPub, + Address: pk.Address(), + PubKey: pk, Power: 10, Name: "testvalidator", }, } - // Load distribution. - balances, err := loadGenesisBalances(genesisBalancesFile) + // Load balances files + balances, err := gnoland.LoadGenesisBalancesFile(c.genesisBalancesFile) if err != nil { - return nil, fmt.Errorf("unable to load genesis balances, %w", err) + return fmt.Errorf("unable to load genesis balances file %q: %w", c.genesisBalancesFile, err) } - // Load initial packages from examples. + // Load examples folder + examplesDir := filepath.Join(c.gnoRootDir, "examples") test1 := crypto.MustAddressFromString("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5") - txs := []std.Tx{} - - // List initial packages to load from examples. - pkgs, err := gnomod.ListPkgs(filepath.Join("..", "examples")) + defaultFee := std.NewFee(50000, std.MustParseCoin("1000000ugnot")) + pkgsTxs, err := gnoland.LoadPackagesFromDir(examplesDir, test1, defaultFee, nil) if err != nil { - panic(fmt.Errorf("listing gno packages: %w", err)) + return fmt.Errorf("unable to load examples folder: %w", err) } - // Sort packages by dependencies. - sortedPkgs, err := pkgs.Sort() + // Load Genesis TXs + genesisTxs, err := gnoland.LoadGenesisTxsFile(c.genesisTxsFile, c.chainID, c.genesisRemote) if err != nil { - panic(fmt.Errorf("sorting packages: %w", err)) + return fmt.Errorf("unable to load genesis txs file: %w", err) } - // Filter out draft packages. - nonDraftPkgs := sortedPkgs.GetNonDraftPkgs() - - for _, pkg := range nonDraftPkgs { - // open files in directory as MemPackage. - memPkg := gno.ReadMemPackage(pkg.Dir, pkg.Name) - - var tx std.Tx - tx.Msgs = []std.Msg{ - vmm.MsgAddPackage{ - Creator: test1, - Package: memPkg, - Deposit: nil, - }, - } - tx.Fee = std.NewFee(50000, std.MustParseCoin("1000000ugnot")) - tx.Signatures = make([]std.Signature, len(tx.GetSigners())) - txs = append(txs, tx) - } + genesisTxs = append(pkgsTxs, genesisTxs...) - // load genesis txs from file. - txs = append(txs, genesisTxs...) - - // construct genesis AppState. + // Construct genesis AppState. gen.AppState = gnoland.GnoGenesisState{ Balances: balances, - Txs: txs, - } - return gen, nil -} - -func writeGenesisFile(gen *bft.GenesisDoc, filePath string) { - err := gen.SaveAs(filePath) - if err != nil { - panic(err) - } -} - -func loadGenesisTxs( - path string, - chainID string, - genesisRemote string, -) ([]std.Tx, error) { - txs := make([]std.Tx, 0) - - if !osm.FileExists(path) { - // No initial transactions - return txs, nil - } - - txsFile, openErr := os.Open(path) - if openErr != nil { - return nil, fmt.Errorf("unable to open genesis txs file, %w", openErr) - } - - scanner := bufio.NewScanner(txsFile) - - for scanner.Scan() { - txLine := scanner.Text() - - if txLine == "" { - continue // skip empty line - } - - // patch the TX - txLine = strings.ReplaceAll(txLine, "%%CHAINID%%", chainID) - txLine = strings.ReplaceAll(txLine, "%%REMOTE%%", genesisRemote) - - var tx std.Tx - - if unmarshalErr := amino.UnmarshalJSON([]byte(txLine), &tx); unmarshalErr != nil { - return nil, fmt.Errorf("unable to amino unmarshal tx, %w", unmarshalErr) - } - - txs = append(txs, tx) + Txs: genesisTxs, } - if scanErr := scanner.Err(); scanErr != nil { - return nil, fmt.Errorf("error encountered while scanning, %w", scanErr) + // Write genesis state + if err := gen.SaveAs(genesisFile); err != nil { + return fmt.Errorf("unable to write genesis file %q: %w", genesisFile, err) } - return txs, nil + return nil } -func loadGenesisBalances(path string) ([]string, error) { - // each balance is in the form: g1xxxxxxxxxxxxxxxx=100000ugnot - balances := make([]string, 0) - - if !osm.FileExists(path) { - // No initial balances - return balances, nil - } - - balancesFile, openErr := os.Open(path) - if openErr != nil { - return nil, fmt.Errorf("unable to open genesis balances file, %w", openErr) - } - - scanner := bufio.NewScanner(balancesFile) - - for scanner.Scan() { - line := scanner.Text() - - line = strings.TrimSpace(line) - - // remove comments. - line = strings.Split(line, "#")[0] - line = strings.TrimSpace(line) +// getTxEventStoreConfig constructs an event store config from provided user options +func getTxEventStoreConfig(c *startCfg) (*eventstorecfg.Config, error) { + var cfg *eventstorecfg.Config - // skip empty lines. - if line == "" { - continue + switch c.txEventStoreType { + case file.EventStoreType: + if c.txEventStorePath == "" { + return nil, errors.New("unspecified file transaction indexer path") } - if len(strings.Split(line, "=")) != 2 { - return nil, fmt.Errorf("invalid genesis_balance line: %s", line) + // Fill out the configuration + cfg = &eventstorecfg.Config{ + EventStoreType: file.EventStoreType, + Params: map[string]any{ + file.Path: c.txEventStorePath, + }, } - - balances = append(balances, line) - } - - if scanErr := scanner.Err(); scanErr != nil { - return nil, fmt.Errorf("error encountered while scanning, %w", scanErr) + default: + cfg = eventstorecfg.DefaultEventStoreConfig() } - return balances, nil + return cfg, nil } diff --git a/gno.land/cmd/gnoland/testdata/addpkg.txtar b/gno.land/cmd/gnoland/testdata/addpkg.txtar index 5e871b058ac..5f1ee0caf49 100644 --- a/gno.land/cmd/gnoland/testdata/addpkg.txtar +++ b/gno.land/cmd/gnoland/testdata/addpkg.txtar @@ -10,7 +10,11 @@ gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/foobar/bar -gas-fee 10000 gnokey maketx call -pkgpath gno.land/r/foobar/bar -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1 ## compare render -cmp stdout stdout.golden +stdout '("hello from foo" string)' +stdout 'OK!' +stdout 'GAS WANTED: 2000000' +stdout 'GAS USED: [0-9]+' + -- bar.gno -- package bar @@ -19,8 +23,3 @@ func Render(path string) string { return "hello from foo" } --- stdout.golden -- -("hello from foo" string) -OK! -GAS WANTED: 2000000 -GAS USED: 69163 \ No newline at end of file diff --git a/gno.land/cmd/gnoweb/main.go b/gno.land/cmd/gnoweb/main.go index 0d9398cb8e2..b080e0b403d 100644 --- a/gno.land/cmd/gnoweb/main.go +++ b/gno.land/cmd/gnoweb/main.go @@ -486,11 +486,11 @@ func writeError(w http.ResponseWriter, err error) { // XXX: writeError should return an error page template. w.WriteHeader(500) - details := errors.Unwrap(err).Error() - main := err.Error() + fmt.Println("main", err.Error()) - fmt.Println("main", main) - fmt.Println("details", details) + if details := errors.Unwrap(err); details != nil { + fmt.Println("details", details.Error()) + } w.Write([]byte(err.Error())) } diff --git a/gno.land/cmd/gnoweb/main_test.go b/gno.land/cmd/gnoweb/main_test.go index 974d3f987b7..61650563405 100644 --- a/gno.land/cmd/gnoweb/main_test.go +++ b/gno.land/cmd/gnoweb/main_test.go @@ -4,10 +4,12 @@ import ( "fmt" "net/http" "net/http/httptest" - "os" "strings" "testing" + "github.com/gnolang/gno/gno.land/pkg/gnoland" + "github.com/gnolang/gno/gno.land/pkg/integration" + "github.com/gnolang/gno/tm2/pkg/log" "github.com/gotuna/gotuna/test/assert" ) @@ -41,20 +43,17 @@ func TestRoutes(t *testing.T) { {"/blog", found, "/r/gnoland/blog"}, {"/404-not-found", notFound, "/404-not-found"}, } - if wd, err := os.Getwd(); err == nil { - if strings.HasSuffix(wd, "cmd/gnoweb") { - os.Chdir("../..") - } - } else { - panic("os.Getwd() -> err: " + err.Error()) - } - // configure default values - flags.RemoteAddr = "127.0.0.1:26657" - flags.HelpRemote = "127.0.0.1:26657" + config, _ := integration.TestingNodeConfig(t, gnoland.MustGuessGnoRootDir()) + node, remoteAddr := integration.TestingInMemoryNode(t, log.NewNopLogger(), config) + defer node.Stop() + + // set the `remoteAddr` of the client to the listening address of the + // node, which is randomly assigned. + flags.RemoteAddr = remoteAddr flags.HelpChainID = "dev" flags.CaptchaSite = "" - flags.ViewsDir = "./cmd/gnoweb/views" + flags.ViewsDir = "../../cmd/gnoweb/views" flags.WithAnalytics = false app := makeApp() @@ -93,27 +92,34 @@ func TestAnalytics(t *testing.T) { "/404-not-found", } + config, _ := integration.TestingNodeConfig(t, gnoland.MustGuessGnoRootDir()) + node, remoteAddr := integration.TestingInMemoryNode(t, log.NewNopLogger(), config) + defer node.Stop() + + flags.ViewsDir = "../../cmd/gnoweb/views" t.Run("with", func(t *testing.T) { for _, route := range routes { t.Run(route, func(t *testing.T) { + flags.RemoteAddr = remoteAddr flags.WithAnalytics = true app := makeApp() request := httptest.NewRequest(http.MethodGet, route, nil) response := httptest.NewRecorder() app.Router.ServeHTTP(response, request) - assert.Contains(t, response.Body.String(), "simpleanalytics") + assert.Contains(t, response.Body.String(), "sa.gno.services") }) } }) t.Run("without", func(t *testing.T) { for _, route := range routes { t.Run(route, func(t *testing.T) { + flags.RemoteAddr = remoteAddr flags.WithAnalytics = false app := makeApp() request := httptest.NewRequest(http.MethodGet, route, nil) response := httptest.NewRecorder() app.Router.ServeHTTP(response, request) - assert.Equal(t, strings.Contains(response.Body.String(), "simpleanalytics"), false) + assert.Equal(t, strings.Contains(response.Body.String(), "sa.gno.services"), false) }) } }) diff --git a/gno.land/pkg/gnoland/app.go b/gno.land/pkg/gnoland/app.go index 3585f99d7de..a8a2736c8d1 100644 --- a/gno.land/pkg/gnoland/app.go +++ b/gno.land/pkg/gnoland/app.go @@ -1,10 +1,12 @@ package gnoland import ( + "errors" "fmt" "os" "os/exec" "path/filepath" + "runtime" "strings" "github.com/gnolang/gno/gno.land/pkg/sdk/vm" @@ -36,7 +38,7 @@ func NewAppOptions() *AppOptions { return &AppOptions{ Logger: log.NewNopLogger(), DB: dbm.NewMemDB(), - GnoRootDir: GuessGnoRootDir(), + GnoRootDir: MustGuessGnoRootDir(), } } @@ -73,6 +75,8 @@ func NewAppWithOptions(cfg *AppOptions) (abci.Application, error) { // Construct keepers. acctKpr := auth.NewAccountKeeper(mainKey, ProtoGnoAccount) bankKpr := bank.NewBankKeeper(acctKpr) + + // XXX: Embed this ? stdlibsDir := filepath.Join(cfg.GnoRootDir, "gnovm", "stdlibs") vmKpr := vm.NewVMKeeper(baseKey, mainKey, acctKpr, bankKpr, stdlibsDir, cfg.MaxCycles) @@ -142,10 +146,9 @@ func InitChainer(baseApp *sdk.BaseApp, acctKpr auth.AccountKeeperI, bankKpr bank genState := req.AppState.(GnoGenesisState) // Parse and set genesis state balances. for _, bal := range genState.Balances { - addr, coins := parseBalance(bal) - acc := acctKpr.NewAccountWithAddress(ctx, addr) + acc := acctKpr.NewAccountWithAddress(ctx, bal.Address) acctKpr.SetAccount(ctx, acc) - err := bankKpr.SetCoins(ctx, addr, coins) + err := bankKpr.SetCoins(ctx, bal.Address, bal.Amount) if err != nil { panic(err) } @@ -195,24 +198,44 @@ func EndBlocker(vmk vm.VMKeeperI) func(ctx sdk.Context, req abci.RequestEndBlock } } -func GuessGnoRootDir() string { - var rootdir string +// XXX: all the method bellow should be removed in favor of +// https://github.com/gnolang/gno/pull/1233 +func MustGuessGnoRootDir() string { + root, err := GuessGnoRootDir() + if err != nil { + panic(err) + } + + return root +} +func GuessGnoRootDir() (string, error) { // First try to get the root directory from the GNOROOT environment variable. - if rootdir = os.Getenv("GNOROOT"); rootdir != "" { - return filepath.Clean(rootdir) + if rootdir := os.Getenv("GNOROOT"); rootdir != "" { + return filepath.Clean(rootdir), nil } + // Try to guess GNOROOT using the nearest go.mod. if gobin, err := exec.LookPath("go"); err == nil { // If GNOROOT is not set, try to guess the root directory using the `go list` command. cmd := exec.Command(gobin, "list", "-m", "-mod=mod", "-f", "{{.Dir}}", "github.com/gnolang/gno") out, err := cmd.CombinedOutput() - if err != nil { - panic(fmt.Errorf("invalid gno directory %q: %w", rootdir, err)) + if err == nil { + return strings.TrimSpace(string(out)), nil } + } - return strings.TrimSpace(string(out)) + // Try to guess GNOROOT using caller stack. + if _, filename, _, ok := runtime.Caller(1); ok && filepath.IsAbs(filename) { + if currentDir := filepath.Dir(filename); currentDir != "" { + // Gno root directory relative from `app.go` path: + // gno/ .. /gno.land/ .. /pkg/ .. /gnoland/app.go + rootdir, err := filepath.Abs(filepath.Join(currentDir, "..", "..", "..")) + if err == nil { + return rootdir, nil + } + } } - panic("no go binary available, unable to determine gno root-dir path") + return "", errors.New("unable to guess gno's root-directory") } diff --git a/gno.land/pkg/gnoland/genesis.go b/gno.land/pkg/gnoland/genesis.go new file mode 100644 index 00000000000..e809103469d --- /dev/null +++ b/gno.land/pkg/gnoland/genesis.go @@ -0,0 +1,126 @@ +package gnoland + +import ( + "errors" + "fmt" + "strings" + + vmm "github.com/gnolang/gno/gno.land/pkg/sdk/vm" + gno "github.com/gnolang/gno/gnovm/pkg/gnolang" + "github.com/gnolang/gno/gnovm/pkg/gnomod" + "github.com/gnolang/gno/tm2/pkg/amino" + bft "github.com/gnolang/gno/tm2/pkg/bft/types" + "github.com/gnolang/gno/tm2/pkg/crypto" + osm "github.com/gnolang/gno/tm2/pkg/os" + "github.com/gnolang/gno/tm2/pkg/std" +) + +// LoadGenesisBalancesFile loads genesis balances from the provided file path. +func LoadGenesisBalancesFile(path string) ([]Balance, error) { + // each balance is in the form: g1xxxxxxxxxxxxxxxx=100000ugnot + content := osm.MustReadFile(path) + lines := strings.Split(string(content), "\n") + + balances := make([]Balance, 0, len(lines)) + for _, line := range lines { + line = strings.TrimSpace(line) + + // remove comments. + line = strings.Split(line, "#")[0] + line = strings.TrimSpace(line) + + // skip empty lines. + if line == "" { + continue + } + + parts := strings.Split(line, "=") //
= + if len(parts) != 2 { + return nil, errors.New("invalid genesis_balance line: " + line) + } + + addr, err := crypto.AddressFromBech32(parts[0]) + if err != nil { + return nil, fmt.Errorf("invalid balance addr %s: %w", parts[0], err) + } + + coins, err := std.ParseCoins(parts[1]) + if err != nil { + return nil, fmt.Errorf("invalid balance coins %s: %w", parts[1], err) + } + + balances = append(balances, Balance{ + Address: addr, + Amount: coins, + }) + } + + return balances, nil +} + +// LoadGenesisTxsFile loads genesis transactions from the provided file path. +// XXX: Improve the way we generate and load this file +func LoadGenesisTxsFile(path string, chainID string, genesisRemote string) ([]std.Tx, error) { + txs := []std.Tx{} + txsBz := osm.MustReadFile(path) + txsLines := strings.Split(string(txsBz), "\n") + for _, txLine := range txsLines { + if txLine == "" { + continue // Skip empty line. + } + + // Patch the TX. + txLine = strings.ReplaceAll(txLine, "%%CHAINID%%", chainID) + txLine = strings.ReplaceAll(txLine, "%%REMOTE%%", genesisRemote) + + var tx std.Tx + if err := amino.UnmarshalJSON([]byte(txLine), &tx); err != nil { + return nil, fmt.Errorf("unable to Unmarshall txs file: %w", err) + } + + txs = append(txs, tx) + } + + return txs, nil +} + +// LoadPackagesFromDir loads gno packages from a directory. +// It creates and returns a list of transactions based on these packages. +func LoadPackagesFromDir(dir string, creator bft.Address, fee std.Fee, deposit std.Coins) ([]std.Tx, error) { + // list all packages from target path + pkgs, err := gnomod.ListPkgs(dir) + if err != nil { + return nil, fmt.Errorf("listing gno packages: %w", err) + } + + // Sort packages by dependencies. + sortedPkgs, err := pkgs.Sort() + if err != nil { + return nil, fmt.Errorf("sorting packages: %w", err) + } + + // Filter out draft packages. + nonDraftPkgs := sortedPkgs.GetNonDraftPkgs() + txs := []std.Tx{} + for _, pkg := range nonDraftPkgs { + // Open files in directory as MemPackage. + memPkg := gno.ReadMemPackage(pkg.Dir, pkg.Name) + + // Create transaction + tx := std.Tx{ + Fee: fee, + Msgs: []std.Msg{ + vmm.MsgAddPackage{ + Creator: creator, + Package: memPkg, + Deposit: deposit, + }, + }, + } + + tx.Signatures = make([]std.Signature, len(tx.GetSigners())) + txs = append(txs, tx) + } + + return txs, nil +} diff --git a/gno.land/pkg/gnoland/node_inmemory.go b/gno.land/pkg/gnoland/node_inmemory.go new file mode 100644 index 00000000000..a0ab6a51e82 --- /dev/null +++ b/gno.land/pkg/gnoland/node_inmemory.go @@ -0,0 +1,147 @@ +package gnoland + +import ( + "fmt" + "time" + + abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types" + tmcfg "github.com/gnolang/gno/tm2/pkg/bft/config" + "github.com/gnolang/gno/tm2/pkg/bft/node" + "github.com/gnolang/gno/tm2/pkg/bft/proxy" + bft "github.com/gnolang/gno/tm2/pkg/bft/types" + "github.com/gnolang/gno/tm2/pkg/crypto" + "github.com/gnolang/gno/tm2/pkg/crypto/ed25519" + "github.com/gnolang/gno/tm2/pkg/db" + "github.com/gnolang/gno/tm2/pkg/log" + "github.com/gnolang/gno/tm2/pkg/p2p" + "github.com/gnolang/gno/tm2/pkg/std" +) + +type InMemoryNodeConfig struct { + PrivValidator bft.PrivValidator // identity of the validator + Genesis *bft.GenesisDoc + TMConfig *tmcfg.Config + SkipFailingGenesisTxs bool + GenesisMaxVMCycles int64 +} + +// NewMockedPrivValidator generate a new key +func NewMockedPrivValidator() bft.PrivValidator { + return bft.NewMockPVWithParams(ed25519.GenPrivKey(), false, false) +} + +// NewInMemoryNodeConfig creates a default configuration for an in-memory node. +func NewDefaultGenesisConfig(pk crypto.PubKey, chainid string) *bft.GenesisDoc { + return &bft.GenesisDoc{ + GenesisTime: time.Now(), + ChainID: chainid, + ConsensusParams: abci.ConsensusParams{ + Block: &abci.BlockParams{ + MaxTxBytes: 1_000_000, // 1MB, + MaxDataBytes: 2_000_000, // 2MB, + MaxGas: 10_0000_000, // 10M gas + TimeIotaMS: 100, // 100ms + }, + }, + AppState: &GnoGenesisState{ + Balances: []Balance{}, + Txs: []std.Tx{}, + }, + } +} + +func NewDefaultTMConfig(rootdir string) *tmcfg.Config { + return tmcfg.DefaultConfig().SetRootDir(rootdir) +} + +// NewInMemoryNodeConfig creates a default configuration for an in-memory node. +func NewDefaultInMemoryNodeConfig(rootdir string) *InMemoryNodeConfig { + tm := NewDefaultTMConfig(rootdir) + + // Create Mocked Identity + pv := NewMockedPrivValidator() + genesis := NewDefaultGenesisConfig(pv.GetPubKey(), tm.ChainID()) + + // Add self as validator + self := pv.GetPubKey() + genesis.Validators = []bft.GenesisValidator{ + { + Address: self.Address(), + PubKey: self, + Power: 10, + Name: "self", + }, + } + + return &InMemoryNodeConfig{ + PrivValidator: pv, + TMConfig: tm, + Genesis: genesis, + GenesisMaxVMCycles: 10_000_000, + } +} + +func (cfg *InMemoryNodeConfig) validate() error { + if cfg.PrivValidator == nil { + return fmt.Errorf("`PrivValidator` is required but not provided") + } + + if cfg.TMConfig == nil { + return fmt.Errorf("`TMConfig` is required but not provided") + } + + if cfg.TMConfig.RootDir == "" { + return fmt.Errorf("`TMConfig.RootDir` is required to locate `stdlibs` directory") + } + + return nil +} + +// NewInMemoryNode creates an in-memory gnoland node. In this mode, the node does not +// persist any data and uses an in-memory database. The `InMemoryNodeConfig.TMConfig.RootDir` +// should point to the correct gno repository to load the stdlibs. +func NewInMemoryNode(logger log.Logger, cfg *InMemoryNodeConfig) (*node.Node, error) { + if err := cfg.validate(); err != nil { + return nil, fmt.Errorf("validate config error: %w", err) + } + + // Initialize the application with the provided options + gnoApp, err := NewAppWithOptions(&AppOptions{ + Logger: logger, + GnoRootDir: cfg.TMConfig.RootDir, + SkipFailingGenesisTxs: cfg.SkipFailingGenesisTxs, + MaxCycles: cfg.GenesisMaxVMCycles, + DB: db.NewMemDB(), + }) + if err != nil { + return nil, fmt.Errorf("error initializing new app: %w", err) + } + + cfg.TMConfig.LocalApp = gnoApp + + // Setup app client creator + appClientCreator := proxy.DefaultClientCreator( + cfg.TMConfig.LocalApp, + cfg.TMConfig.ProxyApp, + cfg.TMConfig.ABCI, + cfg.TMConfig.DBDir(), + ) + + // Create genesis factory + genProvider := func() (*bft.GenesisDoc, error) { + return cfg.Genesis, nil + } + + // generate p2p node identity + // XXX: do we need to configur + nodekey := &p2p.NodeKey{PrivKey: ed25519.GenPrivKey()} + + // Create and return the in-memory node instance + return node.NewNode(cfg.TMConfig, + cfg.PrivValidator, nodekey, + appClientCreator, + genProvider, + node.DefaultDBProvider, + logger, + ) +} diff --git a/gno.land/pkg/gnoland/types.go b/gno.land/pkg/gnoland/types.go index 1c762366ae9..5d68064c9c5 100644 --- a/gno.land/pkg/gnoland/types.go +++ b/gno.land/pkg/gnoland/types.go @@ -1,9 +1,20 @@ package gnoland import ( + "errors" + "fmt" + "strings" + + bft "github.com/gnolang/gno/tm2/pkg/bft/types" + "github.com/gnolang/gno/tm2/pkg/crypto" "github.com/gnolang/gno/tm2/pkg/std" ) +var ( + ErrBalanceEmptyAddress = errors.New("balance address is empty") + ErrBalanceEmptyAmount = errors.New("balance amount is empty") +) + type GnoAccount struct { std.BaseAccount } @@ -13,6 +24,56 @@ func ProtoGnoAccount() std.Account { } type GnoGenesisState struct { - Balances []string `json:"balances"` - Txs []std.Tx `json:"txs"` + Balances []Balance `json:"balances"` + Txs []std.Tx `json:"txs"` +} + +type Balance struct { + Address bft.Address + Amount std.Coins +} + +func (b *Balance) Verify() error { + if b.Address.IsZero() { + return ErrBalanceEmptyAddress + } + + if b.Amount.Len() == 0 { + return ErrBalanceEmptyAmount + } + + return nil +} + +func (b *Balance) Parse(entry string) error { + parts := strings.Split(strings.TrimSpace(entry), "=") //
= + if len(parts) != 2 { + return fmt.Errorf("malformed entry: %q", entry) + } + + var err error + + b.Address, err = crypto.AddressFromBech32(parts[0]) + if err != nil { + return fmt.Errorf("invalid address %q: %w", parts[0], err) + } + + b.Amount, err = std.ParseCoins(parts[1]) + if err != nil { + return fmt.Errorf("invalid amount %q: %w", parts[1], err) + } + + return nil +} + +func (b *Balance) UnmarshalAmino(rep string) error { + return b.Parse(rep) +} + +func (b Balance) MarshalAmino() (string, error) { + return b.String(), nil +} + +func (b Balance) String() string { + return fmt.Sprintf("%s=%s", b.Address.String(), b.Amount.String()) } diff --git a/gno.land/pkg/gnoland/types_test.go b/gno.land/pkg/gnoland/types_test.go new file mode 100644 index 00000000000..97222d0cdfd --- /dev/null +++ b/gno.land/pkg/gnoland/types_test.go @@ -0,0 +1,98 @@ +package gnoland + +import ( + "fmt" + "testing" + + "github.com/gnolang/gno/tm2/pkg/amino" + bft "github.com/gnolang/gno/tm2/pkg/bft/types" + "github.com/gnolang/gno/tm2/pkg/crypto" + "github.com/gnolang/gno/tm2/pkg/std" + "github.com/jaekwon/testify/assert" + "github.com/jaekwon/testify/require" +) + +func TestBalance_Verify(t *testing.T) { + validAddress := crypto.MustAddressFromString("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5") + emptyAmount := std.Coins{} + nonEmptyAmount := std.NewCoins(std.NewCoin("test", 100)) + + tests := []struct { + name string + balance Balance + expectErr bool + }{ + {"empty amount", Balance{Address: validAddress, Amount: emptyAmount}, true}, + {"empty address", Balance{Address: bft.Address{}, Amount: nonEmptyAmount}, true}, + {"valid balance", Balance{Address: validAddress, Amount: nonEmptyAmount}, false}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + err := tc.balance.Verify() + if tc.expectErr { + assert.Error(t, err, fmt.Sprintf("TestVerifyBalance: %s", tc.name)) + } else { + assert.NoError(t, err, fmt.Sprintf("TestVerifyBalance: %s", tc.name)) + } + }) + } +} + +func TestBalance_Parse(t *testing.T) { + validAddress := crypto.MustAddressFromString("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5") + validBalance := Balance{Address: validAddress, Amount: std.NewCoins(std.NewCoin("test", 100))} + + tests := []struct { + name string + entry string + expected Balance + expectErr bool + }{ + {"valid entry", "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5=100test", validBalance, false}, + {"invalid address", "invalid=100test", Balance{}, true}, + {"incomplete entry", "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Balance{}, true}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + balance := Balance{} + err := balance.Parse(tc.entry) + if tc.expectErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tc.expected, balance) + } + }) + } +} + +func TestBalance_AminoUnmarshalJSON(t *testing.T) { + expected := Balance{ + Address: crypto.MustAddressFromString("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"), + Amount: std.MustParseCoins("100ugnot"), + } + value := fmt.Sprintf("[%q]", expected.String()) + + var balances []Balance + err := amino.UnmarshalJSON([]byte(value), &balances) + require.NoError(t, err) + require.Len(t, balances, 1, "there should be one balance after unmarshaling") + + balance := balances[0] + require.Equal(t, expected.Address, balance.Address) + require.True(t, expected.Amount.IsEqual(balance.Amount)) +} + +func TestBalance_AminoMarshalJSON(t *testing.T) { + expected := Balance{ + Address: crypto.MustAddressFromString("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"), + Amount: std.MustParseCoins("100ugnot"), + } + expectedJSON := fmt.Sprintf("[%q]", expected.String()) + + balancesJSON, err := amino.MarshalJSON([]Balance{expected}) + require.NoError(t, err) + require.JSONEq(t, expectedJSON, string(balancesJSON)) +} diff --git a/gno.land/pkg/integration/gnoland.go b/gno.land/pkg/integration/gnoland.go deleted file mode 100644 index 318d76eea86..00000000000 --- a/gno.land/pkg/integration/gnoland.go +++ /dev/null @@ -1,334 +0,0 @@ -package integration - -import ( - "flag" - "fmt" - "path/filepath" - "strings" - "testing" - "time" - - "github.com/gnolang/gno/gno.land/pkg/gnoland" - vmm "github.com/gnolang/gno/gno.land/pkg/sdk/vm" - gno "github.com/gnolang/gno/gnovm/pkg/gnolang" - "github.com/gnolang/gno/gnovm/pkg/gnomod" - "github.com/gnolang/gno/tm2/pkg/amino" - abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types" - "github.com/gnolang/gno/tm2/pkg/bft/config" - "github.com/gnolang/gno/tm2/pkg/bft/node" - "github.com/gnolang/gno/tm2/pkg/bft/privval" - bft "github.com/gnolang/gno/tm2/pkg/bft/types" - "github.com/gnolang/gno/tm2/pkg/crypto" - "github.com/gnolang/gno/tm2/pkg/db" - "github.com/gnolang/gno/tm2/pkg/log" - osm "github.com/gnolang/gno/tm2/pkg/os" - "github.com/gnolang/gno/tm2/pkg/std" - "github.com/rogpeppe/go-internal/testscript" -) - -type IntegrationConfig struct { - SkipFailingGenesisTxs bool - SkipStart bool - GenesisBalancesFile string - GenesisTxsFile string - ChainID string - GenesisRemote string - RootDir string - GenesisMaxVMCycles int64 - Config string -} - -// NOTE: This is a copy of gnoland actual flags. -// XXX: A lot this make no sense for integration. -func (c *IntegrationConfig) RegisterFlags(fs *flag.FlagSet) { - fs.BoolVar( - &c.SkipFailingGenesisTxs, - "skip-failing-genesis-txs", - false, - "don't panic when replaying invalid genesis txs", - ) - fs.BoolVar( - &c.SkipStart, - "skip-start", - false, - "quit after initialization, don't start the node", - ) - - fs.StringVar( - &c.GenesisBalancesFile, - "genesis-balances-file", - "./genesis/genesis_balances.txt", - "initial distribution file", - ) - - fs.StringVar( - &c.GenesisTxsFile, - "genesis-txs-file", - "./genesis/genesis_txs.txt", - "initial txs to replay", - ) - - fs.StringVar( - &c.ChainID, - "chainid", - "dev", - "the ID of the chain", - ) - - fs.StringVar( - &c.RootDir, - "root-dir", - "testdir", - "directory for config and data", - ) - - fs.StringVar( - &c.GenesisRemote, - "genesis-remote", - "localhost:26657", - "replacement for '%%REMOTE%%' in genesis", - ) - - fs.Int64Var( - &c.GenesisMaxVMCycles, - "genesis-max-vm-cycles", - 10_000_000, - "set maximum allowed vm cycles per operation. Zero means no limit.", - ) -} - -func execTestingGnoland(t *testing.T, logger log.Logger, gnoDataDir, gnoRootDir string, args []string) (*node.Node, error) { - t.Helper() - - // Setup start config. - icfg := &IntegrationConfig{} - { - fs := flag.NewFlagSet("start", flag.ExitOnError) - icfg.RegisterFlags(fs) - - // Override default value for flags. - fs.VisitAll(func(f *flag.Flag) { - switch f.Name { - case "root-dir": - f.DefValue = gnoDataDir - case "chainid": - f.DefValue = "tendermint_test" - case "genesis-balances-file": - f.DefValue = filepath.Join(gnoRootDir, "gno.land", "genesis", "genesis_balances.txt") - case "genesis-txs-file": - f.DefValue = filepath.Join(gnoRootDir, "gno.land", "genesis", "genesis_txs.txt") - default: - return - } - - f.Value.Set(f.DefValue) - }) - - if err := fs.Parse(args); err != nil { - return nil, fmt.Errorf("unable to parse flags: %w", err) - } - } - - // Setup testing config. - cfg := config.TestConfig().SetRootDir(gnoDataDir) - { - cfg.EnsureDirs() - cfg.RPC.ListenAddress = "tcp://127.0.0.1:0" - cfg.P2P.ListenAddress = "tcp://127.0.0.1:0" - } - - // Prepare genesis. - if err := setupTestingGenesis(gnoDataDir, cfg, icfg, gnoRootDir); err != nil { - return nil, err - } - - // Create application and node. - return createAppAndNode(cfg, logger, gnoRootDir, icfg) -} - -func setupTestingGenesis(gnoDataDir string, cfg *config.Config, icfg *IntegrationConfig, gnoRootDir string) error { - newPrivValKey := cfg.PrivValidatorKeyFile() - newPrivValState := cfg.PrivValidatorStateFile() - priv := privval.LoadOrGenFilePV(newPrivValKey, newPrivValState) - - genesisFilePath := filepath.Join(gnoDataDir, cfg.Genesis) - genesisDirPath := filepath.Dir(genesisFilePath) - if err := osm.EnsureDir(genesisDirPath, 0o700); err != nil { - return fmt.Errorf("unable to ensure directory %q: %w", genesisDirPath, err) - } - - genesisTxs := loadGenesisTxs(icfg.GenesisTxsFile, icfg.ChainID, icfg.GenesisRemote) - pvPub := priv.GetPubKey() - - gen := &bft.GenesisDoc{ - GenesisTime: time.Now(), - ChainID: icfg.ChainID, - ConsensusParams: abci.ConsensusParams{ - Block: &abci.BlockParams{ - // TODO: update limits. - MaxTxBytes: 1000000, // 1MB, - MaxDataBytes: 2000000, // 2MB, - MaxGas: 10000000, // 10M gas - TimeIotaMS: 100, // 100ms - }, - }, - Validators: []bft.GenesisValidator{ - { - Address: pvPub.Address(), - PubKey: pvPub, - Power: 10, - Name: "testvalidator", - }, - }, - } - - // Load distribution. - balances := loadGenesisBalances(icfg.GenesisBalancesFile) - - // Load initial packages from examples. - // XXX: We should be able to config this. - test1 := crypto.MustAddressFromString(test1Addr) - txs := []std.Tx{} - - // List initial packages to load from examples. - // println(filepath.Join(gnoRootDir, "examples")) - pkgs, err := gnomod.ListPkgs(filepath.Join(gnoRootDir, "examples")) - if err != nil { - return fmt.Errorf("listing gno packages: %w", err) - } - - // Sort packages by dependencies. - sortedPkgs, err := pkgs.Sort() - if err != nil { - return fmt.Errorf("sorting packages: %w", err) - } - - // Filter out draft packages. - nonDraftPkgs := sortedPkgs.GetNonDraftPkgs() - - for _, pkg := range nonDraftPkgs { - // Open files in directory as MemPackage. - memPkg := gno.ReadMemPackage(pkg.Dir, pkg.Name) - - var tx std.Tx - tx.Msgs = []std.Msg{ - vmm.MsgAddPackage{ - Creator: test1, - Package: memPkg, - Deposit: nil, - }, - } - - // XXX: Add fee flag ? - // Or maybe reduce fee to the minimum ? - tx.Fee = std.NewFee(50000, std.MustParseCoin("1000000ugnot")) - tx.Signatures = make([]std.Signature, len(tx.GetSigners())) - txs = append(txs, tx) - } - - // Load genesis txs from file. - txs = append(txs, genesisTxs...) - - // Construct genesis AppState. - gen.AppState = gnoland.GnoGenesisState{ - Balances: balances, - Txs: txs, - } - - writeGenesisFile(gen, genesisFilePath) - - return nil -} - -func createAppAndNode(cfg *config.Config, logger log.Logger, gnoRootDir string, icfg *IntegrationConfig) (*node.Node, error) { - gnoApp, err := gnoland.NewAppWithOptions(&gnoland.AppOptions{ - Logger: logger, - GnoRootDir: gnoRootDir, - SkipFailingGenesisTxs: icfg.SkipFailingGenesisTxs, - MaxCycles: icfg.GenesisMaxVMCycles, - DB: db.NewMemDB(), - }) - if err != nil { - return nil, fmt.Errorf("error in creating new app: %w", err) - } - - cfg.LocalApp = gnoApp - node, err := node.DefaultNewNode(cfg, logger) - if err != nil { - return nil, fmt.Errorf("error in creating node: %w", err) - } - - return node, node.Start() -} - -func tsValidateError(ts *testscript.TestScript, cmd string, neg bool, err error) { - if err != nil { - fmt.Fprintf(ts.Stderr(), "%q error: %v\n", cmd, err) - if !neg { - ts.Fatalf("unexpected %q command failure: %s", cmd, err) - } - } else { - if neg { - ts.Fatalf("unexpected %s command success", cmd) - } - } -} - -func loadGenesisTxs( - path string, - chainID string, - genesisRemote string, -) []std.Tx { - txs := []std.Tx{} - txsBz := osm.MustReadFile(path) - txsLines := strings.Split(string(txsBz), "\n") - for _, txLine := range txsLines { - if txLine == "" { - continue // Skip empty line. - } - - // Patch the TX. - txLine = strings.ReplaceAll(txLine, "%%CHAINID%%", chainID) - txLine = strings.ReplaceAll(txLine, "%%REMOTE%%", genesisRemote) - - var tx std.Tx - amino.MustUnmarshalJSON([]byte(txLine), &tx) - txs = append(txs, tx) - } - - return txs -} - -func loadGenesisBalances(path string) []string { - // Each balance is in the form: g1xxxxxxxxxxxxxxxx=100000ugnot. - balances := []string{} - content := osm.MustReadFile(path) - lines := strings.Split(string(content), "\n") - for _, line := range lines { - line = strings.TrimSpace(line) - - // Remove comments. - line = strings.Split(line, "#")[0] - line = strings.TrimSpace(line) - - // Skip empty lines. - if line == "" { - continue - } - - parts := strings.Split(line, "=") - if len(parts) != 2 { - panic("invalid genesis_balance line: " + line) - } - - balances = append(balances, line) - } - return balances -} - -func writeGenesisFile(gen *bft.GenesisDoc, filePath string) { - err := gen.SaveAs(filePath) - if err != nil { - panic(err) - } -} diff --git a/gno.land/pkg/integration/testing.go b/gno.land/pkg/integration/testing.go new file mode 100644 index 00000000000..7803e213da1 --- /dev/null +++ b/gno.land/pkg/integration/testing.go @@ -0,0 +1,39 @@ +package integration + +import ( + "errors" + + "github.com/jaekwon/testify/assert" + "github.com/jaekwon/testify/require" + "github.com/rogpeppe/go-internal/testscript" +) + +// This error is from testscript.Fatalf and is needed to correctly +// handle the FailNow method. +// see: https://github.com/rogpeppe/go-internal/blob/32ae33786eccde1672d4ba373c80e1bc282bfbf6/testscript/testscript.go#L799-L812 +var errFailNow = errors.New("fail now!") //nolint:stylecheck + +var ( + _ require.TestingT = (*testingTS)(nil) + _ assert.TestingT = (*testingTS)(nil) +) + +type TestingTS = require.TestingT + +type testingTS struct { + *testscript.TestScript +} + +func TSTestingT(ts *testscript.TestScript) TestingTS { + return &testingTS{ts} +} + +func (t *testingTS) Errorf(format string, args ...interface{}) { + defer recover() // we can ignore recover result, we just want to catch it up + t.Fatalf(format, args...) +} + +func (t *testingTS) FailNow() { + // unfortunately we can't access underlying `t.t.FailNow` method + panic(errFailNow) +} diff --git a/gno.land/pkg/integration/testing_integration.go b/gno.land/pkg/integration/testing_integration.go index f0a696ddd85..b773317513f 100644 --- a/gno.land/pkg/integration/testing_integration.go +++ b/gno.land/pkg/integration/testing_integration.go @@ -10,28 +10,18 @@ import ( "strings" "sync" "testing" - "time" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/tm2/pkg/bft/node" - "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/commands" "github.com/gnolang/gno/tm2/pkg/crypto/keys" "github.com/gnolang/gno/tm2/pkg/crypto/keys/client" - "github.com/gnolang/gno/tm2/pkg/events" "github.com/gnolang/gno/tm2/pkg/log" "github.com/rogpeppe/go-internal/testscript" ) -// XXX: This should be centralize somewhere. -const ( - test1Addr = "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5" - test1Seed = "source bonus chronic canvas draft south burst lottery vacant surface solve popular case indicate oppose farm nothing bullet exhibit title speed wink action roast" -) - type testNode struct { *node.Node - logger log.Logger nGnoKeyExec uint // Counter for execution of gnokey. } @@ -51,15 +41,11 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { // `gnoRootDir` should point to the local location of the gno repository. // It serves as the gno equivalent of GOROOT. - gnoRootDir := gnoland.GuessGnoRootDir() + gnoRootDir := gnoland.MustGuessGnoRootDir() // `gnoHomeDir` should be the local directory where gnokey stores keys. gnoHomeDir := filepath.Join(tmpdir, "gno") - // `gnoDataDir` should refer to the local location where the gnoland node - // stores its configuration and data. - gnoDataDir := filepath.Join(tmpdir, "data") - // Testscripts run concurrently by default, so we need to be prepared for that. var muNodes sync.Mutex nodes := map[string]*testNode{} @@ -76,10 +62,35 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { return err } - // XXX: Add a command to add custom account. - kb.CreateAccount("test1", test1Seed, "", "", 0, 0) - env.Setenv("USER_SEED_test1", test1Seed) - env.Setenv("USER_ADDR_test1", test1Addr) + // create sessions ID + var sid string + { + works := env.Getenv("WORK") + sum := crc32.ChecksumIEEE([]byte(works)) + sid = strconv.FormatUint(uint64(sum), 16) + env.Setenv("SID", sid) + } + + // setup logger + var logger log.Logger + { + logger = log.NewNopLogger() + if persistWorkDir || os.Getenv("LOG_DIR") != "" { + logname := fmt.Sprintf("gnoland-%s.log", sid) + logger, err = getTestingLogger(env, logname) + if err != nil { + return fmt.Errorf("unable to setup logger: %w", err) + } + } + + env.Values["_logger"] = logger + } + + // Setup "test1" default account + kb.CreateAccount(DefaultAccount_Name, DefaultAccount_Seed, "", "", 0, 0) + + env.Setenv("USER_SEED_"+DefaultAccount_Name, DefaultAccount_Seed) + env.Setenv("USER_ADDR_"+DefaultAccount_Name, DefaultAccount_Address) env.Setenv("GNOROOT", gnoRootDir) env.Setenv("GNOHOME", gnoHomeDir) @@ -96,7 +107,8 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { return } - sid := getSessionID(ts) + logger := ts.Value("_logger").(log.Logger) // grab logger + sid := ts.Getenv("SID") // grab session id var cmd string cmd, args = args[0], args[1:] @@ -109,63 +121,20 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { break } - logger := log.NewNopLogger() - if persistWorkDir || os.Getenv("LOG_DIR") != "" { - logname := fmt.Sprintf("gnoland-%s.log", sid) - logger = getTestingLogger(ts, logname) - } + // Warp up `ts` so we can pass it to other testing method + t := TSTestingT(ts) - dataDir := filepath.Join(gnoDataDir, sid) - var node *node.Node - if node, err = execTestingGnoland(t, logger, dataDir, gnoRootDir, args); err == nil { - nodes[sid] = &testNode{ - Node: node, - logger: logger, - } - ts.Defer(func() { - muNodes.Lock() - defer muNodes.Unlock() - - if n := nodes[sid]; n != nil { - if err := n.Stop(); err != nil { - panic(fmt.Errorf("node %q was unable to stop: %w", sid, err)) - } - } - }) - - // Get listen address environment. - // It should have been updated with the right port on start. - laddr := node.Config().RPC.ListenAddress - - // Add default environements. - ts.Setenv("RPC_ADDR", laddr) - ts.Setenv("GNODATA", gnoDataDir) - - const listenerID = "testing_listener" - - // Wait for first block by waiting for `EventNewBlock` event. - nb := make(chan struct{}, 1) - node.EventSwitch().AddListener(listenerID, func(ev events.Event) { - if _, ok := ev.(types.EventNewBlock); ok { - select { - case nb <- struct{}{}: - default: - } - } - }) - - if node.BlockStore().Height() == 0 { - select { - case <-nb: // ok - case <-time.After(time.Second * 6): - ts.Fatalf("timeout while waiting for the node to start") - } - } - - node.EventSwitch().RemoveListener(listenerID) - - fmt.Fprintln(ts.Stdout(), "node started successfully") - } + // Generate config and node + cfg := TestingMinimalNodeConfig(t, gnoRootDir) + n, remoteAddr := TestingInMemoryNode(t, logger, cfg) + + // Register cleanup + nodes[sid] = &testNode{Node: n} + + // Add default environements + ts.Setenv("RPC_ADDR", remoteAddr) + + fmt.Fprintln(ts.Stdout(), "node started successfully") case "stop": n, ok := nodes[sid] if !ok { @@ -176,9 +145,8 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { if err = n.Stop(); err == nil { delete(nodes, sid) - // Unset gnoland environements. + // Unset gnoland environements ts.Setenv("RPC_ADDR", "") - ts.Setenv("GNODATA", "") fmt.Fprintln(ts.Stdout(), "node stopped successfully") } default: @@ -191,9 +159,10 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { muNodes.Lock() defer muNodes.Unlock() - sid := getSessionID(ts) + logger := ts.Value("_logger").(log.Logger) // grab logger + sid := ts.Getenv("SID") // grab session id - // Setup IO command. + // Setup IO command io := commands.NewTestIO() io.SetOut(commands.WriteNopCloser(ts.Stdout())) io.SetErr(commands.WriteNopCloser(ts.Stderr())) @@ -212,9 +181,10 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { n.nGnoKeyExec++ headerlog := fmt.Sprintf("%.02d!EXEC_GNOKEY", n.nGnoKeyExec) + // Log the command inside gnoland logger, so we can better scope errors. - n.logger.Info(headerlog, strings.Join(args, " ")) - defer n.logger.Info(headerlog, "END") + logger.Info(headerlog, strings.Join(args, " ")) + defer logger.Info(headerlog, "END") } // Inject default argument, if duplicate @@ -230,35 +200,30 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { } } -func getSessionID(ts *testscript.TestScript) string { - works := ts.Getenv("WORK") - sum := crc32.ChecksumIEEE([]byte(works)) - return strconv.FormatUint(uint64(sum), 16) -} - -func getTestingLogger(ts *testscript.TestScript, logname string) log.Logger { +func getTestingLogger(env *testscript.Env, logname string) (log.Logger, error) { var path string + if logdir := os.Getenv("LOG_DIR"); logdir != "" { if err := os.MkdirAll(logdir, 0o755); err != nil { - ts.Fatalf("unable to make log directory %q", logdir) + return nil, fmt.Errorf("unable to make log directory %q", logdir) } var err error if path, err = filepath.Abs(filepath.Join(logdir, logname)); err != nil { - ts.Fatalf("uanble to get absolute path of logdir %q", logdir) + return nil, fmt.Errorf("uanble to get absolute path of logdir %q", logdir) } - } else if workdir := ts.Getenv("WORK"); workdir != "" { + } else if workdir := env.Getenv("WORK"); workdir != "" { path = filepath.Join(workdir, logname) } else { - return log.NewNopLogger() + return log.NewNopLogger(), nil } f, err := os.Create(path) if err != nil { - ts.Fatalf("unable to create log file %q: %s", path, err.Error()) + return nil, fmt.Errorf("unable to create log file %q: %w", path, err) } - ts.Defer(func() { + env.Defer(func() { if err := f.Close(); err != nil { panic(fmt.Errorf("unable to close log file %q: %w", path, err)) } @@ -274,9 +239,22 @@ func getTestingLogger(ts *testscript.TestScript, logname string) log.Logger { logger.SetLevel(log.LevelInfo) case "": default: - ts.Fatalf("invalid log level %q", level) + return nil, fmt.Errorf("invalid log level %q", level) } - ts.Logf("starting logger: %q", path) - return logger + env.T().Log("starting logger: %q", path) + return logger, nil +} + +func tsValidateError(ts *testscript.TestScript, cmd string, neg bool, err error) { + if err != nil { + fmt.Fprintf(ts.Stderr(), "%q error: %v\n", cmd, err) + if !neg { + ts.Fatalf("unexpected %q command failure: %s", cmd, err) + } + } else { + if neg { + ts.Fatalf("unexpected %q command success", cmd) + } + } } diff --git a/gno.land/pkg/integration/testing_node.go b/gno.land/pkg/integration/testing_node.go new file mode 100644 index 00000000000..1ca7e11eb63 --- /dev/null +++ b/gno.land/pkg/integration/testing_node.go @@ -0,0 +1,184 @@ +package integration + +import ( + "path/filepath" + "sync" + "time" + + "github.com/gnolang/gno/gno.land/pkg/gnoland" + abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types" + tmcfg "github.com/gnolang/gno/tm2/pkg/bft/config" + "github.com/gnolang/gno/tm2/pkg/bft/node" + bft "github.com/gnolang/gno/tm2/pkg/bft/types" + "github.com/gnolang/gno/tm2/pkg/crypto" + "github.com/gnolang/gno/tm2/pkg/events" + "github.com/gnolang/gno/tm2/pkg/log" + "github.com/gnolang/gno/tm2/pkg/std" + "github.com/jaekwon/testify/require" +) + +const ( + DefaultAccount_Name = "test1" + DefaultAccount_Address = "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5" + DefaultAccount_Seed = "source bonus chronic canvas draft south burst lottery vacant surface solve popular case indicate oppose farm nothing bullet exhibit title speed wink action roast" +) + +// TestingInMemoryNode initializes and starts an in-memory node for testing. +// It returns the node instance and its RPC remote address. +func TestingInMemoryNode(t TestingTS, logger log.Logger, config *gnoland.InMemoryNodeConfig) (*node.Node, string) { + node, err := gnoland.NewInMemoryNode(logger, config) + require.NoError(t, err) + + err = node.Start() + require.NoError(t, err) + + select { + case <-waitForNodeReadiness(node): + case <-time.After(time.Second * 6): + require.FailNow(t, "timeout while waiting for the node to start") + } + + return node, node.Config().RPC.ListenAddress +} + +// TestingNodeConfig constructs an in-memory node configuration +// with default packages and genesis transactions already loaded. +// It will return the default creator address of the loaded packages. +func TestingNodeConfig(t TestingTS, gnoroot string) (*gnoland.InMemoryNodeConfig, bft.Address) { + cfg := TestingMinimalNodeConfig(t, gnoroot) + + creator := crypto.MustAddressFromString(DefaultAccount_Address) // test1 + + balances := LoadDefaultGenesisBalanceFile(t, gnoroot) + txs := []std.Tx{} + txs = append(txs, LoadDefaultPackages(t, creator, gnoroot)...) + txs = append(txs, LoadDefaultGenesisTXsFile(t, cfg.Genesis.ChainID, gnoroot)...) + + cfg.Genesis.AppState = gnoland.GnoGenesisState{ + Balances: balances, + Txs: txs, + } + + return cfg, creator +} + +// TestingMinimalNodeConfig constructs the default minimal in-memory node configuration for testing. +func TestingMinimalNodeConfig(t TestingTS, gnoroot string) *gnoland.InMemoryNodeConfig { + tmconfig := DefaultTestingTMConfig(gnoroot) + + // Create Mocked Identity + pv := gnoland.NewMockedPrivValidator() + + // Generate genesis config + genesis := DefaultTestingGenesisConfig(t, gnoroot, pv.GetPubKey(), tmconfig) + + return &gnoland.InMemoryNodeConfig{ + PrivValidator: pv, + Genesis: genesis, + TMConfig: tmconfig, + } +} + +func DefaultTestingGenesisConfig(t TestingTS, gnoroot string, self crypto.PubKey, tmconfig *tmcfg.Config) *bft.GenesisDoc { + return &bft.GenesisDoc{ + GenesisTime: time.Now(), + ChainID: tmconfig.ChainID(), + ConsensusParams: abci.ConsensusParams{ + Block: &abci.BlockParams{ + MaxTxBytes: 1_000_000, // 1MB, + MaxDataBytes: 2_000_000, // 2MB, + MaxGas: 10_0000_000, // 10M gas + TimeIotaMS: 100, // 100ms + }, + }, + Validators: []bft.GenesisValidator{ + { + Address: self.Address(), + PubKey: self, + Power: 10, + Name: "self", + }, + }, + AppState: gnoland.GnoGenesisState{ + Balances: []gnoland.Balance{ + { + Address: crypto.MustAddressFromString(DefaultAccount_Address), + Amount: std.MustParseCoins("10000000000000ugnot"), + }, + }, + Txs: []std.Tx{}, + }, + } +} + +// LoadDefaultPackages loads the default packages for testing using a given creator address and gnoroot directory. +func LoadDefaultPackages(t TestingTS, creator bft.Address, gnoroot string) []std.Tx { + examplesDir := filepath.Join(gnoroot, "examples") + + defaultFee := std.NewFee(50000, std.MustParseCoin("1000000ugnot")) + defaultCreator := crypto.MustAddressFromString(DefaultAccount_Address) // test1 + txs, err := gnoland.LoadPackagesFromDir(examplesDir, defaultCreator, defaultFee, nil) + require.NoError(t, err) + + return txs +} + +// LoadDefaultGenesisBalanceFile loads the default genesis balance file for testing. +func LoadDefaultGenesisBalanceFile(t TestingTS, gnoroot string) []gnoland.Balance { + balanceFile := filepath.Join(gnoroot, "gno.land", "genesis", "genesis_balances.txt") + + genesisBalances, err := gnoland.LoadGenesisBalancesFile(balanceFile) + require.NoError(t, err) + + return genesisBalances +} + +// LoadDefaultGenesisTXsFile loads the default genesis transactions file for testing. +func LoadDefaultGenesisTXsFile(t TestingTS, chainid string, gnoroot string) []std.Tx { + txsFile := filepath.Join(gnoroot, "gno.land", "genesis", "genesis_txs.txt") + + // NOTE: We dont care about giving a correct address here, as it's only for display + // XXX: Do we care loading this TXs for testing ? + genesisTXs, err := gnoland.LoadGenesisTxsFile(txsFile, chainid, "https://127.0.0.1:26657") + require.NoError(t, err) + + return genesisTXs +} + +// DefaultTestingTMConfig constructs the default Tendermint configuration for testing. +func DefaultTestingTMConfig(gnoroot string) *tmcfg.Config { + const defaultListner = "tcp://127.0.0.1:0" + + tmconfig := tmcfg.TestConfig().SetRootDir(gnoroot) + tmconfig.Consensus.CreateEmptyBlocks = true + tmconfig.Consensus.CreateEmptyBlocksInterval = time.Duration(0) + tmconfig.RPC.ListenAddress = defaultListner + tmconfig.P2P.ListenAddress = defaultListner + return tmconfig +} + +// waitForNodeReadiness waits until the node is ready, signaling via the EventNewBlock event. +// XXX: This should be replace by https://github.com/gnolang/gno/pull/1216 +func waitForNodeReadiness(n *node.Node) <-chan struct{} { + const listenerID = "first_block_listener" + + var once sync.Once + + nb := make(chan struct{}) + ready := func() { + close(nb) + n.EventSwitch().RemoveListener(listenerID) + } + + n.EventSwitch().AddListener(listenerID, func(ev events.Event) { + if _, ok := ev.(bft.EventNewBlock); ok { + once.Do(ready) + } + }) + + if n.BlockStore().Height() > 0 { + once.Do(ready) + } + + return nb +} From a88e3e37923ab6ca562ca0d7d39606e490d9a736 Mon Sep 17 00:00:00 2001 From: Guilhem Fanton <8671905+gfanton@users.noreply.github.com> Date: Tue, 7 Nov 2023 14:28:50 +0100 Subject: [PATCH 11/25] feat: setup testscripts coverage (#1249) Co-authored-by: Manfred Touron <94029+moul@users.noreply.github.com> --- .github/workflows/gnovm.yml | 43 ++++++++++-- gnovm/Makefile | 18 ++--- gnovm/cmd/gno/build_test.go | 18 ++++- gnovm/cmd/gno/main_test.go | 44 ------------ gnovm/cmd/gno/test_test.go | 18 ++++- gnovm/pkg/integration/coverage.go | 68 +++++++++++++++++++ gnovm/pkg/integration/gno.go | 108 ++++++++++++++++++++++++++++++ 7 files changed, 255 insertions(+), 62 deletions(-) create mode 100644 gnovm/pkg/integration/coverage.go create mode 100644 gnovm/pkg/integration/gno.go diff --git a/.github/workflows/gnovm.yml b/.github/workflows/gnovm.yml index 71b03b5ca05..5fa68ac305a 100644 --- a/.github/workflows/gnovm.yml +++ b/.github/workflows/gnovm.yml @@ -67,6 +67,8 @@ jobs: - _test.gnolang.other runs-on: ubuntu-latest timeout-minutes: 15 + env: + COVERAGE_DIR: "/tmp/coverage" steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v4 @@ -74,28 +76,59 @@ jobs: go-version: ${{ matrix.goversion }} - name: test working-directory: gnovm + env: + TXTARCOVERDIR: ${{ env.COVERAGE_DIR }} run: | + mkdir -p $COVERAGE_DIR + + # Setup testing environements variables export GOPATH=$HOME/go - export GOTEST_FLAGS="-v -p 1 -timeout=30m -coverprofile=coverage.out -covermode=atomic" + export GOTEST_FLAGS="-v -p 1 -timeout=30m -covermode=atomic -test.gocoverdir=$COVERAGE_DIR" + + # Run target test make ${{ matrix.args }} - uses: actions/upload-artifact@v3 if: ${{ runner.os == 'Linux' && matrix.goversion == '1.21.x' }} with: name: ${{runner.os}}-coverage-gnovm-${{ matrix.args}}-${{matrix.goversion}} - path: ./gnovm/coverage.out + path: ${{ env.COVERAGE_DIR }} upload-coverage: needs: test runs-on: ubuntu-latest + env: + COVERAGE_DATA: /tmp/coverage/coverage-raw + COVERAGE_OUTPUT: /tmp/coverage/coverage-out + COVERAGE_PROFILE: /tmp/coverage/coverage.txt steps: - - name: Download all previous coverage artifacts + - run: mkdir -p $COVERAGE_DATA $COVERAGE_OUTPUT + - name: Download all previous coverage data artifacts uses: actions/download-artifact@v3 with: - path: ${{ runner.temp }}/coverage + path: ${{ env.COVERAGE_DATA }} + - uses: actions/setup-go@v4 + with: + go-version: "1.21.x" + - name: Merge coverages + working-directory: ${{ env.COVERAGE_DATA }} + run: | + # Create coverage directory list separate by comma + export COVERAGE_DIRS="$(ls | tr '\n' ',' | sed s/,$//)" + + # Merge all coverage data directories from previous tests + go tool covdata merge -v 1 -i="$COVERAGE_DIRS" -o $COVERAGE_OUTPUT + + # Print coverage percent for debug purpose if needed + echo 'coverage results:' + go tool covdata percent -i=$COVERAGE_OUTPUT + + # Generate coverage profile + go tool covdata textfmt -v 1 -i=$COVERAGE_OUTPUT -o $COVERAGE_PROFILE + - name: Upload combined coverage to Codecov uses: codecov/codecov-action@v3 with: - directory: ${{ runner.temp }}/coverage + files: ${{ env.COVERAGE_PROFILE }} token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: ${{ github.repository == 'gnolang/gno' }} diff --git a/gnovm/Makefile b/gnovm/Makefile index 5fcacf94f62..34e94f88633 100644 --- a/gnovm/Makefile +++ b/gnovm/Makefile @@ -46,15 +46,15 @@ _test.pkg: .PHONY: _test.gnolang _test.gnolang: _test.gnolang.native _test.gnolang.stdlibs _test.gnolang.realm _test.gnolang.pkg0 _test.gnolang.pkg1 _test.gnolang.pkg2 _test.gnolang.other -_test.gnolang.other:; go test $(GOTEST_FLAGS) tests/*.go -run "(TestFileStr|TestSelectors)" -_test.gnolang.realm:; go test $(GOTEST_FLAGS) tests/*.go -run "TestFiles/^zrealm" -_test.gnolang.pkg0:; go test $(GOTEST_FLAGS) tests/*.go -run "TestPackages/(bufio|crypto|encoding|errors|internal|io|math|sort|std|stdshim|strconv|strings|testing|unicode)" -_test.gnolang.pkg1:; go test $(GOTEST_FLAGS) tests/*.go -run "TestPackages/regexp" -_test.gnolang.pkg2:; go test $(GOTEST_FLAGS) tests/*.go -run "TestPackages/bytes" -_test.gnolang.native:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run "TestFilesNative/" -_test.gnolang.stdlibs:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run 'TestFiles$$/' -_test.gnolang.native.sync:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run "TestFilesNative/" --update-golden-tests -_test.gnolang.stdlibs.sync:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run 'TestFiles$$/' --update-golden-tests +_test.gnolang.other:; go test tests/*.go -run "(TestFileStr|TestSelectors)" $(GOTEST_FLAGS) +_test.gnolang.realm:; go test tests/*.go -run "TestFiles/^zrealm" $(GOTEST_FLAGS) +_test.gnolang.pkg0:; go test tests/*.go -run "TestPackages/(bufio|crypto|encoding|errors|internal|io|math|sort|std|stdshim|strconv|strings|testing|unicode)" $(GOTEST_FLAGS) +_test.gnolang.pkg1:; go test tests/*.go -run "TestPackages/regexp" $(GOTEST_FLAGS) +_test.gnolang.pkg2:; go test tests/*.go -run "TestPackages/bytes" $(GOTEST_FLAGS) +_test.gnolang.native:; go test tests/*.go -test.short -run "TestFilesNative/" $(GOTEST_FLAGS) +_test.gnolang.stdlibs:; go test tests/*.go -test.short -run 'TestFiles$$/' $(GOTEST_FLAGS) +_test.gnolang.native.sync:; go test tests/*.go -test.short -run "TestFilesNative/" --update-golden-tests $(GOTEST_FLAGS) +_test.gnolang.stdlibs.sync:; go test tests/*.go -test.short -run 'TestFiles$$/' --update-golden-tests $(GOTEST_FLAGS) ######################################## # Code gen diff --git a/gnovm/cmd/gno/build_test.go b/gnovm/cmd/gno/build_test.go index 5bb03ef0d35..81aed7d1c79 100644 --- a/gnovm/cmd/gno/build_test.go +++ b/gnovm/cmd/gno/build_test.go @@ -3,9 +3,23 @@ package main import ( "testing" + "github.com/gnolang/gno/gnovm/pkg/integration" "github.com/rogpeppe/go-internal/testscript" + "github.com/stretchr/testify/require" ) -func TestBuild(t *testing.T) { - testscript.Run(t, setupTestScript(t, "testdata/gno_build")) +func Test_ScriptsBuild(t *testing.T) { + p := testscript.Params{ + Dir: "testdata/gno_build", + } + + if coverdir, ok := integration.ResolveCoverageDir(); ok { + err := integration.SetupTestscriptsCoverage(&p, coverdir) + require.NoError(t, err) + } + + err := integration.SetupGno(&p, t.TempDir()) + require.NoError(t, err) + + testscript.Run(t, p) } diff --git a/gnovm/cmd/gno/main_test.go b/gnovm/cmd/gno/main_test.go index 8d19a50e814..371cdf913e8 100644 --- a/gnovm/cmd/gno/main_test.go +++ b/gnovm/cmd/gno/main_test.go @@ -5,12 +5,10 @@ import ( "context" "fmt" "os" - "os/exec" "path/filepath" "strings" "testing" - "github.com/rogpeppe/go-internal/testscript" "github.com/stretchr/testify/require" "github.com/gnolang/gno/tm2/pkg/commands" @@ -144,45 +142,3 @@ func testMainCaseRun(t *testing.T, tc []testMainCase) { }) } } - -func setupTestScript(t *testing.T, txtarDir string) testscript.Params { - t.Helper() - // Get root location of github.com/gnolang/gno - goModPath, err := exec.Command("go", "env", "GOMOD").CombinedOutput() - require.NoError(t, err) - rootDir := filepath.Dir(string(goModPath)) - // Build a fresh gno binary in a temp directory - gnoBin := filepath.Join(t.TempDir(), "gno") - err = exec.Command("go", "build", "-o", gnoBin, filepath.Join(rootDir, "gnovm", "cmd", "gno")).Run() - require.NoError(t, err) - // Define script params - return testscript.Params{ - Setup: func(env *testscript.Env) error { - env.Vars = append(env.Vars, - "GNOROOT="+rootDir, // thx PR 1014 :) - // by default, $HOME=/no-home, but we need an existing $HOME directory - // because some commands needs to access $HOME/.cache/go-build - "HOME="+t.TempDir(), - ) - return nil - }, - Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){ - // add a custom "gno" command so txtar files can easily execute "gno" - // without knowing where is the binary or how it is executed. - "gno": func(ts *testscript.TestScript, neg bool, args []string) { - err := ts.Exec(gnoBin, args...) - if err != nil { - ts.Logf("[%v]\n", err) - if !neg { - ts.Fatalf("unexpected gno command failure") - } - } else { - if neg { - ts.Fatalf("unexpected gno command success") - } - } - }, - }, - Dir: txtarDir, - } -} diff --git a/gnovm/cmd/gno/test_test.go b/gnovm/cmd/gno/test_test.go index f5b069a5f03..b1dcfb21d29 100644 --- a/gnovm/cmd/gno/test_test.go +++ b/gnovm/cmd/gno/test_test.go @@ -3,9 +3,23 @@ package main import ( "testing" + "github.com/gnolang/gno/gnovm/pkg/integration" "github.com/rogpeppe/go-internal/testscript" + "github.com/stretchr/testify/require" ) -func TestTest(t *testing.T) { - testscript.Run(t, setupTestScript(t, "testdata/gno_test")) +func Test_ScriptsTest(t *testing.T) { + p := testscript.Params{ + Dir: "testdata/gno_test", + } + + if coverdir, ok := integration.ResolveCoverageDir(); ok { + err := integration.SetupTestscriptsCoverage(&p, coverdir) + require.NoError(t, err) + } + + err := integration.SetupGno(&p, t.TempDir()) + require.NoError(t, err) + + testscript.Run(t, p) } diff --git a/gnovm/pkg/integration/coverage.go b/gnovm/pkg/integration/coverage.go new file mode 100644 index 00000000000..017f5f9de88 --- /dev/null +++ b/gnovm/pkg/integration/coverage.go @@ -0,0 +1,68 @@ +package integration + +import ( + "flag" + "fmt" + "os" + "path/filepath" + + "github.com/rogpeppe/go-internal/testscript" +) + +var coverageEnv struct { + coverdir string +} + +func init() { + flag.StringVar(&coverageEnv.coverdir, + "txtarcoverdir", "", "write testscripts coverage intermediate files to this directory") +} + +// ResolveCoverageDir attempts to resolve the coverage directory from the 'TXTARCOVERDIR' +// environment variable first, and if not set, from the 'test.txtarcoverdir' flag. +// It returns the resolved directory and a boolean indicating if the resolution was successful. +func ResolveCoverageDir() (string, bool) { + // Attempt to resolve the cover directory from the environment variable or flag + coverdir := os.Getenv("TXTARCOVERDIR") + if coverdir == "" { + coverdir = coverageEnv.coverdir + } + + return coverdir, coverdir != "" +} + +// SetupTestscriptsCoverage sets up the given testscripts environment for coverage. +// It will mostly override `GOCOVERDIR` with the target cover directory +func SetupTestscriptsCoverage(p *testscript.Params, coverdir string) error { + // Check if the given coverage directory exist + info, err := os.Stat(coverdir) + if err != nil { + return fmt.Errorf("output directory %q inaccessible: %w", coverdir, err) + } else if !info.IsDir() { + return fmt.Errorf("output %q not a directory", coverdir) + } + + // We need to have an absolute path here, because current directory + // context will change while executing testscripts. + if !filepath.IsAbs(coverdir) { + var err error + if coverdir, err = filepath.Abs(coverdir); err != nil { + return fmt.Errorf("unable to determine absolute path of %q: %w", coverdir, err) + } + } + + // Backup the original setup function + origSetup := p.Setup + p.Setup = func(env *testscript.Env) error { + if origSetup != nil { + // Call previous setup first + origSetup(env) + } + + // Override `GOCOVEDIR` directory for sub-execution + env.Setenv("GOCOVERDIR", coverdir) + return nil + } + + return nil +} diff --git a/gnovm/pkg/integration/gno.go b/gnovm/pkg/integration/gno.go new file mode 100644 index 00000000000..56e18bbb5db --- /dev/null +++ b/gnovm/pkg/integration/gno.go @@ -0,0 +1,108 @@ +package integration + +import ( + "errors" + "fmt" + "os" + "os/exec" + "path/filepath" + "testing" + + osm "github.com/gnolang/gno/tm2/pkg/os" + "github.com/rogpeppe/go-internal/testscript" +) + +// SetupGno prepares the given testscript environment for tests that utilize the gno command. +// If the `gno` binary doesn't exist, it's built using the `go build` command into the specified buildDir. +// The function also include the `gno` command into `p.Cmds` to and wrap environment into p.Setup +// to correctly set up the environment variables needed for the `gno` command. +func SetupGno(p *testscript.Params, buildDir string) error { + // Try to fetch `GNOROOT` from the environment variables + gnoroot := os.Getenv("GNOROOT") + if gnoroot == "" { + // If `GNOROOT` isn't set, determine the root directory of github.com/gnolang/gno + goModPath, err := exec.Command("go", "env", "GOMOD").CombinedOutput() + if err != nil { + return fmt.Errorf("unable to determine gno root directory") + } + + gnoroot = filepath.Dir(string(goModPath)) + } + + if !osm.DirExists(buildDir) { + return fmt.Errorf("%q does not exist or is not a directory", buildDir) + } + + // Determine the path to the gno binary within the build directory + gnoBin := filepath.Join(buildDir, "gno") + if _, err := os.Stat(gnoBin); err != nil { + if !errors.Is(err, os.ErrNotExist) { + // Handle other potential errors from os.Stat + return err + } + + // Build a fresh gno binary in a temp directory + gnoArgsBuilder := []string{"build", "-o", gnoBin} + + // Forward `-covermode` settings if set + if coverMode := testing.CoverMode(); coverMode != "" { + gnoArgsBuilder = append(gnoArgsBuilder, "-covermode", coverMode) + } + + // Append the path to the gno command source + gnoArgsBuilder = append(gnoArgsBuilder, filepath.Join(gnoroot, "gnovm", "cmd", "gno")) + + if err = exec.Command("go", gnoArgsBuilder...).Run(); err != nil { + return fmt.Errorf("unable to build gno binary: %w", err) + } + } + + // Store the original setup scripts for potential wrapping + origSetup := p.Setup + p.Setup = func(env *testscript.Env) error { + // If there's an original setup, execute it + if origSetup != nil { + if err := origSetup(env); err != nil { + return err + } + } + + // Set the GNOROOT environment variable + env.Setenv("GNOROOT", gnoroot) + + // Create a temporary home directory because certain commands require access to $HOME/.cache/go-build + home, err := os.MkdirTemp("", "gno") + if err != nil { + return fmt.Errorf("unable to create temporary home directory: %w", err) + } + env.Setenv("HOME", home) + + // Cleanup home folder + env.Defer(func() { os.RemoveAll(home) }) + + return nil + } + + // Initialize cmds map if needed + if p.Cmds == nil { + p.Cmds = make(map[string]func(ts *testscript.TestScript, neg bool, args []string)) + } + + // Register the gno command for testscripts + p.Cmds["gno"] = func(ts *testscript.TestScript, neg bool, args []string) { + err := ts.Exec(gnoBin, args...) + if err != nil { + ts.Logf("gno command error: %v", err) + } + + commandSucceeded := (err == nil) + successExpected := !neg + + // Compare the command's success status with the expected outcome. + if commandSucceeded != successExpected { + ts.Fatalf("unexpected gno command outcome (err=%t expected=%t)", commandSucceeded, successExpected) + } + } + + return nil +} From 17322140c6b138c1ee27187c71f4cdc8cf30fa72 Mon Sep 17 00:00:00 2001 From: deelawn Date: Tue, 7 Nov 2023 16:17:29 +0000 Subject: [PATCH 12/25] fix: don't pass value types by reference (#1263) Addresses #1096 These changes ensure that passing non-primitive value types to a function do not result in the modification of the original value, even if the value type is represented as a pointer inside the VM. --- gnovm/pkg/gnolang/op_call.go | 6 ++- gnovm/pkg/gnolang/values.go | 10 +++- gnovm/tests/files/issue-1096.gno | 87 ++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 gnovm/tests/files/issue-1096.gno diff --git a/gnovm/pkg/gnolang/op_call.go b/gnovm/pkg/gnolang/op_call.go index f43a593c50e..8d652667111 100644 --- a/gnovm/pkg/gnolang/op_call.go +++ b/gnovm/pkg/gnolang/op_call.go @@ -154,7 +154,11 @@ func (m *Machine) doOpCall() { } // TODO: some more pt <> pv.Type // reconciliations/conversions necessary. - b.Values[i] = pv + + // Make a copy so that a reference to the arguemnt isn't used + // in cases where the non-primitive value type is represented + // as a pointer, *StructValue, for example. + b.Values[i] = pv.Copy(m.Alloc) } } diff --git a/gnovm/pkg/gnolang/values.go b/gnovm/pkg/gnolang/values.go index 3de74ac0130..3bdd3332e08 100644 --- a/gnovm/pkg/gnolang/values.go +++ b/gnovm/pkg/gnolang/values.go @@ -500,7 +500,15 @@ func (sv *StructValue) Copy(alloc *Allocator) *StructValue { } */ fields := alloc.NewStructFields(len(sv.Fields)) - copy(fields, sv.Fields) + + // Each field needs to be copied individually to ensure that + // value fields are copied as such, even though they may be represented + // as pointers. A good example of this would be a struct that has + // a field that is an array. The value array is represented as a pointer. + for i, field := range sv.Fields { + fields[i] = field.Copy(alloc) + } + return alloc.NewStruct(fields) } diff --git a/gnovm/tests/files/issue-1096.gno b/gnovm/tests/files/issue-1096.gno new file mode 100644 index 00000000000..b0593913401 --- /dev/null +++ b/gnovm/tests/files/issue-1096.gno @@ -0,0 +1,87 @@ +package main + +import "fmt" + +type X struct { + Array [8]int + Test bool +} + +type Y [8]int + +func main() { + x := X{} + x.Array[1] = 888 + println(x.Array[1]) + println(x.Array[2]) + println(x.Test) + + x.manip() + println(x.Array[1]) + println(x.Array[2]) + println(x.Test) + + println("-----") + + y := Y{} + y[1] = 888 + println(y[1]) + println(y[2]) + + y.manip() + println(y[1]) + println(y[2]) + println("-----") + + x = X{} + println(x.Array[1]) + println(x.Array[2]) + println(x.Test) + + x.Array[1] = 888 + println(x.Array[1]) + println(x.Array[2]) + println(x.Test) + + manip(x) + println(x.Array[1]) + println(x.Array[2]) + println(x.Test) +} + +func (x X) manip() { + x.Array[2] = 999 + x.Test = true +} + +func manip(x X) { + x.Array[2] = 999 + x.Test = true +} + +func (y Y) manip() { + y[2] = 111 +} + +// Output: +// 888 +// 0 +// false +// 888 +// 0 +// false +// ----- +// 888 +// 0 +// 888 +// 0 +// ----- +// 0 +// 0 +// false +// 888 +// 0 +// false +// 888 +// 0 +// false From 49a5fa437c9a4fd96c4510ca91bb1f740f00050f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 21:37:07 +0100 Subject: [PATCH 13/25] chore(deps): bump go.etcd.io/bbolt from 1.3.7 to 1.3.8 (#1318) Bumps [go.etcd.io/bbolt](https://github.com/etcd-io/bbolt) from 1.3.7 to 1.3.8.
Release notes

Sourced from go.etcd.io/bbolt's releases.

v1.3.8

See the CHANGELOG for more details.

Commits
  • 42a914d Merge pull request #586 from ahrtr/1.3_64bit_align_20231025
  • f9d290f ensure the stats is always 64bit aligned
  • 4a17732 Merge pull request #444 from jmhbnz/backport-failpoints-injection-2
  • 95acc50 Backport add test cases to simulate mlock failure.
  • 7a13798 Backport perform unmap when failing to mlock or both meta pages corrupted.
  • ad36005 Merge pull request #439 from jmhbnz/backport-failpoints-injection
  • 8165a40 Backport change to error handling logic in db.close().
  • e4e06d2 update the usage of surgery command
  • 1108915 Avoid syscall.Syscall use on OpenBSD
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=go.etcd.io/bbolt&package-manager=go_modules&previous-version=1.3.7&new-version=1.3.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b627bea1ce1..f8b1ecf669b 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/rs/cors v1.10.1 github.com/stretchr/testify v1.8.4 github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c - go.etcd.io/bbolt v1.3.7 + go.etcd.io/bbolt v1.3.8 go.uber.org/multierr v1.9.0 golang.org/x/crypto v0.14.0 golang.org/x/mod v0.14.0 diff --git a/go.sum b/go.sum index 2bbff44d4d1..b9ab94d490c 100644 --- a/go.sum +++ b/go.sum @@ -178,8 +178,8 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= -go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= From 55e88bedf00a3584d919a68d0f4d2e8787363785 Mon Sep 17 00:00:00 2001 From: Lee ByeongJun Date: Wed, 8 Nov 2023 16:46:48 +0900 Subject: [PATCH 14/25] chore: remove deprecated io/ioutil methods (#1277) ## Description Replace depreacated `io/ioutil` to `os` methods --------- Co-authored-by: Manfred Touron <94029+moul@users.noreply.github.com> Co-authored-by: Morgan Bazalgette --- gnovm/pkg/gnolang/nodes.go | 3 +- gnovm/pkg/gnolang/precompile.go | 3 +- gnovm/pkg/gnomod/gnomod.go | 5 +- gnovm/stdlibs/io/export_test.gno | 6 +- gnovm/stdlibs/io/io.gno | 77 +++++++++++++++++ gnovm/stdlibs/io/io_test.gno | 86 ++++++++++++++++++- gnovm/stdlibs/io/ioutil/ioutil.gno | 83 ------------------ gnovm/stdlibs/io/multi_test.gno | 4 +- gnovm/tests/backup/cli1.gno | 4 +- gnovm/tests/backup/cli2.gno | 4 +- gnovm/tests/backup/cli3.gno | 4 +- gnovm/tests/backup/cli4.gno | 4 +- gnovm/tests/backup/cli5.gno | 4 +- gnovm/tests/backup/cli6.gno | 4 +- gnovm/tests/backup/file_access.gno | 5 +- gnovm/tests/backup/ioutil.gno | 16 ---- gnovm/tests/backup/issue-558.gno | 6 +- gnovm/tests/files/{ioutil0.gno => io2.gno} | 4 +- gnovm/tests/files/issue-558b.gno | 4 +- gnovm/tests/imports.go | 8 +- tm2/pkg/amino/genproto/genproto.go | 5 +- tm2/pkg/autofile/autofile_test.go | 7 +- tm2/pkg/bft/config/toml.go | 3 +- tm2/pkg/bft/consensus/common_test.go | 7 +- tm2/pkg/bft/consensus/replay_test.go | 3 +- tm2/pkg/bft/privval/file_test.go | 25 +++--- tm2/pkg/bft/privval/socket_listeners_test.go | 3 +- tm2/pkg/bft/rpc/client/main_test.go | 3 +- tm2/pkg/bft/rpc/lib/client/http_client.go | 8 +- tm2/pkg/bft/rpc/lib/server/handlers.go | 4 +- tm2/pkg/bft/rpc/lib/server/handlers_test.go | 10 +-- .../bft/rpc/lib/server/http_server_test.go | 5 +- tm2/pkg/bft/types/genesis_test.go | 3 +- tm2/pkg/bft/types/part_set_test.go | 4 +- tm2/pkg/db/fsdb.go | 4 +- tm2/pkg/iavl/tree_dotgraph_test.go | 4 +- tm2/pkg/log/tm_logger_test.go | 6 +- tm2/pkg/os/tempfile_test.go | 3 +- tm2/pkg/p2p/upnp/upnp.go | 6 +- 39 files changed, 245 insertions(+), 202 deletions(-) delete mode 100644 gnovm/stdlibs/io/ioutil/ioutil.gno delete mode 100644 gnovm/tests/backup/ioutil.gno rename gnovm/tests/files/{ioutil0.gno => io2.gno} (88%) diff --git a/gnovm/pkg/gnolang/nodes.go b/gnovm/pkg/gnolang/nodes.go index 46308fb3a02..2a9e0b51a97 100644 --- a/gnovm/pkg/gnolang/nodes.go +++ b/gnovm/pkg/gnolang/nodes.go @@ -4,7 +4,6 @@ import ( "fmt" "go/parser" "go/token" - "io/ioutil" "os" "path/filepath" "reflect" @@ -1095,7 +1094,7 @@ func PackageNameFromFileBody(name, body string) Name { // NOTE: panics if package name is invalid. func ReadMemPackage(dir string, pkgPath string) *std.MemPackage { - files, err := ioutil.ReadDir(dir) + files, err := os.ReadDir(dir) if err != nil { panic(err) } diff --git a/gnovm/pkg/gnolang/precompile.go b/gnovm/pkg/gnolang/precompile.go index f7a10d5589a..c3116f25800 100644 --- a/gnovm/pkg/gnolang/precompile.go +++ b/gnovm/pkg/gnolang/precompile.go @@ -7,7 +7,6 @@ import ( "go/format" "go/parser" "go/token" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -112,7 +111,7 @@ func GetPrecompileFilenameAndTags(gnoFilePath string) (targetFilename, tags stri func PrecompileAndCheckMempkg(mempkg *std.MemPackage) error { gofmt := "gofmt" - tmpDir, err := ioutil.TempDir("", mempkg.Name) + tmpDir, err := os.MkdirTemp("", mempkg.Name) if err != nil { return err } diff --git a/gnovm/pkg/gnomod/gnomod.go b/gnovm/pkg/gnomod/gnomod.go index 7bb51d6558a..3c224bafb87 100644 --- a/gnovm/pkg/gnomod/gnomod.go +++ b/gnovm/pkg/gnomod/gnomod.go @@ -3,7 +3,6 @@ package gnomod import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -172,9 +171,9 @@ func CreateGnoModFile(rootDir, modPath string) error { if modPath == "" { // Check .gno files for package name // and use it as modPath - files, err := ioutil.ReadDir(rootDir) + files, err := os.ReadDir(rootDir) if err != nil { - fmt.Errorf("read dir %q: %w", rootDir, err) + return fmt.Errorf("read dir %q: %w", rootDir, err) } var pkgName gnolang.Name diff --git a/gnovm/stdlibs/io/export_test.gno b/gnovm/stdlibs/io/export_test.gno index fa3e8e76f61..6204ffc4591 100644 --- a/gnovm/stdlibs/io/export_test.gno +++ b/gnovm/stdlibs/io/export_test.gno @@ -5,4 +5,8 @@ package io // exported for test -var ErrInvalidWrite = errInvalidWrite +var ( + ErrInvalidWrite = errInvalidWrite + ErrWhence = errWhence + ErrOffset = errOffset +) diff --git a/gnovm/stdlibs/io/io.gno b/gnovm/stdlibs/io/io.gno index 54caf32cb95..6ee52cfe293 100644 --- a/gnovm/stdlibs/io/io.gno +++ b/gnovm/stdlibs/io/io.gno @@ -16,6 +16,8 @@ import ( "errors" ) +// TODO: implement rest of io package after sync package added. + // Seek whence values. const ( SeekStart = 0 // seek relative to the origin of the file @@ -477,6 +479,15 @@ func (l *LimitedReader) Read(p []byte) (n int, err error) { // NewSectionReader returns a SectionReader that reads from r // starting at offset off and stops with EOF after n bytes. func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader { + var remaining int64 + const maxInt64 = 1<<63 - 1 + if off <= maxInt64-n { + remaining = n + off + } else { + // Overflow, with no way to return error. + // Assume we can read up to an offset of `1<<63 - 1` bytes in this case. + remaining = maxInt64 + } return &SectionReader{r, off, off, off + n} } @@ -543,6 +554,53 @@ func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error) { // Size returns the size of the section in bytes. func (s *SectionReader) Size() int64 { return s.limit - s.base } +// An OffsetWriter maps writers at offset base to offset base + off in the underlying writer. +type OffsetWriter struct { + w WriterAt + base int64 // the original offset + off int64 // the current offset +} + +// NewOffsetWriter returns a new OffsetWriter that writes to w starting at offset off. +func NewOffsetWriter(w WriterAt, off int64) *OffsetWriter { + return &OffsetWriter{w: w, off: off} +} + +func (o *OffsetWriter) Write(p []byte) (n int, err error) { + // n, err = o.w.WriterAt(p, o.off) + wa := o.w + n, err = wa.WriteAt(p, o.off) + o.off += int64(n) + return +} + +func (o *OffsetWriter) WriteAt(p []byte, off int64) (n int, err error) { + if off < 0 { + return 0, errOffset + } + + off += o.base + return o.w.WriteAt(p, off) +} + +func (o *OffsetWriter) Seek(offset int64, whence int) (int64, error) { + switch whence { + default: + return 0, errWhence + case SeekStart: + offset += o.base + case SeekCurrent: + offset += o.off + } + + if offset < o.base { + return 0, errOffset + } + + o.off = offset + return offset - o.base, nil +} + // TeeReader returns a Reader that writes to w what it reads from r. // All reads from r performed through it are matched with // corresponding writes to w. There is no internal buffering - @@ -614,7 +672,12 @@ func (discard) ReadFrom(r Reader) (n int64, err error) { // NopCloser returns a ReadCloser with a no-op Close method wrapping // the provided Reader r. +// If r implements WriterTo, the returned ReadCloser will implement WriterTo +// by forwarding calls to r. func NopCloser(r Reader) ReadCloser { + if _, ok := r.(WriterTo); ok { + return nopCloserWriterTo{r} + } return nopCloser{r} } @@ -624,6 +687,16 @@ type nopCloser struct { func (nopCloser) Close() error { return nil } +type nopCloserWriterTo struct { + Reader +} + +func (nopCloserWriterTo) Close() error { return nil } + +func (c nopCloserWriterTo) WriteTo(w Writer) (n int64, err error) { + return c.Reader.(WriterTo).WriteTo(w) +} + // ReadAll reads from r until an error or EOF and returns the data it read. // A successful call returns err == nil, not err == EOF. Because ReadAll is // defined to read from src until EOF, it does not treat an EOF from Read @@ -643,5 +716,9 @@ func ReadAll(r Reader) ([]byte, error) { } return b, err } + if len(b) == cap(b) { + // Add more capacity (let append pick how much). + b = append(b, 0)[:len(b)] + } } } diff --git a/gnovm/stdlibs/io/io_test.gno b/gnovm/stdlibs/io/io_test.gno index a97f6b8c075..613b7d13e35 100644 --- a/gnovm/stdlibs/io/io_test.gno +++ b/gnovm/stdlibs/io/io_test.gno @@ -1,14 +1,15 @@ +package io_test + // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package io_test - import ( "bytes" "errors" "fmt" "io" + "os" "strings" "testing" ) @@ -459,3 +460,84 @@ func TestCopyLargeWriter(t *testing.T) { t.Errorf("Copy error: got %v, want %v", err, want) } } + +func TestNopCloserWriterToForwarding(t *testing.T) { + for _, tc := range [...]struct { + Name string + r io.Reader + }{ + {"not a WriterTo", io.Reader(nil)}, + {"a WriterTo", struct { + io.Reader + io.WriterTo + }{}}, + } { + nc := io.NopCloser(tc.r) + + _, expected := tc.r.(io.WriterTo) + _, got := nc.(io.WriterTo) + if expected != got { + t.Errorf("NopCloser incorrectly forwards WriterTo for %s, got %t want %t", tc.Name, got, expected) + } + } +} + +// XXX os.CreateTemp is not available for now +// func TestOffsetWriter_Seek(t *testing.T) { +// tmpfilename := "TestOffsetWriter_Seek" +// tmpfile, err := os.CreateTemp(t.TempDir(), tmpfilename) +// if err != nil || tmpfile == nil { +// t.Fatalf("CreateTemp(%s) failed: %v", tmpfilename, err) +// } +// defer tmpfile.Close() +// w := NewOffsetWriter(tmpfile, 0) + +// // Should throw error errWhence if whence is not valid +// t.Run("errWhence", func(t *testing.T) { +// for _, whence := range []int{-3, -2, -1, 3, 4, 5} { +// var offset int64 = 0 +// gotOff, gotErr := w.Seek(offset, whence) +// if gotOff != 0 || gotErr != ErrWhence { +// t.Errorf("For whence %d, offset %d, OffsetWriter.Seek got: (%d, %v), want: (%d, %v)", +// whence, offset, gotOff, gotErr, 0, ErrWhence) +// } +// } +// }) + +// // Should throw error errOffset if offset is negative +// t.Run("errOffset", func(t *testing.T) { +// for _, whence := range []int{SeekStart, SeekCurrent} { +// for offset := int64(-3); offset < 0; offset++ { +// gotOff, gotErr := w.Seek(offset, whence) +// if gotOff != 0 || gotErr != ErrOffset { +// t.Errorf("For whence %d, offset %d, OffsetWriter.Seek got: (%d, %v), want: (%d, %v)", +// whence, offset, gotOff, gotErr, 0, ErrOffset) +// } +// } +// } +// }) + +// // Normal tests +// t.Run("normal", func(t *testing.T) { +// tests := []struct { +// offset int64 +// whence int +// returnOff int64 +// }{ +// // keep in order +// {whence: SeekStart, offset: 1, returnOff: 1}, +// {whence: SeekStart, offset: 2, returnOff: 2}, +// {whence: SeekStart, offset: 3, returnOff: 3}, +// {whence: SeekCurrent, offset: 1, returnOff: 4}, +// {whence: SeekCurrent, offset: 2, returnOff: 6}, +// {whence: SeekCurrent, offset: 3, returnOff: 9}, +// } +// for idx, tt := range tests { +// gotOff, gotErr := w.Seek(tt.offset, tt.whence) +// if gotOff != tt.returnOff || gotErr != nil { +// t.Errorf("%d:: For whence %d, offset %d, OffsetWriter.Seek got: (%d, %v), want: (%d, )", +// idx+1, tt.whence, tt.offset, gotOff, gotErr, tt.returnOff) +// } +// } +// }) +// } diff --git a/gnovm/stdlibs/io/ioutil/ioutil.gno b/gnovm/stdlibs/io/ioutil/ioutil.gno deleted file mode 100644 index 935031c0511..00000000000 --- a/gnovm/stdlibs/io/ioutil/ioutil.gno +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ioutil implements some I/O utility functions. -// -// As of Go 1.16, the same functionality is now provided -// by package io or package os, and those implementations -// should be preferred in new code. -// See the specific function documentation for details. -package ioutil - -import ( - "io" -) - -// ReadAll reads from r until an error or EOF and returns the data it read. -// A successful call returns err == nil, not err == EOF. Because ReadAll is -// defined to read from src until EOF, it does not treat an EOF from Read -// as an error to be reported. -// -// As of Go 1.16, this function simply calls io.ReadAll. -func ReadAll(r io.Reader) ([]byte, error) { - return io.ReadAll(r) -} - -/* XXX os and os/fs removed. -// ReadFile reads the file named by filename and returns the contents. -// A successful call returns err == nil, not err == EOF. Because ReadFile -// reads the whole file, it does not treat an EOF from Read as an error -// to be reported. -// -// As of Go 1.16, this function simply calls os.ReadFile. -func ReadFile(filename string) ([]byte, error) { - return os.ReadFile(filename) -} - -// WriteFile writes data to a file named by filename. -// If the file does not exist, WriteFile creates it with permissions perm -// (before umask); otherwise WriteFile truncates it before writing, without changing permissions. -// -// As of Go 1.16, this function simply calls os.WriteFile. -func WriteFile(filename string, data []byte, perm fs.FileMode) error { - return os.WriteFile(filename, data, perm) -} - -// ReadDir reads the directory named by dirname and returns -// a list of fs.FileInfo for the directory's contents, -// sorted by filename. If an error occurs reading the directory, -// ReadDir returns no directory entries along with the error. -// -// As of Go 1.16, os.ReadDir is a more efficient and correct choice: -// it returns a list of fs.DirEntry instead of fs.FileInfo, -// and it returns partial results in the case of an error -// midway through reading a directory. -func ReadDir(dirname string) ([]fs.FileInfo, error) { - f, err := os.Open(dirname) - if err != nil { - return nil, err - } - list, err := f.Readdir(-1) - f.Close() - if err != nil { - return nil, err - } - sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() }) - return list, nil -} -*/ - -// NopCloser returns a ReadCloser with a no-op Close method wrapping -// the provided Reader r. -// -// As of Go 1.16, this function simply calls io.NopCloser. -func NopCloser(r io.Reader) io.ReadCloser { - return io.NopCloser(r) -} - -// Discard is an io.Writer on which all Write calls succeed -// without doing anything. -// -// As of Go 1.16, this value is simply io.Discard. -var Discard io.Writer = io.Discard diff --git a/gnovm/stdlibs/io/multi_test.gno b/gnovm/stdlibs/io/multi_test.gno index ee800b3ec24..31345279318 100644 --- a/gnovm/stdlibs/io/multi_test.gno +++ b/gnovm/stdlibs/io/multi_test.gno @@ -1,9 +1,9 @@ +package io_test + // Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package io_test - import ( "bytes" "crypto/sha1" diff --git a/gnovm/tests/backup/cli1.gno b/gnovm/tests/backup/cli1.gno index 8eb9e8c40d7..843eb461ac2 100644 --- a/gnovm/tests/backup/cli1.gno +++ b/gnovm/tests/backup/cli1.gno @@ -2,7 +2,7 @@ package main import ( "fmt" - "io/ioutil" + "io" "log" "net" "net/http" @@ -13,7 +13,7 @@ func client(uri string) { if err != nil { log.Fatal(err) } - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } diff --git a/gnovm/tests/backup/cli2.gno b/gnovm/tests/backup/cli2.gno index a9e8e53be3a..0be01d2f1a9 100644 --- a/gnovm/tests/backup/cli2.gno +++ b/gnovm/tests/backup/cli2.gno @@ -2,7 +2,7 @@ package main import ( "fmt" - "io/ioutil" + "io" "log" "net" "net/http" @@ -21,7 +21,7 @@ func client(uri string) { if err != nil { log.Fatal(err) } - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } diff --git a/gnovm/tests/backup/cli3.gno b/gnovm/tests/backup/cli3.gno index 1c696d4bc4c..50b11b9e4c3 100644 --- a/gnovm/tests/backup/cli3.gno +++ b/gnovm/tests/backup/cli3.gno @@ -2,7 +2,7 @@ package main import ( "fmt" - "io/ioutil" + "io" "log" "net/http" "net/http/httptest" @@ -13,7 +13,7 @@ func client(uri string) { if err != nil { log.Fatal(err) } - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } diff --git a/gnovm/tests/backup/cli4.gno b/gnovm/tests/backup/cli4.gno index 147b63c3e6e..aab6405917c 100644 --- a/gnovm/tests/backup/cli4.gno +++ b/gnovm/tests/backup/cli4.gno @@ -2,7 +2,7 @@ package main import ( "fmt" - "io/ioutil" + "io" "log" "net/http" "net/http/httptest" @@ -40,7 +40,7 @@ func client(uri string) { if err != nil { log.Fatal(err) } - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } diff --git a/gnovm/tests/backup/cli5.gno b/gnovm/tests/backup/cli5.gno index a2e1787c996..6b536841a6d 100644 --- a/gnovm/tests/backup/cli5.gno +++ b/gnovm/tests/backup/cli5.gno @@ -2,7 +2,7 @@ package main import ( "fmt" - "io/ioutil" + "io" "log" "net/http" "net/http/httptest" @@ -40,7 +40,7 @@ func client(uri string) { if err != nil { log.Fatal(err) } - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } diff --git a/gnovm/tests/backup/cli6.gno b/gnovm/tests/backup/cli6.gno index 89ae9f8b98d..e97da82736e 100644 --- a/gnovm/tests/backup/cli6.gno +++ b/gnovm/tests/backup/cli6.gno @@ -2,7 +2,7 @@ package main import ( "fmt" - "io/ioutil" + "io" "log" "net/http" "net/http/httptest" @@ -41,7 +41,7 @@ func client(uri string) { if err != nil { log.Fatal(err) } - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } diff --git a/gnovm/tests/backup/file_access.gno b/gnovm/tests/backup/file_access.gno index 6d750c44a36..e81cc6a0bee 100644 --- a/gnovm/tests/backup/file_access.gno +++ b/gnovm/tests/backup/file_access.gno @@ -2,12 +2,11 @@ package main import ( "fmt" - "io/ioutil" - "os" + "io" ) func main() { - file, err := ioutil.TempFile("", "yeagibench") + file, err := io.TempFile("", "yeagibench") if err != nil { panic(err) } diff --git a/gnovm/tests/backup/ioutil.gno b/gnovm/tests/backup/ioutil.gno deleted file mode 100644 index eae22b6ea5a..00000000000 --- a/gnovm/tests/backup/ioutil.gno +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "fmt" - "os" -) - -func main() { - _, err := os.ReadFile("__NotExisting__") - if err != nil { - fmt.Println(err.Error()) - } -} - -// Output: -// open __NotExisting__: no such file or directory diff --git a/gnovm/tests/backup/issue-558.gno b/gnovm/tests/backup/issue-558.gno index d36bb4e18a7..e99566f7634 100644 --- a/gnovm/tests/backup/issue-558.gno +++ b/gnovm/tests/backup/issue-558.gno @@ -4,7 +4,7 @@ import ( "errors" "fmt" "io" - "io/ioutil" + "io" "log" "strings" ) @@ -37,7 +37,7 @@ type pipe struct { func newReadAutoCloser(r io.Reader) readAutoCloser { if _, ok := r.(io.Closer); !ok { - return readAutoCloser{ioutil.NopCloser(r)} + return readAutoCloser{io.NopCloser(r)} } return readAutoCloser{r.(io.ReadCloser)} } @@ -45,7 +45,7 @@ func newReadAutoCloser(r io.Reader) readAutoCloser { func main() { p := &pipe{} p.Reader = newReadAutoCloser(strings.NewReader("test")) - b, err := ioutil.ReadAll(p.Reader) + b, err := io.ReadAll(p.Reader) if err != nil { log.Fatal(err) } diff --git a/gnovm/tests/files/ioutil0.gno b/gnovm/tests/files/io2.gno similarity index 88% rename from gnovm/tests/files/ioutil0.gno rename to gnovm/tests/files/io2.gno index 800d237be22..24655f5040c 100644 --- a/gnovm/tests/files/ioutil0.gno +++ b/gnovm/tests/files/io2.gno @@ -2,7 +2,7 @@ package main import ( "fmt" - "io/ioutil" + "io" "log" "strings" ) @@ -10,7 +10,7 @@ import ( func main() { r := strings.NewReader("Go is a general-purpose language designed with systems programming in mind.") - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err != nil { log.Fatal(err) } diff --git a/gnovm/tests/files/issue-558b.gno b/gnovm/tests/files/issue-558b.gno index 686c73b5c88..55eba88c985 100644 --- a/gnovm/tests/files/issue-558b.gno +++ b/gnovm/tests/files/issue-558b.gno @@ -3,7 +3,7 @@ package main import ( "fmt" "io" - "io/ioutil" + "io" "log" "strings" ) @@ -36,7 +36,7 @@ type pipe struct { func newReadAutoCloser(r io.Reader) readAutoCloser { if _, ok := r.(io.Closer); !ok { - return readAutoCloser{ioutil.NopCloser(r)} + return readAutoCloser{io.NopCloser(r)} } return readAutoCloser{r.(io.ReadCloser)} } diff --git a/gnovm/tests/imports.go b/gnovm/tests/imports.go index fc2820ce00e..0741d0b466a 100644 --- a/gnovm/tests/imports.go +++ b/gnovm/tests/imports.go @@ -20,7 +20,6 @@ import ( "image" "image/color" "io" - "io/ioutil" "log" "math" "math/big" @@ -356,16 +355,13 @@ func TestStore(rootDir, filesPath string, stdin io.Reader, stdout, stderr io.Wri case "io": pkg := gno.NewPackageNode("io", pkgPath, nil) pkg.DefineGoNativeValue("EOF", io.EOF) + pkg.DefineGoNativeValue("NopCloser", io.NopCloser) pkg.DefineGoNativeValue("ReadFull", io.ReadFull) + pkg.DefineGoNativeValue("ReadAll", io.ReadAll) pkg.DefineGoNativeType(reflect.TypeOf((*io.ReadCloser)(nil)).Elem()) pkg.DefineGoNativeType(reflect.TypeOf((*io.Closer)(nil)).Elem()) pkg.DefineGoNativeType(reflect.TypeOf((*io.Reader)(nil)).Elem()) return pkg, pkg.NewPackage() - case "io/ioutil": - pkg := gno.NewPackageNode("ioutil", pkgPath, nil) - pkg.DefineGoNativeValue("NopCloser", ioutil.NopCloser) - pkg.DefineGoNativeValue("ReadAll", ioutil.ReadAll) - return pkg, pkg.NewPackage() case "log": pkg := gno.NewPackageNode("log", pkgPath, nil) pkg.DefineGoNativeValue("Fatal", log.Fatal) diff --git a/tm2/pkg/amino/genproto/genproto.go b/tm2/pkg/amino/genproto/genproto.go index 8af73b2690a..4f7154e058c 100644 --- a/tm2/pkg/amino/genproto/genproto.go +++ b/tm2/pkg/amino/genproto/genproto.go @@ -6,7 +6,6 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" "os" "os/exec" "path" @@ -120,7 +119,6 @@ func (p3c *P3Context) GetP3ImportPath(p3type P3Type, implicit bool) string { func (p3c *P3Context) GenerateProto3MessagePartial(p3doc *P3Doc, rt reflect.Type) (p3msg P3Message) { if p3doc.PackageName == "" { panic(fmt.Sprintf("cannot generate message partials in the root package \"\".")) - return } if rt.Kind() == reflect.Ptr { panic("pointers not yet supported. if you meant pointer-preferred (for decoding), pass in rt.Elem()") @@ -220,7 +218,6 @@ func (p3c *P3Context) GenerateProto3MessagePartial(p3doc *P3Doc, rt reflect.Type func (p3c *P3Context) GenerateProto3ListPartial(p3doc *P3Doc, nl NList) (p3msg P3Message) { if p3doc.PackageName == "" { panic(fmt.Sprintf("cannot generate message partials in the root package \"\".")) - return } ep3 := nl.ElemP3Type() @@ -496,7 +493,7 @@ func RunProtoc(pkg *amino.Package, protosDir string) { } } // First generate output to a temp dir. - tempDir, err := ioutil.TempDir("", "amino-genproto") + tempDir, err := os.MkdirTemp("", "amino-genproto") if err != nil { return } diff --git a/tm2/pkg/autofile/autofile_test.go b/tm2/pkg/autofile/autofile_test.go index d50bdca3ce0..d631e0ed265 100644 --- a/tm2/pkg/autofile/autofile_test.go +++ b/tm2/pkg/autofile/autofile_test.go @@ -1,7 +1,6 @@ package autofile import ( - "io/ioutil" "os" "syscall" "testing" @@ -14,7 +13,7 @@ import ( func TestSIGHUP(t *testing.T) { // First, create an AutoFile writing to a tempfile dir - file, err := ioutil.TempFile("", "sighup_test") + file, err := os.CreateTemp("", "sighup_test") require.NoError(t, err) err = file.Close() require.NoError(t, err) @@ -60,7 +59,7 @@ func TestSIGHUP(t *testing.T) { // // Manually modify file permissions, close, and reopen using autofile: // // We expect the file permissions to be changed back to the intended perms. // func TestOpenAutoFilePerms(t *testing.T) { -// file, err := ioutil.TempFile("", "permission_test") +// file, err := os.CreateTemp("", "permission_test") // require.NoError(t, err) // err = file.Close() // require.NoError(t, err) @@ -86,7 +85,7 @@ func TestSIGHUP(t *testing.T) { func TestAutoFileSize(t *testing.T) { // First, create an AutoFile writing to a tempfile dir - f, err := ioutil.TempFile("", "sighup_test") + f, err := os.CreateTemp("", "sighup_test") require.NoError(t, err) err = f.Close() require.NoError(t, err) diff --git a/tm2/pkg/bft/config/toml.go b/tm2/pkg/bft/config/toml.go index fdaa1295342..1599bc78968 100644 --- a/tm2/pkg/bft/config/toml.go +++ b/tm2/pkg/bft/config/toml.go @@ -3,7 +3,6 @@ package config import ( "bytes" "fmt" - "io/ioutil" "os" "path/filepath" "text/template" @@ -308,7 +307,7 @@ func ResetTestRoot(testName string) *Config { func ResetTestRootWithChainID(testName string, chainID string) *Config { // create a unique, concurrency-safe test directory under os.TempDir() - rootDir, err := ioutil.TempDir("", fmt.Sprintf("%s-%s_", chainID, testName)) + rootDir, err := os.MkdirTemp("", fmt.Sprintf("%s-%s_", chainID, testName)) if err != nil { panic(err) } diff --git a/tm2/pkg/bft/consensus/common_test.go b/tm2/pkg/bft/consensus/common_test.go index 7424305c00a..19c96756624 100644 --- a/tm2/pkg/bft/consensus/common_test.go +++ b/tm2/pkg/bft/consensus/common_test.go @@ -3,7 +3,6 @@ package consensus import ( "bytes" "fmt" - "io/ioutil" "os" "path" "path/filepath" @@ -662,11 +661,11 @@ func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerF if i < nValidators { privVal = privVals[i] } else { - tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_") + tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") if err != nil { panic(err) } - tempStateFile, err := ioutil.TempFile("", "priv_validator_state_") + tempStateFile, err := os.CreateTemp("", "priv_validator_state_") if err != nil { panic(err) } @@ -795,7 +794,7 @@ func newCounter() abci.Application { } func newPersistentKVStore() abci.Application { - dir, err := ioutil.TempDir("", "persistent-kvstore") + dir, err := os.MkdirTemp("", "persistent-kvstore") if err != nil { panic(err) } diff --git a/tm2/pkg/bft/consensus/replay_test.go b/tm2/pkg/bft/consensus/replay_test.go index 3174207ef8d..556689ec3f4 100644 --- a/tm2/pkg/bft/consensus/replay_test.go +++ b/tm2/pkg/bft/consensus/replay_test.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path/filepath" "runtime" @@ -604,7 +603,7 @@ func TestMockProxyApp(t *testing.T) { } func tempWALWithData(data []byte) string { - walFile, err := ioutil.TempFile("", "wal") + walFile, err := os.CreateTemp("", "wal") if err != nil { panic(fmt.Sprintf("failed to create temp WAL file: %v", err)) } diff --git a/tm2/pkg/bft/privval/file_test.go b/tm2/pkg/bft/privval/file_test.go index 306db4177e5..36979e19ea3 100644 --- a/tm2/pkg/bft/privval/file_test.go +++ b/tm2/pkg/bft/privval/file_test.go @@ -3,7 +3,6 @@ package privval import ( "encoding/base64" "fmt" - "io/ioutil" "os" "testing" "time" @@ -20,9 +19,9 @@ import ( func TestGenLoadValidator(t *testing.T) { assert := assert.New(t) - tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_") + tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") require.Nil(t, err) - tempStateFile, err := ioutil.TempFile("", "priv_validator_state_") + tempStateFile, err := os.CreateTemp("", "priv_validator_state_") require.Nil(t, err) privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name()) @@ -38,9 +37,9 @@ func TestGenLoadValidator(t *testing.T) { } func TestResetValidator(t *testing.T) { - tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_") + tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") require.Nil(t, err) - tempStateFile, err := ioutil.TempFile("", "priv_validator_state_") + tempStateFile, err := os.CreateTemp("", "priv_validator_state_") require.Nil(t, err) privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name()) @@ -68,9 +67,9 @@ func TestResetValidator(t *testing.T) { func TestLoadOrGenValidator(t *testing.T) { assert := assert.New(t) - tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_") + tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") require.Nil(t, err) - tempStateFile, err := ioutil.TempFile("", "priv_validator_state_") + tempStateFile, err := os.CreateTemp("", "priv_validator_state_") require.Nil(t, err) tempKeyFilePath := tempKeyFile.Name() @@ -160,9 +159,9 @@ func TestUnmarshalValidatorKey(t *testing.T) { func TestSignVote(t *testing.T) { assert := assert.New(t) - tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_") + tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") require.Nil(t, err) - tempStateFile, err := ioutil.TempFile("", "priv_validator_state_") + tempStateFile, err := os.CreateTemp("", "priv_validator_state_") require.Nil(t, err) privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name()) @@ -206,9 +205,9 @@ func TestSignVote(t *testing.T) { func TestSignProposal(t *testing.T) { assert := assert.New(t) - tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_") + tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") require.Nil(t, err) - tempStateFile, err := ioutil.TempFile("", "priv_validator_state_") + tempStateFile, err := os.CreateTemp("", "priv_validator_state_") require.Nil(t, err) privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name()) @@ -248,9 +247,9 @@ func TestSignProposal(t *testing.T) { } func TestDifferByTimestamp(t *testing.T) { - tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_") + tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") require.Nil(t, err) - tempStateFile, err := ioutil.TempFile("", "priv_validator_state_") + tempStateFile, err := os.CreateTemp("", "priv_validator_state_") require.Nil(t, err) privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name()) diff --git a/tm2/pkg/bft/privval/socket_listeners_test.go b/tm2/pkg/bft/privval/socket_listeners_test.go index a3630903197..6ca7863d1fd 100644 --- a/tm2/pkg/bft/privval/socket_listeners_test.go +++ b/tm2/pkg/bft/privval/socket_listeners_test.go @@ -1,7 +1,6 @@ package privval import ( - "io/ioutil" "net" "os" "testing" @@ -29,7 +28,7 @@ type listenerTestCase struct { // testUnixAddr will attempt to obtain a platform-independent temporary file // name for a Unix socket func testUnixAddr() (string, error) { - f, err := ioutil.TempFile("", "tendermint-privval-test-*") + f, err := os.CreateTemp("", "tendermint-privval-test-*") if err != nil { return "", err } diff --git a/tm2/pkg/bft/rpc/client/main_test.go b/tm2/pkg/bft/rpc/client/main_test.go index 58dd9538412..759104a3029 100644 --- a/tm2/pkg/bft/rpc/client/main_test.go +++ b/tm2/pkg/bft/rpc/client/main_test.go @@ -1,7 +1,6 @@ package client_test import ( - "io/ioutil" "os" "testing" @@ -14,7 +13,7 @@ var node *nm.Node func TestMain(m *testing.M) { // start a tendermint node (and kvstore) in the background to test against - dir, err := ioutil.TempDir("/tmp", "rpc-client-test") + dir, err := os.MkdirTemp("/tmp", "rpc-client-test") if err != nil { panic(err) } diff --git a/tm2/pkg/bft/rpc/lib/client/http_client.go b/tm2/pkg/bft/rpc/lib/client/http_client.go index 5a9da9ec052..c02d029f27a 100644 --- a/tm2/pkg/bft/rpc/lib/client/http_client.go +++ b/tm2/pkg/bft/rpc/lib/client/http_client.go @@ -4,7 +4,7 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" + "io" "net" "net/http" "net/url" @@ -201,7 +201,7 @@ func (c *JSONRPCClient) Call(method string, params map[string]interface{}, resul return nil, errors.New("server at '%s' returned %s", c.address, httpResponse.Status) } - responseBytes, err := ioutil.ReadAll(httpResponse.Body) + responseBytes, err := io.ReadAll(httpResponse.Body) if err != nil { return nil, err } @@ -238,7 +238,7 @@ func (c *JSONRPCClient) sendBatch(requests []*jsonRPCBufferedRequest) ([]interfa return nil, errors.New("server at '%s' returned %s", c.address, httpResponse.Status) } - responseBytes, err := ioutil.ReadAll(httpResponse.Body) + responseBytes, err := io.ReadAll(httpResponse.Body) if err != nil { return nil, err } @@ -332,7 +332,7 @@ func (c *URIClient) Call(method string, params map[string]interface{}, result in return nil, errors.New("server at '%s' returned %s", c.address, resp.Status) } - responseBytes, err := ioutil.ReadAll(resp.Body) + responseBytes, err := io.ReadAll(resp.Body) if err != nil { return nil, err } diff --git a/tm2/pkg/bft/rpc/lib/server/handlers.go b/tm2/pkg/bft/rpc/lib/server/handlers.go index aa3fadd4d18..40543e5f465 100644 --- a/tm2/pkg/bft/rpc/lib/server/handlers.go +++ b/tm2/pkg/bft/rpc/lib/server/handlers.go @@ -6,7 +6,7 @@ import ( "encoding/hex" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "reflect" "runtime/debug" @@ -101,7 +101,7 @@ func funcReturnTypes(f interface{}) []reflect.Type { // jsonrpc calls grab the given method's function info and runs reflect.Call func makeJSONRPCHandler(funcMap map[string]*RPCFunc, logger log.Logger) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) if err != nil { WriteRPCResponseHTTP(w, types.RPCInvalidRequestError(types.JSONRPCStringID(""), errors.Wrap(err, "error reading request body"))) return diff --git a/tm2/pkg/bft/rpc/lib/server/handlers_test.go b/tm2/pkg/bft/rpc/lib/server/handlers_test.go index 8bf2cc0f7f1..b7a9445a82d 100644 --- a/tm2/pkg/bft/rpc/lib/server/handlers_test.go +++ b/tm2/pkg/bft/rpc/lib/server/handlers_test.go @@ -3,7 +3,7 @@ package rpcserver_test import ( "bytes" "encoding/json" - "io/ioutil" + "io" "net/http" "net/http/httptest" "strings" @@ -70,7 +70,7 @@ func TestRPCParams(t *testing.T) { res := rec.Result() // Always expecting back a JSONRPCResponse assert.True(t, statusOK(res.StatusCode), "#%d: should always return 2XX", i) - blob, err := ioutil.ReadAll(res.Body) + blob, err := io.ReadAll(res.Body) if err != nil { t.Errorf("#%d: err reading body: %v", i, err) continue @@ -118,7 +118,7 @@ func TestJSONRPCID(t *testing.T) { res := rec.Result() // Always expecting back a JSONRPCResponse assert.True(t, statusOK(res.StatusCode), "#%d: should always return 2XX", i) - blob, err := ioutil.ReadAll(res.Body) + blob, err := io.ReadAll(res.Body) if err != nil { t.Errorf("#%d: err reading body: %v", i, err) continue @@ -147,7 +147,7 @@ func TestRPCNotification(t *testing.T) { // Always expecting back a JSONRPCResponse require.True(t, statusOK(res.StatusCode), "should always return 2XX") - blob, err := ioutil.ReadAll(res.Body) + blob, err := io.ReadAll(res.Body) require.Nil(t, err, "reading from the body should not give back an error") require.Equal(t, len(blob), 0, "a notification SHOULD NOT be responded to by the server") } @@ -182,7 +182,7 @@ func TestRPCNotificationInBatch(t *testing.T) { res := rec.Result() // Always expecting back a JSONRPCResponse assert.True(t, statusOK(res.StatusCode), "#%d: should always return 2XX", i) - blob, err := ioutil.ReadAll(res.Body) + blob, err := io.ReadAll(res.Body) if err != nil { t.Errorf("#%d: err reading body: %v", i, err) continue diff --git a/tm2/pkg/bft/rpc/lib/server/http_server_test.go b/tm2/pkg/bft/rpc/lib/server/http_server_test.go index 6753a339981..aaf817e6d85 100644 --- a/tm2/pkg/bft/rpc/lib/server/http_server_test.go +++ b/tm2/pkg/bft/rpc/lib/server/http_server_test.go @@ -5,7 +5,6 @@ import ( "crypto/tls" "fmt" "io" - "io/ioutil" "net" "net/http" "net/http/httptest" @@ -58,7 +57,7 @@ func TestMaxOpenConnections(t *testing.T) { return } defer r.Body.Close() - io.Copy(ioutil.Discard, r.Body) + io.Copy(io.Discard, r.Body) }() } wg.Wait() @@ -91,7 +90,7 @@ func TestStartHTTPAndTLSServer(t *testing.T) { defer res.Body.Close() assert.Equal(t, http.StatusOK, res.StatusCode) - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) require.NoError(t, err) assert.Equal(t, []byte("some body"), body) } diff --git a/tm2/pkg/bft/types/genesis_test.go b/tm2/pkg/bft/types/genesis_test.go index a8816bed2e7..f8d19324eb5 100644 --- a/tm2/pkg/bft/types/genesis_test.go +++ b/tm2/pkg/bft/types/genesis_test.go @@ -1,7 +1,6 @@ package types import ( - "io/ioutil" "os" "testing" "time" @@ -88,7 +87,7 @@ func TestGenesisGood(t *testing.T) { } func TestGenesisSaveAs(t *testing.T) { - tmpfile, err := ioutil.TempFile("", "genesis") + tmpfile, err := os.CreateTemp("", "genesis") require.NoError(t, err) defer os.Remove(tmpfile.Name()) diff --git a/tm2/pkg/bft/types/part_set_test.go b/tm2/pkg/bft/types/part_set_test.go index 2e05daed849..c4e30c89372 100644 --- a/tm2/pkg/bft/types/part_set_test.go +++ b/tm2/pkg/bft/types/part_set_test.go @@ -1,7 +1,7 @@ package types import ( - "io/ioutil" + "io" "testing" "github.com/stretchr/testify/assert" @@ -54,7 +54,7 @@ func TestBasicPartSet(t *testing.T) { // Reconstruct data, assert that they are equal. data2Reader := partSet2.GetReader() - data2, err := ioutil.ReadAll(data2Reader) + data2, err := io.ReadAll(data2Reader) require.NoError(t, err) assert.Equal(t, data, data2) diff --git a/tm2/pkg/db/fsdb.go b/tm2/pkg/db/fsdb.go index aa8cea83889..e11cd6d4ce5 100644 --- a/tm2/pkg/db/fsdb.go +++ b/tm2/pkg/db/fsdb.go @@ -2,7 +2,7 @@ package db import ( "fmt" - "io/ioutil" + "io" "net/url" "os" "path/filepath" @@ -189,7 +189,7 @@ func read(path string) ([]byte, error) { } defer f.Close() - d, err := ioutil.ReadAll(f) + d, err := io.ReadAll(f) if err != nil { return nil, err } diff --git a/tm2/pkg/iavl/tree_dotgraph_test.go b/tm2/pkg/iavl/tree_dotgraph_test.go index 29be03ca241..f3c2786cda3 100644 --- a/tm2/pkg/iavl/tree_dotgraph_test.go +++ b/tm2/pkg/iavl/tree_dotgraph_test.go @@ -1,7 +1,7 @@ package iavl import ( - "io/ioutil" + "io" "testing" db "github.com/gnolang/gno/tm2/pkg/db" @@ -15,5 +15,5 @@ func TestWriteDOTGraph(t *testing.T) { key := []byte{ikey} tree.Set(key, key) } - WriteDOTGraph(ioutil.Discard, tree.ImmutableTree, []PathToLeaf{}) + WriteDOTGraph(io.Discard, tree.ImmutableTree, []PathToLeaf{}) } diff --git a/tm2/pkg/log/tm_logger_test.go b/tm2/pkg/log/tm_logger_test.go index a6d56bb8feb..81614c5ea21 100644 --- a/tm2/pkg/log/tm_logger_test.go +++ b/tm2/pkg/log/tm_logger_test.go @@ -2,7 +2,7 @@ package log_test import ( "bytes" - "io/ioutil" + "io" "strings" "testing" @@ -21,11 +21,11 @@ func TestLoggerLogsItsErrors(t *testing.T) { } func BenchmarkTMLoggerSimple(b *testing.B) { - benchmarkRunner(b, log.NewTMLogger(ioutil.Discard), baseInfoMessage) + benchmarkRunner(b, log.NewTMLogger(io.Discard), baseInfoMessage) } func BenchmarkTMLoggerContextual(b *testing.B) { - benchmarkRunner(b, log.NewTMLogger(ioutil.Discard), withInfoMessage) + benchmarkRunner(b, log.NewTMLogger(io.Discard), withInfoMessage) } func benchmarkRunner(b *testing.B, logger log.Logger, f func(log.Logger)) { diff --git a/tm2/pkg/os/tempfile_test.go b/tm2/pkg/os/tempfile_test.go index 12d6abb27cb..ec294d58e30 100644 --- a/tm2/pkg/os/tempfile_test.go +++ b/tm2/pkg/os/tempfile_test.go @@ -5,7 +5,6 @@ package os import ( "bytes" "fmt" - "io/ioutil" "os" "testing" @@ -21,7 +20,7 @@ func TestWriteFileAtomic(t *testing.T) { perm os.FileMode = 0o600 ) - f, err := ioutil.TempFile("/tmp", "write-atomic-test-") + f, err := os.CreateTemp("/tmp", "write-atomic-test-") if err != nil { t.Fatal(err) } diff --git a/tm2/pkg/p2p/upnp/upnp.go b/tm2/pkg/p2p/upnp/upnp.go index 40f2067e232..cd47ac35553 100644 --- a/tm2/pkg/p2p/upnp/upnp.go +++ b/tm2/pkg/p2p/upnp/upnp.go @@ -10,7 +10,7 @@ import ( "encoding/xml" "errors" "fmt" - "io/ioutil" + "io" "net" "net/http" "strconv" @@ -306,7 +306,7 @@ func (n *upnpNAT) getExternalIPAddress() (info statusInfo, err error) { return } var envelope Envelope - data, err := ioutil.ReadAll(response.Body) + data, err := io.ReadAll(response.Body) if err != nil { return } @@ -363,7 +363,7 @@ func (n *upnpNAT) AddPortMapping(protocol string, externalPort, internalPort int // TODO: check response to see if the port was forwarded // log.Println(message, response) // JAE: - // body, err := ioutil.ReadAll(response.Body) + // body, err := io.ReadAll(response.Body) // fmt.Println(string(body), err) mappedExternalPort = externalPort _ = response From 31d2ce95845c8e8c286e703f589447a5476d8b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milo=C5=A1=20=C5=BDivkovi=C4=87?= Date: Wed, 8 Nov 2023 09:15:04 +0100 Subject: [PATCH 15/25] feat: add `unused` linter (#1294) ## Description This PR adds the `unused` linter to the linter configuration, and removes unused code segments
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [ ] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--- .github/golangci.yml | 27 ++- gnovm/pkg/gnolang/helpers.go | 12 -- gnovm/pkg/gnolang/preprocess.go | 24 --- gnovm/pkg/gnolang/scanner.go | 18 -- gnovm/pkg/gnolang/store.go | 8 +- gnovm/pkg/gnolang/types.go | 1 - gnovm/stdlibs/stdlibs.go | 10 - misc/logos/buffer.go | 12 +- misc/logos/cmd/logos.go | 5 - misc/logos/debug.go | 26 --- misc/logos/types.go | 14 +- misc/logos/unicode.go | 11 +- tm2/pkg/amino/binary_decode.go | 8 - tm2/pkg/amino/codec_test.go | 3 - tm2/pkg/amino/genproto/bindings.go | 117 +---------- tm2/pkg/amino/genproto/example/main.go | 4 - tm2/pkg/amino/genproto/scanner.go | 192 ------------------ tm2/pkg/amino/reflect.go | 31 +-- tm2/pkg/amino/tests/common.go | 2 - tm2/pkg/bft/abci/client/client.go | 9 +- tm2/pkg/bft/consensus/common_test.go | 10 - tm2/pkg/bft/consensus/replay.go | 3 - tm2/pkg/bft/consensus/state_test.go | 14 +- tm2/pkg/bft/consensus/wal_generator.go | 4 +- tm2/pkg/bft/consensus/wal_test.go | 7 +- tm2/pkg/bft/node/node.go | 1 - .../privval/signer_listener_endpoint_test.go | 2 +- tm2/pkg/bft/rpc/core/pipe.go | 15 -- tm2/pkg/bft/rpc/lib/client/ws_client.go | 2 +- tm2/pkg/bft/rpc/lib/server/handlers_test.go | 6 +- tm2/pkg/bft/state/helpers_test.go | 20 +- tm2/pkg/bft/types/validator_set.go | 10 +- tm2/pkg/bft/wal/wal.go | 4 +- tm2/pkg/bft/wal/wal_test.go | 2 +- tm2/pkg/crypto/keys/client/export_test.go | 8 +- tm2/pkg/crypto/keys/keybase.go | 8 - tm2/pkg/crypto/merkle/proof_test.go | 15 +- tm2/pkg/crypto/util.go | 7 - tm2/pkg/events/store.go | 23 +-- tm2/pkg/iavl/benchmarks/bench_test.go | 30 --- tm2/pkg/iavl/node.go | 4 - tm2/pkg/iavl/nodedb.go | 2 +- tm2/pkg/iavl/proof_path.go | 57 ------ tm2/pkg/iavl/proof_range.go | 4 +- tm2/pkg/iavl/tree_test.go | 2 +- tm2/pkg/p2p/config/config.go | 4 +- tm2/pkg/p2p/switch.go | 4 - tm2/pkg/sdk/auth/test_common.go | 27 --- tm2/pkg/sdk/baseapp_test.go | 6 +- tm2/pkg/std/coin.go | 2 - tm2/pkg/store/gas/store_test.go | 6 - tm2/pkg/store/rootmulti/dbadapter.go | 33 --- 52 files changed, 89 insertions(+), 787 deletions(-) delete mode 100644 misc/logos/debug.go delete mode 100644 tm2/pkg/amino/genproto/scanner.go delete mode 100644 tm2/pkg/crypto/util.go delete mode 100644 tm2/pkg/store/rootmulti/dbadapter.go diff --git a/.github/golangci.yml b/.github/golangci.yml index 992398956b1..53141a3143d 100644 --- a/.github/golangci.yml +++ b/.github/golangci.yml @@ -1,9 +1,20 @@ run: - timeout: 5m + concurrency: 8 + timeout: 10m + issue-exit-code: 1 tests: true skip-dirs-use-default: true + modules-download-mode: readonly + allow-parallel-runners: false + go: "" + +output: + uniq-by-line: false + path-prefix: "" + sort-results: true linters: + fast: false disable-all: true enable: - whitespace # Tool for detection of leading and trailing whitespace @@ -21,12 +32,11 @@ linters: - gofmt # Whether the code was gofmt-ed - goimports # Unused imports - goconst # Repeated strings that could be replaced by a constant - #- forcetypeassert # Finds forced type assertions - dogsled # Checks assignments with too many blank identifiers (e.g. x, , , _, := f()) - #- dupl # Code clone detection - errname # Checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13 - gofumpt # Stricter gofmt + - unused # Checks Go code for unused constants, variables, functions and types linters-settings: gofmt: @@ -42,9 +52,20 @@ linters-settings: checks: [ "all", "-ST1022", "-ST1003" ] errorlint: asserts: false + gocritic: + enabled-tags: + - diagnostic + - experimental + - opinionated + - performance + - style issues: whole-files: true + max-issues-per-linter: 0 + max-same-issues: 0 + new: false + fix: false exclude-rules: - path: _test\.go linters: diff --git a/gnovm/pkg/gnolang/helpers.go b/gnovm/pkg/gnolang/helpers.go index c16ea795ea3..4810a67304a 100644 --- a/gnovm/pkg/gnolang/helpers.go +++ b/gnovm/pkg/gnolang/helpers.go @@ -440,18 +440,6 @@ var ( precs = [][]string{prec1, prec2, prec3, prec4, prec5} ) -// 0 for prec1... -1 if no match. -func lowestMatch(op string) int { - for i, prec := range precs { - for _, op2 := range prec { - if op == op2 { - return i - } - } - } - return -1 -} - func Ss(b ...Stmt) []Stmt { return b } diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index e02a158fcf1..1a1edc41222 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -3338,23 +3338,6 @@ func elideCompositeExpr(vx *Expr, vt Type) { } } -// returns true of x is exactly `nil`. -func isNilExpr(x Expr) bool { - if nx, ok := x.(*NameExpr); ok { - return nx.Name == nilStr - } - return false -} - -func isNilComparableKind(k Kind) bool { - switch k { - case SliceKind, MapKind, FuncKind: - return true - default: - return false - } -} - // returns number of args, or if arg is a call result, // the number of results of the return tuple type. func countNumArgs(store Store, last BlockNode, n *CallExpr) (numArgs int) { @@ -3374,13 +3357,6 @@ func countNumArgs(store Store, last BlockNode, n *CallExpr) (numArgs int) { } } -func mergeNames(a, b []Name) []Name { - c := make([]Name, len(a)+len(b)) - copy(c, a) - copy(c[len(a):], b) - return c -} - // This is to be run *after* preprocessing is done, // to determine the order of var decl execution // (which may include functions which may refer to package vars). diff --git a/gnovm/pkg/gnolang/scanner.go b/gnovm/pkg/gnolang/scanner.go index 87695c0f346..f0b3f34c9ad 100644 --- a/gnovm/pkg/gnolang/scanner.go +++ b/gnovm/pkg/gnolang/scanner.go @@ -192,21 +192,3 @@ func (ss *scanner) advanceEscapeSequence() bool { return ss.done() } } - -// pops the next monoid term. -// The result is a string enclosed in balanced parentheses, -// brackets, or quotes; or what comes before such things. -// scanner doesn't understand operators, so a polynomial -// expression could be a single monoid as far as this scanner -// is concerned. TODO Chop functions should maybe use this. -func (ss *scanner) popMonoid() string { - startOut := ss.out() - start := ss.idx - for !ss.advance() { - if ss.out() != startOut { - end := ss.idx - return string(ss.rnz[start:end]) - } - } - panic("no monoid") -} diff --git a/gnovm/pkg/gnolang/store.go b/gnovm/pkg/gnolang/store.go index d3628edf216..24aff4936f3 100644 --- a/gnovm/pkg/gnolang/store.go +++ b/gnovm/pkg/gnolang/store.go @@ -11,8 +11,6 @@ import ( "github.com/gnolang/gno/tm2/pkg/store" ) -const iavlCacheSize = 1024 * 1024 // TODO increase and parameterize. - // return nil if package doesn't exist. type PackageGetter func(pkgPath string) (*PackageNode, *PackageValue) @@ -626,7 +624,7 @@ func (ds *defaultStore) Flush() { // XXX } -//---------------------------------------- +// ---------------------------------------- // StoreOp type StoreOpType uint8 @@ -723,7 +721,7 @@ func (ds *defaultStore) Print() { } } -//---------------------------------------- +// ---------------------------------------- // backend keys func backendObjectKey(oid ObjectID) string { @@ -755,7 +753,7 @@ func backendPackagePathKey(path string) string { return fmt.Sprintf("pkg:" + path) } -//---------------------------------------- +// ---------------------------------------- // builtin types and packages func InitStoreCaches(store Store) { diff --git a/gnovm/pkg/gnolang/types.go b/gnovm/pkg/gnolang/types.go index c3e439e9427..6aed71fcf9b 100644 --- a/gnovm/pkg/gnolang/types.go +++ b/gnovm/pkg/gnolang/types.go @@ -879,7 +879,6 @@ type InterfaceType struct { } // General empty interface. -var gEmptyInterfaceType *InterfaceType = &InterfaceType{} func (it *InterfaceType) IsEmptyInterface() bool { return len(it.Methods) == 0 diff --git a/gnovm/stdlibs/stdlibs.go b/gnovm/stdlibs/stdlibs.go index fb230a0cf86..8931266eb9a 100644 --- a/gnovm/stdlibs/stdlibs.go +++ b/gnovm/stdlibs/stdlibs.go @@ -581,13 +581,3 @@ func typedByteArray(ln int, bz *gno.ArrayValue) gno.TypedValue { tv := gno.TypedValue{T: &gno.ArrayType{Len: ln, Elt: gno.Uint8Type}, V: bz} return tv } - -func typedByteSlice(bz *gno.SliceValue) gno.TypedValue { - tv := gno.TypedValue{T: &gno.SliceType{Elt: gno.Uint8Type}, V: bz} - return tv -} - -func typedNil(t gno.Type) gno.TypedValue { - tv := gno.TypedValue{T: t, V: nil} - return tv -} diff --git a/misc/logos/buffer.go b/misc/logos/buffer.go index 90665f79bfd..81e8d1abc75 100644 --- a/misc/logos/buffer.go +++ b/misc/logos/buffer.go @@ -7,7 +7,7 @@ import ( "github.com/gdamore/tcell/v2" ) -//---------------------------------------- +// ---------------------------------------- // Buffer // A Buffer is a buffer area in which to draw. @@ -82,7 +82,7 @@ func (bb *Buffer) DrawToScreen(s tcell.Screen) { } } -//---------------------------------------- +// ---------------------------------------- // Cell // A terminal character cell. @@ -131,10 +131,6 @@ var gDefaultSpaceTStyle = tcell.StyleDefault. Dim(true). Background(tcell.ColorGray) -var gDefaultTStyle = gDefaultStyle.GetTStyle(). - Foreground(gDefaultForeground). - Background(gDefaultBackground) - // This is where a bit of dynamic logic is performed, // namely where the attr is used to derive the final style. func (cc *Cell) GetTCellContent() (mainc rune, combc []rune, tstyle tcell.Style) { @@ -161,7 +157,7 @@ func (cc *Cell) GetTCellContent() (mainc rune, combc []rune, tstyle tcell.Style) return } -//---------------------------------------- +// ---------------------------------------- // View // analogy: "Buffer:View :: array:slice". @@ -205,7 +201,7 @@ func (bs View) GetCell(x, y int) *Cell { ) } -//---------------------------------------- +// ---------------------------------------- // BufferedView // A view onto an element. diff --git a/misc/logos/cmd/logos.go b/misc/logos/cmd/logos.go index 228895f852d..3a374fecba2 100644 --- a/misc/logos/cmd/logos.go +++ b/misc/logos/cmd/logos.go @@ -10,11 +10,6 @@ import ( "github.com/gnolang/gno/misc/logos" ) -var ( - row = 0 - style = tcell.StyleDefault -) - func main() { encoding.Register() diff --git a/misc/logos/debug.go b/misc/logos/debug.go deleted file mode 100644 index 8b2a4692bf4..00000000000 --- a/misc/logos/debug.go +++ /dev/null @@ -1,26 +0,0 @@ -package logos - -import ( - "fmt" -) - -// NOTE: the golang compiler doesn't seem to be intelligent -// enough to remove steps when const debug is True, -// so it is still faster to first check the truth value -// before calling debug.Println or debug.Printf. - -const debug debugging = false // or flip - -type debugging bool - -func (d debugging) Println(args ...interface{}) { - if d { - fmt.Println(append([]interface{}{"DEBUG:"}, args...)...) - } -} - -func (d debugging) Printf(format string, args ...interface{}) { - if d { - fmt.Printf("DEBUG: "+format, args...) - } -} diff --git a/misc/logos/types.go b/misc/logos/types.go index 944f02515d3..96e983992eb 100644 --- a/misc/logos/types.go +++ b/misc/logos/types.go @@ -7,7 +7,7 @@ import ( "github.com/gdamore/tcell/v2" ) -//---------------------------------------- +// ---------------------------------------- // Page // A Page has renderable Elem(ents). @@ -389,7 +389,7 @@ func (pg *Page) DecCursor(isVertical bool) { } } -//---------------------------------------- +// ---------------------------------------- // TextElem type TextElem struct { @@ -474,8 +474,6 @@ func (tel *TextElem) Render() (updated bool) { return true } -var ctr = 0 - func (tel *TextElem) Draw(offset Coord, view View) { minX, maxX, minY, maxY := computeIntersection(tel.Size, offset, view.Bounds) for y := minY; y < maxY; y++ { @@ -494,7 +492,7 @@ func (tel *TextElem) ProcessEventKey(ev *EventKey) bool { return false // TODO: clipboard. } -//---------------------------------------- +// ---------------------------------------- // misc. type Color = tcell.Color @@ -728,7 +726,7 @@ func (tt *Attrs) Merge(ot *Attrs) { tt.Other = ot.Other // TODO merge by key. } -//---------------------------------------- +// ---------------------------------------- // AttrFlags // NOTE: AttrFlags are merged with a simple or-assign op. @@ -752,7 +750,7 @@ type KVPair struct { Value interface{} } -//---------------------------------------- +// ---------------------------------------- // computeIntersection() // els: element size @@ -812,7 +810,7 @@ func computeIntersection(els Size, elo Coord, vws Size) (minX, maxX, minY, maxY return } -//---------------------------------------- +// ---------------------------------------- // Misc simple types type Padding struct { diff --git a/misc/logos/unicode.go b/misc/logos/unicode.go index 3bdb46cd88b..924edecc2c5 100644 --- a/misc/logos/unicode.go +++ b/misc/logos/unicode.go @@ -4,7 +4,7 @@ func isCombining(r rune) bool { return inTable(r, combining) } -//---------------------------------------- +// ---------------------------------------- // from https://github.com/mattn/go-runewidth // runewidth doesn't expose whether a character is combining or not. // TODO might as well fork both runewidth and tcell. @@ -62,15 +62,6 @@ type interval struct { type table []interval -func inTables(r rune, ts ...table) bool { - for _, t := range ts { - if inTable(r, t) { - return true - } - } - return false -} - func inTable(r rune, t table) bool { if r < t[0].first { return false diff --git a/tm2/pkg/amino/binary_decode.go b/tm2/pkg/amino/binary_decode.go index 8ac4161cede..333994d60b0 100644 --- a/tm2/pkg/amino/binary_decode.go +++ b/tm2/pkg/amino/binary_decode.go @@ -12,14 +12,6 @@ const bdOptionByte = 0x01 // ---------------------------------------- // cdc.decodeReflectBinary -var ErrOverflowInt = errors.New("encoded integer value overflows int(32)") - -const ( - // architecture dependent int limits: - maxInt = int(^uint(0) >> 1) - minInt = -maxInt - 1 -) - // This is the main entrypoint for decoding all types from binary form. This // function calls decodeReflectBinary*, and generally those functions should // only call this one, for overrides all happen here. diff --git a/tm2/pkg/amino/codec_test.go b/tm2/pkg/amino/codec_test.go index 7e025f73271..18bc8f2cd5d 100644 --- a/tm2/pkg/amino/codec_test.go +++ b/tm2/pkg/amino/codec_test.go @@ -214,9 +214,6 @@ func TestEncodeDecodeString(t *testing.T) { } func TestCodecSeal(t *testing.T) { - type Foo interface{} - type Bar interface{} - cdc := amino.NewCodec() cdc.Seal() diff --git a/tm2/pkg/amino/genproto/bindings.go b/tm2/pkg/amino/genproto/bindings.go index 458d8b14578..5d587870a7d 100644 --- a/tm2/pkg/amino/genproto/bindings.go +++ b/tm2/pkg/amino/genproto/bindings.go @@ -105,7 +105,7 @@ func generateMethodsForType(imports *ast.GenDecl, scope *ast.Scope, pkg *amino.P } dpbote_ := pbote_[1:] - ////////////////// + // ----------- // ToPBMessage() { scope2 := ast.NewScope(scope) @@ -127,7 +127,7 @@ func generateMethodsForType(imports *ast.GenDecl, scope *ast.Scope, pkg *amino.P )) } - ////////////////// + // ----------- // EmptyPBMessage() // Use to create the pbm to proto.Unmarshal to before FromPBMessage. { @@ -148,7 +148,7 @@ func generateMethodsForType(imports *ast.GenDecl, scope *ast.Scope, pkg *amino.P )) } - ////////////////// + // ----------- // FromPBMessage() { scope2 := ast.NewScope(scope) @@ -169,7 +169,7 @@ func generateMethodsForType(imports *ast.GenDecl, scope *ast.Scope, pkg *amino.P )) } - ////////////////// + // ----------- // TypeUrl() { methods = append(methods, _func("GetTypeURL", @@ -182,7 +182,7 @@ func generateMethodsForType(imports *ast.GenDecl, scope *ast.Scope, pkg *amino.P )) } - ////////////////// + // ----------- // Is*ReprEmpty() { rinfo := info.ReprType @@ -965,7 +965,7 @@ func isReprEmptyStmts(rootPkg *amino.Package, isRoot bool, imports *ast.GenDecl, return b } -//---------------------------------------- +// ---------------------------------------- // other.... // Splits a Go expression into left and right parts. @@ -1013,7 +1013,7 @@ func chopRight(expr string) (left string, tok rune, right string) { return } -//---------------------------------------- +// ---------------------------------------- // AST Construction (Expr) func _i(name string) *ast.Ident { @@ -1023,14 +1023,6 @@ func _i(name string) *ast.Ident { return &ast.Ident{Name: name} } -func _iOrNil(name string) *ast.Ident { - if name == "" { - return nil - } else { - return _i(name) - } -} - // recvTypeName is empty if there are no receivers. // recvTypeName cannot contain any dots. func _func(name string, recvRef string, recvTypeName string, params *ast.FieldList, results *ast.FieldList, b *ast.BlockStmt) *ast.FuncDecl { @@ -1344,29 +1336,6 @@ func _x(expr string, args ...interface{}) ast.Expr { // 3 == != < <= > >= // 2 && // 1 || -var sp = " " - -var ( - prec5 = strings.Split("* / % << >> & &^", sp) - prec4 = strings.Split("+ - | ^", sp) - prec3 = strings.Split("== != < <= > >=", sp) - prec2 = strings.Split("&&", sp) - prec1 = strings.Split("||", sp) - precs = [][]string{prec1, prec2, prec3, prec4, prec5} -) - -// 0 for prec1... -1 if no match. -func lowestMatch(op string) int { - for i, prec := range precs { - for _, op2 := range prec { - if op == op2 { - return i - } - } - } - return -1 -} - func _kv(k, v interface{}) *ast.KeyValueExpr { var kx, vx ast.Expr if ks, ok := k.(string); ok { @@ -1391,10 +1360,6 @@ func _block(b ...ast.Stmt) *ast.BlockStmt { } } -func _xs(exprs ...ast.Expr) []ast.Expr { - return exprs -} - // Usage: _a(lhs1, lhs2, ..., ":=", rhs1, rhs2, ...) // Token can be ":=", "=", "+=", etc. // Other strings are automatically parsed as _x(arg). @@ -1470,13 +1435,6 @@ func _call(fn ast.Expr, args ...ast.Expr) *ast.CallExpr { } } -func _ta(x ast.Expr, t ast.Expr) *ast.TypeAssertExpr { - return &ast.TypeAssertExpr{ - X: x, - Type: t, - } -} - func _sel(x ast.Expr, sel string) *ast.SelectorExpr { return &ast.SelectorExpr{ X: x, @@ -1532,7 +1490,7 @@ func _sl(x ast.Expr) *ast.ArrayType { } } -//---------------------------------------- +// ---------------------------------------- // AST Construction (Stmt) func _if(cond ast.Expr, b ...ast.Stmt) *ast.IfStmt { @@ -1564,34 +1522,6 @@ func _return(results ...ast.Expr) *ast.ReturnStmt { } } -func _continue(label string) *ast.BranchStmt { - return &ast.BranchStmt{ - Tok: token.CONTINUE, - Label: _i(label), - } -} - -func _break(label string) *ast.BranchStmt { - return &ast.BranchStmt{ - Tok: token.BREAK, - Label: _i(label), - } -} - -func _goto(label string) *ast.BranchStmt { - return &ast.BranchStmt{ - Tok: token.GOTO, - Label: _i(label), - } -} - -func _fallthrough(label string) *ast.BranchStmt { - return &ast.BranchStmt{ - Tok: token.FALLTHROUGH, - Label: _i(label), - } -} - // even/odd args are paired, // name1, path1, name2, path2, etc. func _imports(nameAndPaths ...string) *ast.GenDecl { @@ -1618,15 +1548,6 @@ func _for(init ast.Stmt, cond ast.Expr, post ast.Stmt, b ...ast.Stmt) *ast.ForSt } } -func _loop(b ...ast.Stmt) *ast.ForStmt { - return _for(nil, nil, nil, b...) -} - -func _once(b ...ast.Stmt) *ast.ForStmt { - b = append(b, _break("")) - return _for(nil, nil, nil, b...) -} - func _len(x ast.Expr) *ast.CallExpr { return _call(_i("len"), x) } @@ -1766,7 +1687,7 @@ func _aop(op string) token.Token { } } -//---------------------------------------- +// ---------------------------------------- // AST Compile-Time func _ctif(cond bool, then_, else_ ast.Stmt) ast.Stmt { @@ -1779,7 +1700,7 @@ func _ctif(cond bool, then_, else_ ast.Stmt) ast.Stmt { } } -//---------------------------------------- +// ---------------------------------------- // AST query and manipulation. func importPathForName(name string, imports *ast.GenDecl) (path string, exists bool) { @@ -1800,24 +1721,6 @@ func importPathForName(name string, imports *ast.GenDecl) (path string, exists b return "", false } -func importNameForPath(path string, imports *ast.GenDecl) (name string, exists bool) { - if imports.Tok != token.IMPORT { - panic("unexpected ast.GenDecl token " + imports.Tok.String()) - } - for _, spec := range imports.Specs { - if ispec, ok := spec.(*ast.ImportSpec); ok { - specPath, err := strconv.Unquote(ispec.Path.Value) - if err != nil { - panic("malformed path " + ispec.Path.Value) - } - if specPath == path { - return ispec.Name.Name, true - } - } - } - return "", false -} - func rootScope(scope *ast.Scope) *ast.Scope { for scope.Outer != nil { scope = scope.Outer diff --git a/tm2/pkg/amino/genproto/example/main.go b/tm2/pkg/amino/genproto/example/main.go index 24132305893..6e4023b596d 100644 --- a/tm2/pkg/amino/genproto/example/main.go +++ b/tm2/pkg/amino/genproto/example/main.go @@ -11,16 +11,12 @@ import ( // amino type StructA struct { - fieldA int - fieldB int FieldC int FieldD uint32 } // amino type StructB struct { - fieldA int - fieldB int FieldC int FieldD uint32 FieldE submodule.StructSM diff --git a/tm2/pkg/amino/genproto/scanner.go b/tm2/pkg/amino/genproto/scanner.go deleted file mode 100644 index 6c5f770ab48..00000000000 --- a/tm2/pkg/amino/genproto/scanner.go +++ /dev/null @@ -1,192 +0,0 @@ -package genproto - -import "fmt" - -type runestate int - -const ( - runestateCode runestate = 0 - runestateRune runestate = 1 - runestateStringQuote runestate = 2 - runestateStringBacktick runestate = 3 -) - -type scanner struct { - str string - rnz []rune - idx int - runestate - curly int - round int - square int -} - -// returns a new scanner. -func newScanner(str string) *scanner { - rnz := make([]rune, 0, len(str)) - for _, r := range str { - rnz = append(rnz, r) - } - return &scanner{ - str: str, - runestate: runestateCode, - rnz: rnz, - } -} - -// Peeks the next n runes and returns a string. returns a shorter string if -// there are less than n runes left. -func (ss *scanner) peek(n int) string { - if ss.idx+n > len(ss.rnz) { - return string(ss.rnz[ss.idx:len(ss.rnz)]) - } - return string(ss.rnz[ss.idx : ss.idx+n]) -} - -// Advance a single rune, e.g. by incrementing ss.curly if ss.rnz[ss.idx] is -// '{' before advancing. If ss.runestate is runestateRune or runestateQuote, -// advances escape sequences to completion so ss.idx may increment more than -// one. Returns true if done. -func (ss *scanner) advance() bool { - rn := ss.rnz[ss.idx] // just panic if out of scope, caller error. - switch ss.runestate { - case runestateCode: - switch rn { - case '}': - ss.curly-- - if ss.curly < 0 { - panic("mismatched curly: " + ss.str) - } - case ')': - ss.round-- - if ss.round < 0 { - panic("mismatched round: " + ss.str) - } - case ']': - ss.square-- - if ss.square < 0 { - panic("mismatched square: " + ss.str) - } - case '{': - ss.curly++ - case '(': - ss.round++ - case '[': - ss.square++ - case '\'': - ss.runestate = runestateRune - case '"': - ss.runestate = runestateStringQuote - case '`': - ss.runestate = runestateStringBacktick - } - case runestateRune: - switch rn { - case '\\': - return ss.advanceEscapeSequence() - case '\'': - ss.runestate = runestateCode - } - case runestateStringQuote: - switch rn { - case '\\': - return ss.advanceEscapeSequence() - case '"': - ss.runestate = runestateCode - } - case runestateStringBacktick: - switch rn { - case '`': - ss.runestate = runestateCode - } - } - ss.idx++ - return ss.done() -} - -// returns true if no runes left to advance. -func (ss *scanner) done() bool { - return ss.idx == len(ss.rnz) -} - -// returns true if outside the scope of any -// parentheses, brackets, strings, or rune literals. -func (ss *scanner) out() bool { - return ss.runestate == runestateCode && - ss.curly == int(0) && - ss.round == int(0) && - ss.square == int(0) -} - -func isOctal(r rune) bool { - switch r { - case '0', '1', '2', '3', '4', '5', '6', '7': - return true - default: - return false - } -} - -func isHex(r rune) bool { - switch r { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f', - 'A', 'B', 'C', 'D', 'E', 'F': - return true - default: - return false - } -} - -// Advances runes, while checking that each passes `check`. if error, panics -// with info including `back` runes back. -func (ss *scanner) eatRunes(back int, eat int, check func(rune) bool) { - for i := 0; i < eat; i++ { - if ss.idx+i == len(ss.rnz) { - panic(fmt.Sprintf("eof while parsing: %s", - string(ss.rnz[ss.idx-back:]))) - } - if !check(ss.rnz[ss.idx+i]) { - panic(fmt.Sprintf("invalid character while parsing: %s", - string(ss.rnz[ss.idx-back:ss.idx+i+1]))) - } - ss.idx++ - } -} - -// increments ss.idx until escape sequence is complete. returns true if done. -func (ss *scanner) advanceEscapeSequence() bool { - rn1 := ss.rnz[ss.idx] - if rn1 != '\\' { - panic("should not happen") - } - if ss.idx == len(ss.rnz)-1 { - panic("eof while parsing escape sequence") - } - rn2 := ss.rnz[ss.idx+1] - switch rn2 { - case 'x': - ss.idx += 2 - ss.eatRunes(2, 2, isHex) - return ss.done() - case 'u': - ss.idx += 2 - ss.eatRunes(2, 4, isHex) - return ss.done() - case 'U': - ss.idx += 2 - ss.eatRunes(2, 8, isHex) - return ss.done() - case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"': - ss.idx += 2 - return ss.done() - default: - ss.idx += 1 - if isOctal(rn2) { - ss.eatRunes(1, 3, isOctal) - } else { - panic("invalid escape sequence") - } - return ss.done() - } -} diff --git a/tm2/pkg/amino/reflect.go b/tm2/pkg/amino/reflect.go index bc4fa57e626..01402a320d2 100644 --- a/tm2/pkg/amino/reflect.go +++ b/tm2/pkg/amino/reflect.go @@ -1,26 +1,21 @@ package amino import ( - "encoding/json" "fmt" "reflect" "unicode" ) -//---------------------------------------- +// ---------------------------------------- // Constants -var ( - jsonMarshalerType = reflect.TypeOf(new(json.Marshaler)).Elem() - jsonUnmarshalerType = reflect.TypeOf(new(json.Unmarshaler)).Elem() - errorType = reflect.TypeOf(new(error)).Elem() -) +var errorType = reflect.TypeOf(new(error)).Elem() -//---------------------------------------- +// ---------------------------------------- // encode: see binary-encode.go and json-encode.go // decode: see binary-decode.go and json-decode.go -//---------------------------------------- +// ---------------------------------------- // Misc. // CONTRACT: by the time this is called, len(bz) >= _n @@ -182,18 +177,6 @@ func constructConcreteType(cinfo *TypeInfo) (crv, irvSet reflect.Value) { return } -// Like constructConcreteType(), but if pointer preferred, returns a nil one. -// We like nil pointers for efficiency. -func constructConcreteTypeNilPreferred(cinfo *TypeInfo) (crv reflect.Value) { - // Construct new concrete type. - if cinfo.PointerPreferred { - crv = reflect.Zero(cinfo.PtrToType) - } else { - crv = reflect.New(cinfo.Type).Elem() - } - return -} - func toReprObject(rv reflect.Value) (rrv reflect.Value, err error) { var mwrm reflect.Value if rv.CanAddr() { @@ -269,12 +252,6 @@ func unmarshalAminoReprType(rm reflect.Method) (rrt reflect.Type) { return } -func toPBMessage(cdc *Codec, rv reflect.Value) (pbrv reflect.Value) { - rm := rv.MethodByName("ToPBMessage") - pbrv = rm.Call([]reflect.Value{reflect.ValueOf(cdc)})[0] - return -} - // NOTE: do not change this definition. // It is also defined for genproto. func isListType(rt reflect.Type) bool { diff --git a/tm2/pkg/amino/tests/common.go b/tm2/pkg/amino/tests/common.go index b7213a56efc..1abf3aaf601 100644 --- a/tm2/pkg/amino/tests/common.go +++ b/tm2/pkg/amino/tests/common.go @@ -32,8 +32,6 @@ type PrimitivesStruct struct { Time time.Time Duration time.Duration Empty EmptyStruct - - unexposed int8 } type ShortArraysStruct struct { diff --git a/tm2/pkg/bft/abci/client/client.go b/tm2/pkg/bft/abci/client/client.go index b3d5a945839..f9f21f08fdb 100644 --- a/tm2/pkg/bft/abci/client/client.go +++ b/tm2/pkg/bft/abci/client/client.go @@ -7,11 +7,6 @@ import ( "github.com/gnolang/gno/tm2/pkg/service" ) -const ( - dialRetryIntervalSeconds = 3 - echoRetryIntervalSeconds = 1 -) - // Client defines an interface for an ABCI client. // All `Async` methods return a `ReqRes` object. // All `Sync` methods return the appropriate protobuf ResponseXxx struct and an error. @@ -48,11 +43,11 @@ type Client interface { EndBlockSync(abci.RequestEndBlock) (abci.ResponseEndBlock, error) } -//---------------------------------------- +// ---------------------------------------- type Callback func(abci.Request, abci.Response) -//---------------------------------------- +// ---------------------------------------- type ReqRes struct { abci.Request diff --git a/tm2/pkg/bft/consensus/common_test.go b/tm2/pkg/bft/consensus/common_test.go index 19c96756624..ba19881aace 100644 --- a/tm2/pkg/bft/consensus/common_test.go +++ b/tm2/pkg/bft/consensus/common_test.go @@ -29,7 +29,6 @@ import ( "github.com/gnolang/gno/tm2/pkg/events" "github.com/gnolang/gno/tm2/pkg/log" osm "github.com/gnolang/gno/tm2/pkg/os" - "github.com/gnolang/gno/tm2/pkg/p2p" ) const ( @@ -701,15 +700,6 @@ func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerF } } -func getSwitchIndex(switches []*p2p.Switch, peer p2p.Peer) int { - for i, s := range switches { - if peer.NodeInfo().ID() == s.NodeInfo().ID() { - return i - } - } - panic("didnt find peer in switches") -} - // ------------------------------------------------------------------------------- // genesis diff --git a/tm2/pkg/bft/consensus/replay.go b/tm2/pkg/bft/consensus/replay.go index 16b4ba3fa87..b228c1b63e4 100644 --- a/tm2/pkg/bft/consensus/replay.go +++ b/tm2/pkg/bft/consensus/replay.go @@ -4,7 +4,6 @@ import ( "bytes" "errors" "fmt" - "hash/crc32" "io" "reflect" "time" @@ -21,8 +20,6 @@ import ( "github.com/gnolang/gno/tm2/pkg/log" ) -var crc32c = crc32.MakeTable(crc32.Castagnoli) - // Functionality to replay blocks and messages on recovery from a crash. // There are two general failure scenarios: // diff --git a/tm2/pkg/bft/consensus/state_test.go b/tm2/pkg/bft/consensus/state_test.go index 1587fa03057..0e2e6b629a4 100644 --- a/tm2/pkg/bft/consensus/state_test.go +++ b/tm2/pkg/bft/consensus/state_test.go @@ -59,7 +59,7 @@ x * TestHalt1 - if we see +2/3 precommits after timing out into new round, we sh */ -//---------------------------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------------------------------- // ProposeSuite func TestStateProposerSelection0(t *testing.T) { @@ -255,7 +255,7 @@ func TestStateBadProposal(t *testing.T) { signAddVotes(cs1, types.PrecommitType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) } -//---------------------------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------------------------------- // FullRoundSuite // propose, prevote, and precommit a block @@ -354,7 +354,7 @@ func TestStateFullRound2(t *testing.T) { ensureNewBlock(newBlockCh, height) } -//------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------ // LockSuite // two validators, 4 rounds. @@ -409,7 +409,7 @@ func TestStateLockNoPOL(t *testing.T) { // but with invalid args. then we enterPrecommitWait, and the timeout to new round ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Precommit(round).Nanoseconds()) - /// + // ----------- round++ // moving to the next round ensureNewRound(newRoundCh, height, round) @@ -1496,7 +1496,7 @@ func TestFlappyResetTimeoutPrecommitUponNewHeight(t *testing.T) { assert.False(t, rs.TriggeredTimeoutPrecommit, "triggeredTimeoutPrecommit should be false at the beginning of each height") } -//------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------ // SlashingSuite // TODO: Slashing @@ -1573,10 +1573,10 @@ func TestStateSlashingPrecommits(t *testing.T) { } */ -//------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------ // CatchupSuite -//------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------ // HaltSuite // 4 vals. diff --git a/tm2/pkg/bft/consensus/wal_generator.go b/tm2/pkg/bft/consensus/wal_generator.go index dff1cca1446..7893c544c7f 100644 --- a/tm2/pkg/bft/consensus/wal_generator.go +++ b/tm2/pkg/bft/consensus/wal_generator.go @@ -40,7 +40,7 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { logger := log.TestingLogger().With("wal_generator", "wal_generator") logger.Info("generating WAL (last height msg excluded)", "numBlocks", numBlocks) - ///////////////////////////////////////////////////////////////////////////// + // ----------- // COPY PASTE FROM node.go WITH A FEW MODIFICATIONS // NOTE: we can't import node package because of circular dependency. // NOTE: we don't do handshake so need to set state.Version.Consensus.App directly. @@ -83,7 +83,7 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { consensusState.SetPrivValidator(privValidator) } // END OF COPY PASTE - ///////////////////////////////////////////////////////////////////////////// + // ----------- // set consensus wal to buffered WAL, which will write all incoming msgs to buffer numBlocksWritten := make(chan struct{}) diff --git a/tm2/pkg/bft/consensus/wal_test.go b/tm2/pkg/bft/consensus/wal_test.go index 1b271fb73c7..50f8f4c8b2a 100644 --- a/tm2/pkg/bft/consensus/wal_test.go +++ b/tm2/pkg/bft/consensus/wal_test.go @@ -13,10 +13,6 @@ import ( "github.com/gnolang/gno/tm2/pkg/log" ) -const ( - walTestFlushInterval = time.Duration(100) * time.Millisecond -) - // ---------------------------------------- // copied over from wal/wal_test.go @@ -53,8 +49,7 @@ func makeTempWAL(t *testing.T, walChunkSize int64) (wal walm.WAL) { // ---------------------------------------- func TestWALTruncate(t *testing.T) { - const maxTestMsgSize = 1024 * 1024 // 1MB - const walChunkSize = 409610 // 4KB + const walChunkSize = 409610 // 4KB wal := makeTempWAL(t, walChunkSize) wal.SetLogger(log.TestingLogger()) diff --git a/tm2/pkg/bft/node/node.go b/tm2/pkg/bft/node/node.go index bdeb5061540..9d6143e7af3 100644 --- a/tm2/pkg/bft/node/node.go +++ b/tm2/pkg/bft/node/node.go @@ -665,7 +665,6 @@ func (n *Node) ConfigureRPC() { rpccore.SetPubKey(pubKey) rpccore.SetGenesisDoc(n.genesisDoc) rpccore.SetProxyAppQuery(n.proxyApp.Query()) - rpccore.SetTxEventStore(n.txEventStore) rpccore.SetConsensusReactor(n.consensusReactor) rpccore.SetLogger(n.Logger.With("module", "rpc")) rpccore.SetEventSwitch(n.evsw) diff --git a/tm2/pkg/bft/privval/signer_listener_endpoint_test.go b/tm2/pkg/bft/privval/signer_listener_endpoint_test.go index 8e5b1613454..c2d89660baf 100644 --- a/tm2/pkg/bft/privval/signer_listener_endpoint_test.go +++ b/tm2/pkg/bft/privval/signer_listener_endpoint_test.go @@ -130,7 +130,7 @@ func TestRetryConnToRemoteSigner(t *testing.T) { } } -// ///////////////////////////////// +// ----------- func newSignerListenerEndpoint(logger log.Logger, ln net.Listener, timeoutReadWrite time.Duration) *SignerListenerEndpoint { var listener net.Listener diff --git a/tm2/pkg/bft/rpc/core/pipe.go b/tm2/pkg/bft/rpc/core/pipe.go index a8b102d9ab7..abfdc300d31 100644 --- a/tm2/pkg/bft/rpc/core/pipe.go +++ b/tm2/pkg/bft/rpc/core/pipe.go @@ -10,7 +10,6 @@ import ( "github.com/gnolang/gno/tm2/pkg/bft/proxy" cfg "github.com/gnolang/gno/tm2/pkg/bft/rpc/config" sm "github.com/gnolang/gno/tm2/pkg/bft/state" - "github.com/gnolang/gno/tm2/pkg/bft/state/eventstore" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/crypto" dbm "github.com/gnolang/gno/tm2/pkg/db" @@ -68,7 +67,6 @@ var ( // objects pubKey crypto.PubKey genDoc *types.GenesisDoc // cache the genesis structure - txEventStore eventstore.TxEventStore consensusReactor *consensus.ConsensusReactor evsw events.EventSwitch gTxDispatcher *txDispatcher @@ -115,10 +113,6 @@ func SetProxyAppQuery(appConn proxy.AppConnQuery) { proxyAppQuery = appConn } -func SetTxEventStore(indexer eventstore.TxEventStore) { - txEventStore = indexer -} - func SetConsensusReactor(conR *consensus.ConsensusReactor) { consensusReactor = conR } @@ -169,12 +163,3 @@ func validatePerPage(perPage int) int { } return perPage } - -func validateSkipCount(page, perPage int) int { - skipCount := (page - 1) * perPage - if skipCount < 0 { - return 0 - } - - return skipCount -} diff --git a/tm2/pkg/bft/rpc/lib/client/ws_client.go b/tm2/pkg/bft/rpc/lib/client/ws_client.go index 040437d11ff..4e159a3e3dc 100644 --- a/tm2/pkg/bft/rpc/lib/client/ws_client.go +++ b/tm2/pkg/bft/rpc/lib/client/ws_client.go @@ -226,7 +226,7 @@ func (c *WSClient) CallWithArrayParams(ctx context.Context, method string, param return c.Send(ctx, request) } -/////////////////////////////////////////////////////////////////////////////// +// ----------- // Private methods func (c *WSClient) dial() error { diff --git a/tm2/pkg/bft/rpc/lib/server/handlers_test.go b/tm2/pkg/bft/rpc/lib/server/handlers_test.go index b7a9445a82d..05f92a3b719 100644 --- a/tm2/pkg/bft/rpc/lib/server/handlers_test.go +++ b/tm2/pkg/bft/rpc/lib/server/handlers_test.go @@ -18,11 +18,11 @@ import ( "github.com/gnolang/gno/tm2/pkg/log" ) -////////////////////////////////////////////////////////////////////////////// +// ----------- // HTTP REST API // TODO -////////////////////////////////////////////////////////////////////////////// +// ----------- // JSON-RPC over HTTP func testMux() *http.ServeMux { @@ -229,7 +229,7 @@ func TestUnknownRPCPath(t *testing.T) { require.Equal(t, http.StatusNotFound, res.StatusCode, "should always return 404") } -////////////////////////////////////////////////////////////////////////////// +// ----------- // JSON-RPC over WEBSOCKETS func TestWebsocketManagerHandler(t *testing.T) { diff --git a/tm2/pkg/bft/state/helpers_test.go b/tm2/pkg/bft/state/helpers_test.go index 219baaf0f55..ca4175185a9 100644 --- a/tm2/pkg/bft/state/helpers_test.go +++ b/tm2/pkg/bft/state/helpers_test.go @@ -8,7 +8,6 @@ import ( "github.com/gnolang/gno/tm2/pkg/bft/proxy" sm "github.com/gnolang/gno/tm2/pkg/bft/state" "github.com/gnolang/gno/tm2/pkg/bft/types" - tmtime "github.com/gnolang/gno/tm2/pkg/bft/types/time" "github.com/gnolang/gno/tm2/pkg/crypto" "github.com/gnolang/gno/tm2/pkg/crypto/ed25519" dbm "github.com/gnolang/gno/tm2/pkg/db" @@ -190,24 +189,7 @@ func makeHeaderPartsResponsesParams(state sm.State, params abci.ConsensusParams) return block.Header, types.BlockID{Hash: block.Hash(), PartsHeader: types.PartSetHeader{}}, abciResponses } -func randomGenesisDoc() *types.GenesisDoc { - pubkey := ed25519.GenPrivKey().PubKey() - return &types.GenesisDoc{ - GenesisTime: tmtime.Now(), - ChainID: "abc", - Validators: []types.GenesisValidator{ - { - Address: pubkey.Address(), - PubKey: pubkey, - Power: 10, - Name: "myval", - }, - }, - ConsensusParams: types.DefaultConsensusParams(), - } -} - -//---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- type testApp struct { abci.BaseApplication diff --git a/tm2/pkg/bft/types/validator_set.go b/tm2/pkg/bft/types/validator_set.go index 617ceecaae5..80ed994ca39 100644 --- a/tm2/pkg/bft/types/validator_set.go +++ b/tm2/pkg/bft/types/validator_set.go @@ -758,7 +758,7 @@ func (vals *ValidatorSet) VerifyFutureCommit(newSet *ValidatorSet, chainID strin return nil } -//----------------- +// ----------------- // ErrTooMuchChange func IsErrTooMuchChange(err error) bool { @@ -775,7 +775,7 @@ func (e tooMuchChangeError) Error() string { return fmt.Sprintf("Invalid commit -- insufficient old voting power: got %v, needed %v", e.got, e.needed) } -//---------------- +// ---------------- func (vals *ValidatorSet) String() string { return vals.StringIndented("") @@ -802,7 +802,7 @@ func (vals *ValidatorSet) StringIndented(indent string) string { indent) } -//------------------------------------- +// ------------------------------------- // Implements sort for sorting validators by address. // Sort validators by address. @@ -822,7 +822,7 @@ func (valz ValidatorsByAddress) Swap(i, j int) { valz[j] = it } -//---------------------------------------- +// ---------------------------------------- // for testing // RandValidatorSet returns a randomized validator set, useful for testing. @@ -841,7 +841,7 @@ func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []Pr return vals, privValidators } -/////////////////////////////////////////////////////////////////////////////// +// ----------- // safe addition/subtraction func safeAdd(a, b int64) (int64, bool) { diff --git a/tm2/pkg/bft/wal/wal.go b/tm2/pkg/bft/wal/wal.go index b66a34df222..a4a14d638dd 100644 --- a/tm2/pkg/bft/wal/wal.go +++ b/tm2/pkg/bft/wal/wal.go @@ -436,7 +436,7 @@ OUTER_LOOP: return nil, false, nil } -// ///////////////////////////////////////////////////////////////////////////// +// ----------- // A WALWriter writes custom-encoded WAL messages to an output stream. // Each binary WAL entry is length encoded, then crc encoded, @@ -512,7 +512,7 @@ func (enc *WALWriter) WriteMeta(meta MetaMessage) error { return err } -// ///////////////////////////////////////////////////////////////////////////// +// ----------- // IsDataCorruptionError returns true if data has been corrupted inside WAL. func IsDataCorruptionError(err error) bool { diff --git a/tm2/pkg/bft/wal/wal_test.go b/tm2/pkg/bft/wal/wal_test.go index 4cb94766389..a1a3e831a79 100644 --- a/tm2/pkg/bft/wal/wal_test.go +++ b/tm2/pkg/bft/wal/wal_test.go @@ -29,7 +29,7 @@ type TestMessage struct { func (TestMessage) AssertWALMessage() {} -var testPackage = amino.RegisterPackage(amino.NewPackage( +var _ = amino.RegisterPackage(amino.NewPackage( "github.com/gnolang/gno/tm2/pkg/bft/wal", "wal", amino.GetCallersDirname(), diff --git a/tm2/pkg/crypto/keys/client/export_test.go b/tm2/pkg/crypto/keys/client/export_test.go index 7ddbeede993..0f4c5311dfa 100644 --- a/tm2/pkg/crypto/keys/client/export_test.go +++ b/tm2/pkg/crypto/keys/client/export_test.go @@ -64,11 +64,9 @@ func addRandomKeyToKeybase( } type testCmdKeyOptsBase struct { - kbHome string - keyName string - decryptPassword string - encryptPassword string - unsafe bool + kbHome string + keyName string + unsafe bool } type testExportKeyOpts struct { diff --git a/tm2/pkg/crypto/keys/keybase.go b/tm2/pkg/crypto/keys/keybase.go index 16b3631d188..13f6e00979d 100644 --- a/tm2/pkg/crypto/keys/keybase.go +++ b/tm2/pkg/crypto/keys/keybase.go @@ -46,14 +46,6 @@ const ( infoSuffix = "info" ) -const ( - // used for deriving seed from mnemonic - DefaultBIP39Passphrase = "" - - // bits of entropy to draw when creating a mnemonic - defaultEntropySize = 256 -) - var ( // ErrUnsupportedSigningAlgo is raised when the caller tries to use a // different signing scheme than secp256k1. diff --git a/tm2/pkg/crypto/merkle/proof_test.go b/tm2/pkg/crypto/merkle/proof_test.go index 676e281ac60..3319963ce6c 100644 --- a/tm2/pkg/crypto/merkle/proof_test.go +++ b/tm2/pkg/crypto/merkle/proof_test.go @@ -26,19 +26,6 @@ func NewDominoOp(key, input, output string) DominoOp { } } -//nolint:unused -func DominoOpDecoder(pop ProofOp) (ProofOperator, error) { - if pop.Type != ProofOpDomino { - panic("unexpected proof op type") - } - var op DominoOp // a bit strange as we'll discard this, but it works. - err := amino.UnmarshalSized(pop.Data, &op) - if err != nil { - return nil, errors.Wrap(err, "decoding ProofOp.Data into SimpleValueOp") - } - return NewDominoOp(string(pop.Key), op.Input, op.Output), nil -} - func (dop DominoOp) ProofOp() ProofOp { bz := amino.MustMarshalSized(dop) return ProofOp{ @@ -63,7 +50,7 @@ func (dop DominoOp) GetKey() []byte { return []byte(dop.key) } -//---------------------------------------- +// ---------------------------------------- func TestProofOperators(t *testing.T) { var err error diff --git a/tm2/pkg/crypto/util.go b/tm2/pkg/crypto/util.go deleted file mode 100644 index f017557f09b..00000000000 --- a/tm2/pkg/crypto/util.go +++ /dev/null @@ -1,7 +0,0 @@ -package crypto - -func cp(bz []byte) (ret []byte) { - ret = make([]byte, len(bz)) - copy(ret, bz) - return ret -} diff --git a/tm2/pkg/events/store.go b/tm2/pkg/events/store.go index bea4626394e..1891fd17ac6 100644 --- a/tm2/pkg/events/store.go +++ b/tm2/pkg/events/store.go @@ -1,33 +1,12 @@ package events -import ( - "fmt" - - auto "github.com/gnolang/gno/tm2/pkg/autofile" -) - // StoreStream stores events to disk but is also listenaable. type StoreStream interface { Eventable SetHeight(height int64) // to demarcate height in WAL for replay. } -type storeStream struct { - afile *auto.AutoFile - buf []byte - height int64 -} - -func (ss *storeStream) SetHeight(height int64) { - if ss.height < height { - // write new height - ss.height = height - } else /* if height <= ss.height */ { - panic(fmt.Sprintf("invalid SetHeight height value. current %v, got %v", ss.height, height)) - } -} - -//---------------------------------------- +// ---------------------------------------- // move to own file // FilterStream is listenable and lets you filter. diff --git a/tm2/pkg/iavl/benchmarks/bench_test.go b/tm2/pkg/iavl/benchmarks/bench_test.go index de6a573020e..77ad77eed28 100644 --- a/tm2/pkg/iavl/benchmarks/bench_test.go +++ b/tm2/pkg/iavl/benchmarks/bench_test.go @@ -75,19 +75,6 @@ func runKnownQueries(b *testing.B, t *iavl.MutableTree, keys [][]byte) { } } -func runInsert(b *testing.B, t *iavl.MutableTree, keyLen, dataLen, blockSize int) *iavl.MutableTree { - b.Helper() - - for i := 1; i <= b.N; i++ { - t.Set(randBytes(keyLen), randBytes(dataLen)) - if i%blockSize == 0 { - t.Hash() - t.SaveVersion() - } - } - return t -} - func runUpdate(b *testing.B, t *iavl.MutableTree, dataLen, blockSize int, keys [][]byte) *iavl.MutableTree { b.Helper() @@ -102,23 +89,6 @@ func runUpdate(b *testing.B, t *iavl.MutableTree, dataLen, blockSize int, keys [ return t } -func runDelete(b *testing.B, t *iavl.MutableTree, blockSize int, keys [][]byte) *iavl.MutableTree { - b.Helper() - - var key []byte - l := int32(len(keys)) - for i := 1; i <= b.N; i++ { - key = keys[rand.Int31n(l)] - // key = randBytes(16) - // TODO: test if removed, use more keys (from insert) - t.Remove(key) - if i%blockSize == 0 { - commitTree(b, t) - } - } - return t -} - // runBlock measures time for an entire block, not just one tx func runBlock(b *testing.B, t *iavl.MutableTree, keyLen, dataLen, blockSize int, keys [][]byte) *iavl.MutableTree { b.Helper() diff --git a/tm2/pkg/iavl/node.go b/tm2/pkg/iavl/node.go index f2a944afc6a..ee522016f0c 100644 --- a/tm2/pkg/iavl/node.go +++ b/tm2/pkg/iavl/node.go @@ -371,10 +371,6 @@ func (node *Node) traverse(t *ImmutableTree, ascending bool, cb func(*Node) bool }) } -func (node *Node) traverseWithDepth(t *ImmutableTree, ascending bool, cb func(*Node, uint8) bool) bool { - return node.traverseInRange(t, nil, nil, ascending, false, 0, cb) -} - func (node *Node) traverseInRange(t *ImmutableTree, start, end []byte, ascending bool, inclusive bool, depth uint8, cb func(*Node, uint8) bool) bool { afterStart := start == nil || bytes.Compare(start, node.key) < 0 startOrAfter := start == nil || bytes.Compare(start, node.key) <= 0 diff --git a/tm2/pkg/iavl/nodedb.go b/tm2/pkg/iavl/nodedb.go index 3e59b3480e9..e1998d8cc1d 100644 --- a/tm2/pkg/iavl/nodedb.go +++ b/tm2/pkg/iavl/nodedb.go @@ -385,7 +385,7 @@ func (ndb *nodeDB) saveRoot(hash []byte, version int64) error { return nil } -////////////////// Utility and test functions ///////////////////////////////// +// ----------- Utility and test functions // ----------- func (ndb *nodeDB) leafNodes() []*Node { leaves := []*Node{} diff --git a/tm2/pkg/iavl/proof_path.go b/tm2/pkg/iavl/proof_path.go index f66fcf3c48c..a5ac14bc4e7 100644 --- a/tm2/pkg/iavl/proof_path.go +++ b/tm2/pkg/iavl/proof_path.go @@ -1,11 +1,8 @@ package iavl import ( - "bytes" "fmt" "strings" - - "github.com/gnolang/gno/tm2/pkg/errors" ) // pathWithLeaf is a path to a leaf node and the leaf node itself. @@ -28,14 +25,6 @@ func (pwl pathWithLeaf) StringIndented(indent string) string { indent) } -// `verify` checks that the leaf node's hash + the inner nodes merkle-izes to -// the given root. If it returns an error, it means the leafHash or the -// PathToLeaf is incorrect. -func (pwl pathWithLeaf) verify(root []byte) error { - leafHash := pwl.Leaf.Hash() - return pwl.Path.verify(leafHash, root) -} - // `computeRootHash` computes the root hash with leaf node. // Does not verify the root hash. func (pwl pathWithLeaf) computeRootHash() []byte { @@ -73,21 +62,6 @@ func (pl PathToLeaf) stringIndented(indent string) string { indent) } -// `verify` checks that the leaf node's hash + the inner nodes merkle-izes to -// the given root. If it returns an error, it means the leafHash or the -// PathToLeaf is incorrect. -func (pl PathToLeaf) verify(leafHash []byte, root []byte) error { - hash := leafHash - for i := len(pl) - 1; i >= 0; i-- { - pin := pl[i] - hash = pin.Hash(hash) - } - if !bytes.Equal(root, hash) { - return errors.Wrap(ErrInvalidProof, "") - } - return nil -} - // `computeRootHash` computes the root hash assuming some leaf hash. // Does not verify the root hash. func (pl PathToLeaf) computeRootHash(leafHash []byte) []byte { @@ -117,37 +91,6 @@ func (pl PathToLeaf) isRightmost() bool { return true } -func (pl PathToLeaf) isEmpty() bool { - return pl == nil || len(pl) == 0 -} - -func (pl PathToLeaf) dropRoot() PathToLeaf { - if pl.isEmpty() { - return pl - } - return pl[:len(pl)-1] -} - -func (pl PathToLeaf) hasCommonRoot(pl2 PathToLeaf) bool { - if pl.isEmpty() || pl2.isEmpty() { - return false - } - leftEnd := pl[len(pl)-1] - rightEnd := pl2[len(pl2)-1] - - return bytes.Equal(leftEnd.Left, rightEnd.Left) && - bytes.Equal(leftEnd.Right, rightEnd.Right) -} - -func (pl PathToLeaf) isLeftAdjacentTo(pl2 PathToLeaf) bool { - for pl.hasCommonRoot(pl2) { - pl, pl2 = pl.dropRoot(), pl2.dropRoot() - } - pl, pl2 = pl.dropRoot(), pl2.dropRoot() - - return pl.isRightmost() && pl2.isLeftmost() -} - // returns -1 if invalid. func (pl PathToLeaf) Index() (idx int64) { for i, node := range pl { diff --git a/tm2/pkg/iavl/proof_range.go b/tm2/pkg/iavl/proof_range.go index 799fb65cebb..ea6bce24fc0 100644 --- a/tm2/pkg/iavl/proof_range.go +++ b/tm2/pkg/iavl/proof_range.go @@ -299,7 +299,7 @@ func (proof *RangeProof) _computeRootHash() (rootHash []byte, treeEnd bool, err return rootHash, treeEnd, nil } -/////////////////////////////////////////////////////////////////////////////// +// ----------- // keyStart is inclusive and keyEnd is exclusive. // If keyStart or keyEnd don't exist, the leaf before keyStart @@ -442,7 +442,7 @@ func (t *ImmutableTree) getRangeProof(keyStart, keyEnd []byte, limit int) (proof }, keys, values, nil } -//---------------------------------------- +// ---------------------------------------- // GetWithProof gets the value under the key if it exists, or returns nil. // A proof of existence or absence is returned alongside the value. diff --git a/tm2/pkg/iavl/tree_test.go b/tm2/pkg/iavl/tree_test.go index 56a00ee2424..f15a3276653 100644 --- a/tm2/pkg/iavl/tree_test.go +++ b/tm2/pkg/iavl/tree_test.go @@ -1290,7 +1290,7 @@ func TestLoadVersionForOverwriting(t *testing.T) { require.NoError(err, "SaveVersion should not fail.") } -//////////////////////////// BENCHMARKS /////////////////////////////////////// +// ----------- BENCHMARKS // ----------- func BenchmarkTreeLoadAndDelete(b *testing.B) { if testing.Short() { diff --git a/tm2/pkg/p2p/config/config.go b/tm2/pkg/p2p/config/config.go index 855c0fd9844..830f84ad137 100644 --- a/tm2/pkg/p2p/config/config.go +++ b/tm2/pkg/p2p/config/config.go @@ -6,7 +6,7 @@ import ( "github.com/gnolang/gno/tm2/pkg/errors" ) -//----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // P2PConfig const ( @@ -16,8 +16,6 @@ const ( FuzzModeDelay ) -var defaultConfigDir = "config" // duplicate across module configs? - // P2PConfig defines the configuration options for the Tendermint peer-to-peer networking layer type P2PConfig struct { RootDir string `toml:"home"` diff --git a/tm2/pkg/p2p/switch.go b/tm2/pkg/p2p/switch.go index 1f693544d5a..368de659fb1 100644 --- a/tm2/pkg/p2p/switch.go +++ b/tm2/pkg/p2p/switch.go @@ -387,10 +387,6 @@ func (sw *Switch) reconnectToPeer(addr *NetAddress) { // --------------------------------------------------------------------- // Dialing -type privateAddr interface { - PrivateAddr() bool -} - // DialPeersAsync dials a list of peers asynchronously in random order. // Used to dial peers from config on startup or from unsafe-RPC (trusted sources). // It ignores NetAddressLookupError. However, if there are other errors, first diff --git a/tm2/pkg/sdk/auth/test_common.go b/tm2/pkg/sdk/auth/test_common.go index a51c8576bad..ee4153184a4 100644 --- a/tm2/pkg/sdk/auth/test_common.go +++ b/tm2/pkg/sdk/auth/test_common.go @@ -19,33 +19,6 @@ type testEnv struct { bank BankKeeperI } -// moduleAccount defines an account for modules that holds coins on a pool -type moduleAccount struct { - *std.BaseAccount - name string `json:"name" yaml:"name"` // name of the module - permissions []string `json:"permissions" yaml"permissions"` // permissions of module account -} - -// HasPermission returns whether or not the module account has permission. -func (ma moduleAccount) HasPermission(permission string) bool { - for _, perm := range ma.permissions { - if perm == permission { - return true - } - } - return false -} - -// GetName returns the the name of the holder's module -func (ma moduleAccount) GetName() string { - return ma.name -} - -// GetPermissions returns permissions granted to the module account -func (ma moduleAccount) GetPermissions() []string { - return ma.permissions -} - func setupTestEnv() testEnv { db := dbm.NewMemDB() diff --git a/tm2/pkg/sdk/baseapp_test.go b/tm2/pkg/sdk/baseapp_test.go index 2d130583885..3fb44e5f744 100644 --- a/tm2/pkg/sdk/baseapp_test.go +++ b/tm2/pkg/sdk/baseapp_test.go @@ -444,10 +444,6 @@ func (mch msgCounterHandler) Query(ctx Context, req abci.RequestQuery) abci.Resp panic("should not happen") } -func i2b(i int64) []byte { - return []byte{byte(i)} -} - func getIntFromStore(store store.Store, key []byte) int64 { bz := store.Get(key) if len(bz) == 0 { @@ -477,7 +473,7 @@ func incrementingCounter(t *testing.T, store store.Store, counterKey []byte, cou return } -//--------------------------------------------------------------------- +// --------------------------------------------------------------------- // Tx processing - CheckTx, DeliverTx, SimulateTx. // These tests use the serialized tx as input, while most others will use the // Check(), Deliver(), Simulate() methods directly. diff --git a/tm2/pkg/std/coin.go b/tm2/pkg/std/coin.go index d5eb9bb1da0..75063320ad3 100644 --- a/tm2/pkg/std/coin.go +++ b/tm2/pkg/std/coin.go @@ -619,11 +619,9 @@ var ( // Denominations can be 3 ~ 16 characters long. reDnmString = `[a-z][a-z0-9]{2,15}` reAmt = `[[:digit:]]+` - reDecAmt = `[[:digit:]]*\.[[:digit:]]+` reSpc = `[[:space:]]*` reDnm = regexp.MustCompile(fmt.Sprintf(`^%s$`, reDnmString)) reCoin = regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)$`, reAmt, reSpc, reDnmString)) - reDecCoin = regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)$`, reDecAmt, reSpc, reDnmString)) ) func validateDenom(denom string) error { diff --git a/tm2/pkg/store/gas/store_test.go b/tm2/pkg/store/gas/store_test.go index 70f1fc8ea7f..ad335d73c24 100644 --- a/tm2/pkg/store/gas/store_test.go +++ b/tm2/pkg/store/gas/store_test.go @@ -13,12 +13,6 @@ import ( "github.com/stretchr/testify/require" ) -func newGasKVStore() types.Store { - meter := types.NewGasMeter(10000) - mem := dbadapter.Store{dbm.NewMemDB()} - return gas.New(mem, meter, types.DefaultGasConfig()) -} - func bz(s string) []byte { return []byte(s) } func keyFmt(i int) []byte { return bz(fmt.Sprintf("key%0.8d", i)) } diff --git a/tm2/pkg/store/rootmulti/dbadapter.go b/tm2/pkg/store/rootmulti/dbadapter.go deleted file mode 100644 index 254d139a608..00000000000 --- a/tm2/pkg/store/rootmulti/dbadapter.go +++ /dev/null @@ -1,33 +0,0 @@ -package rootmulti - -import ( - "github.com/gnolang/gno/tm2/pkg/store/dbadapter" - "github.com/gnolang/gno/tm2/pkg/store/types" -) - -var commithash = []byte("FAKE_HASH") - -//---------------------------------------- -// commitDBStoreWrapper should only be used for simulation/debugging, -// as it doesn't compute any commit hash, and it cannot load older state. - -// Wrapper type for dbm.Db with implementation of KVStore -type commitDBStoreAdapter struct { - dbadapter.Store -} - -func (cdsa commitDBStoreAdapter) Commit() types.CommitID { - return types.CommitID{ - Version: -1, - Hash: commithash, - } -} - -func (cdsa commitDBStoreAdapter) LastCommitID() types.CommitID { - return types.CommitID{ - Version: -1, - Hash: commithash, - } -} - -func (cdsa commitDBStoreAdapter) SetPruning(_ types.PruningOptions) {} From 11f4359d2e06179132636057a09c35a74f0fc77a Mon Sep 17 00:00:00 2001 From: Manfred Touron <94029+moul@users.noreply.github.com> Date: Wed, 8 Nov 2023 09:15:15 +0100 Subject: [PATCH 16/25] feat: add contribs/gnomd (#1256) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds a `contribs/gnomd` binary. Please review PR #1001 for the `maketx run`. Additionally, this PR introduces the `contribs/` folder. It allows the creation of `contribs/gno*` Go packages, Python/Rust/Shell/… scripts. This approach keeps the main `gno`, `gnokey`, and `gnoland` simple while adhering to the Unix philosophy and incorporating several specific gno commands. ![CleanShot 2023-10-19 at 09 17 40@2x](https://github.com/gnolang/gno/assets/94029/9b92bf18-f923-4f70-aea7-a88f185f2342) --------- Signed-off-by: moul <94029+moul@users.noreply.github.com> Co-authored-by: Morgan --- .github/workflows/contribs.yml | 35 +++++++++++++++++ .github/workflows/misc.yml | 5 ++- contribs/Makefile | 30 +++++++++++++++ contribs/README.md | 17 +++++++++ contribs/gnomd/go.mod | 25 ++++++++++++ contribs/gnomd/go.sum | 70 ++++++++++++++++++++++++++++++++++ contribs/gnomd/main.go | 38 ++++++++++++++++++ 7 files changed, 218 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/contribs.yml create mode 100644 contribs/Makefile create mode 100644 contribs/README.md create mode 100644 contribs/gnomd/go.mod create mode 100644 contribs/gnomd/go.sum create mode 100644 contribs/gnomd/main.go diff --git a/.github/workflows/contribs.yml b/.github/workflows/contribs.yml new file mode 100644 index 00000000000..939ac670710 --- /dev/null +++ b/.github/workflows/contribs.yml @@ -0,0 +1,35 @@ +name: contribs + +on: + push: + branches: [ "master" ] + pull_request: + paths: + - "contribs/**" + - ".github/workflows/contribs.yml" + - "gnovm/**.go" + - "gno.land/**.go" + - "tm2/**.go" + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + install: + strategy: + fail-fast: false + matrix: + goversion: # two latest versions + - "1.21.x" + program: + - "gnomd" + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 + with: + go-version: ${{ matrix.goversion }} + - run: make install ${{ matrix.program }} + working-directory: contribs diff --git a/.github/workflows/misc.yml b/.github/workflows/misc.yml index a7c20d61ffd..f72a97c95b3 100644 --- a/.github/workflows/misc.yml +++ b/.github/workflows/misc.yml @@ -71,8 +71,9 @@ jobs: - name: Check go.mods run: | - sums="$(sha256sum go.mod misc/devdeps/go.mod)" - for path in . ./misc/devdeps; do + gomods=$(find . -type f -name go.mod) + sums="$(sha256sum ${gomods})" + for path in $(dirname $(gomods)); do env -C $path go mod tidy -v || exit 1 done echo "$sums" | sha256sum -c diff --git a/contribs/Makefile b/contribs/Makefile new file mode 100644 index 00000000000..b816987b733 --- /dev/null +++ b/contribs/Makefile @@ -0,0 +1,30 @@ +.PHONY: help +help: + @echo "Available make commands:" + @cat Makefile | grep '^[a-z][^:]*:' | cut -d: -f1 | sort | sed 's/^/ /' + +.PHONY: install +install: install.gnomd + +install.gnomd:; cd gnomd && go install . + +.PHONY: clean +clean: + rm -rf build + +######################################## +# Dev tools +rundep=go run -modfile ../misc/devdeps/go.mod + +.PHONY: fmt +GOFMT_FLAGS ?= -w +fmt: + $(rundep) mvdan.cc/gofumpt $(GOFMT_FLAGS) . + +######################################## +# Test suite +GOTEST_FLAGS ?= -v -p 1 -timeout=30m + +.PHONY: test +test: + @echo "nothing to do." diff --git a/contribs/README.md b/contribs/README.md new file mode 100644 index 00000000000..c481af0f4aa --- /dev/null +++ b/contribs/README.md @@ -0,0 +1,17 @@ +# Gno Contribs + +This directory houses additional commands and tools designed to enhance your Gno experience. +These tools can range from simple wrappers for `gno`, `gnoland`, and `gnokey` to complete applications. +Some may be Go binaries with their own `go.mod` files, allowing the use of specialized libraries, +while others may be shell scripts or programs written in different languages. + +## Contributing Guidelines + +If you'd like to contribute a tool to Gno Contribs, please follow these guidelines: + +1. **Naming**: Choose a clear and concise name for your tool, starting with one of the prefixes: `gno`, `gnoland`, or `gnokey`, + followed by a short descriptive word or abbreviation. + This naming convention helps users identify the purpose of the tool easily. + +2. **User-Friendly**: Ensure that your tool is user-friendly and follows a similar style to other Gno tools, + providing a consistent experience for users. diff --git a/contribs/gnomd/go.mod b/contribs/gnomd/go.mod new file mode 100644 index 00000000000..b631040ce94 --- /dev/null +++ b/contribs/gnomd/go.mod @@ -0,0 +1,25 @@ +module github.com/gnolang/gno/contribs/gnomd + +go 1.20 + +require github.com/MichaelMure/go-term-markdown v0.1.4 + +require ( + github.com/MichaelMure/go-term-text v0.3.1 // indirect + github.com/alecthomas/chroma v0.7.1 // indirect + github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect + github.com/disintegration/imaging v1.6.2 // indirect + github.com/dlclark/regexp2 v1.1.6 // indirect + github.com/eliukblau/pixterm/pkg/ansimage v0.0.0-20191210081756-9fb6cf8c2f75 // indirect + github.com/fatih/color v1.9.0 // indirect + github.com/gomarkdown/markdown v0.0.0-20191123064959-2c17d62f5098 // indirect + github.com/kyokomi/emoji/v2 v2.2.8 // indirect + github.com/lucasb-eyer/go-colorful v1.0.3 // indirect + github.com/mattn/go-colorable v0.1.4 // indirect + github.com/mattn/go-isatty v0.0.11 // indirect + github.com/mattn/go-runewidth v0.0.12 // indirect + github.com/rivo/uniseg v0.1.0 // indirect + golang.org/x/image v0.0.0-20191206065243-da761ea9ff43 // indirect + golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 // indirect + golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect +) diff --git a/contribs/gnomd/go.sum b/contribs/gnomd/go.sum new file mode 100644 index 00000000000..b4ad4f5c9bf --- /dev/null +++ b/contribs/gnomd/go.sum @@ -0,0 +1,70 @@ +github.com/MichaelMure/go-term-markdown v0.1.4 h1:Ir3kBXDUtOX7dEv0EaQV8CNPpH+T7AfTh0eniMOtNcs= +github.com/MichaelMure/go-term-markdown v0.1.4/go.mod h1:EhcA3+pKYnlUsxYKBJ5Sn1cTQmmBMjeNlpV8nRb+JxA= +github.com/MichaelMure/go-term-text v0.3.1 h1:Kw9kZanyZWiCHOYu9v/8pWEgDQ6UVN9/ix2Vd2zzWf0= +github.com/MichaelMure/go-term-text v0.3.1/go.mod h1:QgVjAEDUnRMlzpS6ky5CGblux7ebeiLnuy9dAaFZu8o= +github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= +github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= +github.com/alecthomas/chroma v0.7.1 h1:G1i02OhUbRi2nJxcNkwJaY/J1gHXj9tt72qN6ZouLFQ= +github.com/alecthomas/chroma v0.7.1/go.mod h1:gHw09mkX1Qp80JlYbmN9L3+4R5o6DJJ3GRShh+AICNc= +github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo= +github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= +github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI= +github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY= +github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= +github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ= +github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= +github.com/dlclark/regexp2 v1.1.6 h1:CqB4MjHw0MFCDj+PHHjiESmHX+N7t0tJzKvC6M97BRg= +github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/eliukblau/pixterm/pkg/ansimage v0.0.0-20191210081756-9fb6cf8c2f75 h1:vbix8DDQ/rfatfFr/8cf/sJfIL69i4BcZfjrVOxsMqk= +github.com/eliukblau/pixterm/pkg/ansimage v0.0.0-20191210081756-9fb6cf8c2f75/go.mod h1:0gZuvTO1ikSA5LtTI6E13LEOdWQNjIo5MTQOvrV0eFg= +github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/gomarkdown/markdown v0.0.0-20191123064959-2c17d62f5098 h1:Qxs3bNRWe8GTcKMxYOSXm0jx6j0de8XUtb/fsP3GZ0I= +github.com/gomarkdown/markdown v0.0.0-20191123064959-2c17d62f5098/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU= +github.com/kyokomi/emoji/v2 v2.2.8 h1:jcofPxjHWEkJtkIbcLHvZhxKgCPl6C7MyjTrD4KDqUE= +github.com/kyokomi/emoji/v2 v2.2.8/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE= +github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac= +github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20191206065243-da761ea9ff43 h1:gQ6GUSD102fPgli+Yb4cR/cGaHF7tNBt+GYoRCpGC7s= +golang.org/x/image v0.0.0-20191206065243-da761ea9ff43/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/contribs/gnomd/main.go b/contribs/gnomd/main.go new file mode 100644 index 00000000000..2d3b7266af5 --- /dev/null +++ b/contribs/gnomd/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" + "io/ioutil" + "os" + + markdown "github.com/MichaelMure/go-term-markdown" +) + +func main() { + // If no arguments are provided, read from stdin + if len(os.Args) <= 1 { + fileContent, err := ioutil.ReadAll(os.Stdin) + checkErr(err) + renderMarkdown("stdin.gno", fileContent) + } + + // Iterate through command-line arguments (file paths) + for _, filePath := range os.Args[1:] { + fileContent, err := ioutil.ReadFile(filePath) + checkErr(err) + renderMarkdown(filePath, fileContent) + } +} + +func renderMarkdown(filePath string, fileContent []byte) { + fmt.Printf("-- %s --\n", filePath) + + result := markdown.Render(string(fileContent), 80, 6) + fmt.Println(string(result)) +} + +func checkErr(err error) { + if err != nil { + panic(err) + } +} From 678686a8b132bb85f76579995f4ae48ca3b9e1ff Mon Sep 17 00:00:00 2001 From: Hariom Verma Date: Wed, 8 Nov 2023 14:50:56 +0530 Subject: [PATCH 17/25] fix(ci): remove unused func `parseBalance` (#1344) Currently CI is complaining about unused func `parseBalance`. Fixed it.
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [x] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--- gno.land/pkg/gnoland/app.go | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/gno.land/pkg/gnoland/app.go b/gno.land/pkg/gnoland/app.go index a8a2736c8d1..0610cd4a93f 100644 --- a/gno.land/pkg/gnoland/app.go +++ b/gno.land/pkg/gnoland/app.go @@ -12,7 +12,6 @@ import ( "github.com/gnolang/gno/gno.land/pkg/sdk/vm" "github.com/gnolang/gno/tm2/pkg/amino" abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types" - "github.com/gnolang/gno/tm2/pkg/crypto" dbm "github.com/gnolang/gno/tm2/pkg/db" "github.com/gnolang/gno/tm2/pkg/log" "github.com/gnolang/gno/tm2/pkg/sdk" @@ -175,22 +174,6 @@ func InitChainer(baseApp *sdk.BaseApp, acctKpr auth.AccountKeeperI, bankKpr bank } } -func parseBalance(bal string) (crypto.Address, std.Coins) { - parts := strings.Split(bal, "=") - if len(parts) != 2 { - panic(fmt.Sprintf("invalid balance string %s", bal)) - } - addr, err := crypto.AddressFromBech32(parts[0]) - if err != nil { - panic(fmt.Sprintf("invalid balance addr %s (%v)", bal, err)) - } - coins, err := std.ParseCoins(parts[1]) - if err != nil { - panic(fmt.Sprintf("invalid balance coins %s (%v)", bal, err)) - } - return addr, coins -} - // XXX not used yet. func EndBlocker(vmk vm.VMKeeperI) func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { From 041d0a84fcca815c3fc1b809d389ed272d927698 Mon Sep 17 00:00:00 2001 From: Hariom Verma Date: Wed, 8 Nov 2023 15:48:21 +0530 Subject: [PATCH 18/25] chore(gnomod): test package does not exist (#1317) Add test for package does not exist. Not able to reproduce `Infinite loop when a requested package does not exist` (#835) --- gnovm/pkg/gnomod/file_test.go | 60 ++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/gnovm/pkg/gnomod/file_test.go b/gnovm/pkg/gnomod/file_test.go index 7acea3a6096..0012960eb4f 100644 --- a/gnovm/pkg/gnomod/file_test.go +++ b/gnovm/pkg/gnomod/file_test.go @@ -20,11 +20,30 @@ func TestFetchDeps(t *testing.T) { for _, tc := range []struct { desc string modFile File + errorShouldContain string requirements []string stdOutContains []string cachedStdOutContains []string }{ { + desc: "not_exists", + modFile: File{ + Module: &modfile.Module{ + Mod: module.Version{ + Path: "testFetchDeps", + }, + }, + Require: []*modfile.Require{ + { + Mod: module.Version{ + Path: "gno.land/p/demo/does_not_exists", + Version: "v0.0.0", + }, + }, + }, + }, + errorShouldContain: "querychain (gno.land/p/demo/does_not_exists)", + }, { desc: "fetch_gno.land/p/demo/avl", modFile: File{ Module: &modfile.Module{ @@ -89,29 +108,34 @@ func TestFetchDeps(t *testing.T) { defer cleanUpFn() // Fetching dependencies - tc.modFile.FetchDeps(dirPath, testRemote, true) + err := tc.modFile.FetchDeps(dirPath, testRemote, true) + if tc.errorShouldContain != "" { + require.ErrorContains(t, err, tc.errorShouldContain) + } else { + require.Nil(t, err) - // Read dir - entries, err := os.ReadDir(filepath.Join(dirPath, "gno.land", "p", "demo")) - require.Nil(t, err) + // Read dir + entries, err := os.ReadDir(filepath.Join(dirPath, "gno.land", "p", "demo")) + require.Nil(t, err) - // Check dir entries - assert.Equal(t, len(tc.requirements), len(entries)) - for _, e := range entries { - assert.Contains(t, tc.requirements, e.Name()) - } + // Check dir entries + assert.Equal(t, len(tc.requirements), len(entries)) + for _, e := range entries { + assert.Contains(t, tc.requirements, e.Name()) + } - // Check logs - for _, c := range tc.stdOutContains { - assert.Contains(t, buf.String(), c) - } + // Check logs + for _, c := range tc.stdOutContains { + assert.Contains(t, buf.String(), c) + } - buf.Reset() + buf.Reset() - // Try fetching again. Should be cached - tc.modFile.FetchDeps(dirPath, testRemote, true) - for _, c := range tc.cachedStdOutContains { - assert.Contains(t, buf.String(), c) + // Try fetching again. Should be cached + tc.modFile.FetchDeps(dirPath, testRemote, true) + for _, c := range tc.cachedStdOutContains { + assert.Contains(t, buf.String(), c) + } } }) } From c33c9f21b398538a9b6d30eabc33057c698b45e6 Mon Sep 17 00:00:00 2001 From: deelawn Date: Wed, 8 Nov 2023 16:29:22 +0000 Subject: [PATCH 19/25] fix: txtar tests load full config and execute serially (#1342) This fixes an issue where executing txtar tests would fail because the example packages weren't loaded into memory.
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [ ] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [ ] Updated the official documentation or not needed - [ ] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [ ] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--------- Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> Co-authored-by: gfanton <8671905+gfanton@users.noreply.github.com> --- gno.land/cmd/gnoland/integration_test.go | 3 +- gno.land/cmd/gnoland/testdata/import.txtar | 27 ++++++++++ gno.land/pkg/gnoland/node_inmemory.go | 8 +-- gno.land/pkg/integration/integration_test.go | 4 +- .../pkg/integration/testing_integration.go | 53 ++++++++++++------- 5 files changed, 67 insertions(+), 28 deletions(-) create mode 100644 gno.land/cmd/gnoland/testdata/import.txtar diff --git a/gno.land/cmd/gnoland/integration_test.go b/gno.land/cmd/gnoland/integration_test.go index 78c8e94fa09..37451df9704 100644 --- a/gno.land/cmd/gnoland/integration_test.go +++ b/gno.land/cmd/gnoland/integration_test.go @@ -4,9 +4,8 @@ import ( "testing" "github.com/gnolang/gno/gno.land/pkg/integration" - "github.com/rogpeppe/go-internal/testscript" ) func TestTestdata(t *testing.T) { - testscript.Run(t, integration.SetupGnolandTestScript(t, "testdata")) + integration.RunGnolandTestscripts(t, "testdata") } diff --git a/gno.land/cmd/gnoland/testdata/import.txtar b/gno.land/cmd/gnoland/testdata/import.txtar new file mode 100644 index 00000000000..3ad070654cf --- /dev/null +++ b/gno.land/cmd/gnoland/testdata/import.txtar @@ -0,0 +1,27 @@ +# test that the example packages directory is loaded and usable. + +## start a new node +gnoland start + +gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/importtest -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout OK! + +## execute Render +gnokey maketx call -pkgpath gno.land/r/importtest -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1 +stdout '("92054" string)' +stdout OK! + +-- gno.mod -- +module gno.land/r/importtest + +-- import.gno -- +package importtest + +import ( + "gno.land/p/demo/ufmt" +) + +func Render(_ string) string { + return ufmt.Sprintf("%d", 92054) +} + diff --git a/gno.land/pkg/gnoland/node_inmemory.go b/gno.land/pkg/gnoland/node_inmemory.go index a0ab6a51e82..0edef304281 100644 --- a/gno.land/pkg/gnoland/node_inmemory.go +++ b/gno.land/pkg/gnoland/node_inmemory.go @@ -128,9 +128,9 @@ func NewInMemoryNode(logger log.Logger, cfg *InMemoryNodeConfig) (*node.Node, er ) // Create genesis factory - genProvider := func() (*bft.GenesisDoc, error) { - return cfg.Genesis, nil - } + genProvider := func() (*bft.GenesisDoc, error) { return cfg.Genesis, nil } + + dbProvider := func(*node.DBContext) (db.DB, error) { return db.NewMemDB(), nil } // generate p2p node identity // XXX: do we need to configur @@ -141,7 +141,7 @@ func NewInMemoryNode(logger log.Logger, cfg *InMemoryNodeConfig) (*node.Node, er cfg.PrivValidator, nodekey, appClientCreator, genProvider, - node.DefaultDBProvider, + dbProvider, logger, ) } diff --git a/gno.land/pkg/integration/integration_test.go b/gno.land/pkg/integration/integration_test.go index 3c22a190d64..a474791de2e 100644 --- a/gno.land/pkg/integration/integration_test.go +++ b/gno.land/pkg/integration/integration_test.go @@ -2,10 +2,8 @@ package integration import ( "testing" - - "github.com/rogpeppe/go-internal/testscript" ) func TestTestdata(t *testing.T) { - testscript.Run(t, SetupGnolandTestScript(t, "testdata")) + RunGnolandTestscripts(t, "testdata") } diff --git a/gno.land/pkg/integration/testing_integration.go b/gno.land/pkg/integration/testing_integration.go index b773317513f..b10686b0105 100644 --- a/gno.land/pkg/integration/testing_integration.go +++ b/gno.land/pkg/integration/testing_integration.go @@ -8,7 +8,6 @@ import ( "path/filepath" "strconv" "strings" - "sync" "testing" "github.com/gnolang/gno/gno.land/pkg/gnoland" @@ -20,21 +19,44 @@ import ( "github.com/rogpeppe/go-internal/testscript" ) +type tSeqShim struct{ *testing.T } + +// noop Parallel method allow us to run test sequentially +func (tSeqShim) Parallel() {} + +func (t tSeqShim) Run(name string, f func(testscript.T)) { + t.T.Run(name, func(t *testing.T) { + f(tSeqShim{t}) + }) +} + +func (t tSeqShim) Verbose() bool { + return testing.Verbose() +} + +// RunGnolandTestscripts sets up and runs txtar integration tests for gnoland nodes. +// It prepares an in-memory gnoland node and initializes the necessary environment and custom commands. +// The function adapts the test setup for use with the testscript package, enabling +// the execution of gnoland and gnokey commands within txtar scripts. +// +// Refer to package documentation in doc.go for more information on commands and example txtar scripts. +func RunGnolandTestscripts(t *testing.T, txtarDir string) { + t.Helper() + + p := setupGnolandTestScript(t, txtarDir) + if deadline, ok := t.Deadline(); ok && p.Deadline.IsZero() { + p.Deadline = deadline + } + + testscript.RunT(tSeqShim{t}, p) +} + type testNode struct { *node.Node nGnoKeyExec uint // Counter for execution of gnokey. } -// SetupGnolandTestScript prepares the test environment to execute txtar tests -// using a partial InMemory gnoland node. It initializes key storage, sets up the gnoland node, -// and provides custom commands like "gnoland" and "gnokey" for txtar script execution. -// -// The function returns testscript.Params which contain the test setup and command -// executions to be used with the testscript package. -// -// For a detailed explanation of the commands and their behaviors, as well as -// example txtar scripts, refer to the package documentation in doc.go. -func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { +func setupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { t.Helper() tmpdir := t.TempDir() @@ -47,7 +69,6 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { gnoHomeDir := filepath.Join(tmpdir, "gno") // Testscripts run concurrently by default, so we need to be prepared for that. - var muNodes sync.Mutex nodes := map[string]*testNode{} updateScripts, _ := strconv.ParseBool(os.Getenv("UPDATE_SCRIPTS")) @@ -99,9 +120,6 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { }, Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){ "gnoland": func(ts *testscript.TestScript, neg bool, args []string) { - muNodes.Lock() - defer muNodes.Unlock() - if len(args) == 0 { tsValidateError(ts, "gnoland", neg, fmt.Errorf("syntax: gnoland [start|stop]")) return @@ -125,7 +143,7 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { t := TSTestingT(ts) // Generate config and node - cfg := TestingMinimalNodeConfig(t, gnoRootDir) + cfg, _ := TestingNodeConfig(t, gnoRootDir) n, remoteAddr := TestingInMemoryNode(t, logger, cfg) // Register cleanup @@ -156,9 +174,6 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params { tsValidateError(ts, "gnoland "+cmd, neg, err) }, "gnokey": func(ts *testscript.TestScript, neg bool, args []string) { - muNodes.Lock() - defer muNodes.Unlock() - logger := ts.Value("_logger").(log.Logger) // grab logger sid := ts.Getenv("SID") // grab session id From e803c45154cfda03de5542b9cb1a29d22a68f031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milo=C5=A1=20=C5=BDivkovi=C4=87?= Date: Thu, 9 Nov 2023 15:07:58 +0100 Subject: [PATCH 20/25] test: make tests run in parallel (#1312) ## Description This PR simply introduces `t.Parallel()` for unit tests that can support it.
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [ ] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--------- Co-authored-by: Guilhem Fanton <8671905+gfanton@users.noreply.github.com> --- gno.land/cmd/gnoland/start_test.go | 5 + gno.land/pkg/integration/integration_test.go | 2 + gnovm/pkg/gnolang/alloc_test.go | 2 + gnovm/pkg/gnolang/gno_test.go | 32 +++++ gnovm/pkg/gnolang/go2gno_test.go | 2 + gnovm/pkg/gnolang/gonative_test.go | 4 + gnovm/pkg/gnolang/package_test.go | 2 + gnovm/pkg/gnolang/precompile_test.go | 4 + gnovm/pkg/gnolang/values_conversions_test.go | 2 + gnovm/pkg/repl/repl_test.go | 4 + gnovm/tests/selector_test.go | 2 + misc/docker-integration/integration_test.go | 2 + tm2/pkg/amino/amino_test.go | 14 +++ tm2/pkg/amino/binary_encode_test.go | 4 + tm2/pkg/amino/binary_test.go | 22 ++++ tm2/pkg/amino/byteslice_test.go | 2 + tm2/pkg/amino/codec_test.go | 16 +++ tm2/pkg/amino/deep_copy_test.go | 22 ++++ tm2/pkg/amino/encoder_test.go | 5 + tm2/pkg/amino/gengo/gengo_test.go | 2 + tm2/pkg/amino/genproto/bindings_test.go | 2 + tm2/pkg/amino/genproto/genproto_test.go | 2 + tm2/pkg/amino/genproto/types_test.go | 2 + tm2/pkg/amino/json_test.go | 16 +++ tm2/pkg/amino/libs/press/press_test.go | 18 +++ tm2/pkg/amino/pkg/pkg_test.go | 6 + tm2/pkg/amino/reflect_test.go | 66 ++++++++-- tm2/pkg/amino/repr_test.go | 4 + .../amino/tests/proto3/proto3_compat_test.go | 26 ++++ tm2/pkg/amino/time2_test.go | 4 + tm2/pkg/amino/wellknown_test.go | 2 + tm2/pkg/async/async_test.go | 8 +- tm2/pkg/autofile/group_test.go | 14 +++ tm2/pkg/bech32/bech32_test.go | 6 + tm2/pkg/bft/blockchain/pool_test.go | 6 + tm2/pkg/bft/blockchain/reactor_test.go | 22 +++- tm2/pkg/bft/config/toml_test.go | 4 + tm2/pkg/bft/consensus/mempool_test.go | 8 ++ tm2/pkg/bft/consensus/reactor_test.go | 44 +++++++ tm2/pkg/bft/consensus/replay_test.go | 18 +++ tm2/pkg/bft/consensus/state_test.go | 56 +++++++++ .../consensus/types/height_vote_set_test.go | 2 + tm2/pkg/bft/consensus/wal_test.go | 2 + tm2/pkg/bft/mempool/cache_test.go | 4 + tm2/pkg/bft/mempool/reactor_test.go | 12 ++ tm2/pkg/bft/privval/file_test.go | 16 +++ tm2/pkg/bft/privval/signer_client_test.go | 20 ++++ .../privval/signer_listener_endpoint_test.go | 4 + tm2/pkg/bft/privval/socket_dialers_test.go | 4 + tm2/pkg/bft/privval/socket_listeners_test.go | 4 + tm2/pkg/bft/privval/utils_test.go | 2 + tm2/pkg/bft/rpc/client/helpers_test.go | 2 + tm2/pkg/bft/rpc/client/rpc_test.go | 34 ++++++ tm2/pkg/bft/rpc/core/blocks_test.go | 2 + tm2/pkg/bft/rpc/core/net_test.go | 4 + tm2/pkg/bft/rpc/core/pipe_test.go | 4 + tm2/pkg/bft/rpc/core/types/responses_test.go | 2 + tm2/pkg/bft/rpc/lib/client/args_test.go | 2 + .../bft/rpc/lib/client/http_client_test.go | 6 + .../bft/rpc/lib/client/integration_test.go | 2 + tm2/pkg/bft/rpc/lib/client/ws_client_test.go | 8 ++ tm2/pkg/bft/rpc/lib/rpc_test.go | 12 ++ tm2/pkg/bft/rpc/lib/server/handlers_test.go | 12 ++ .../bft/rpc/lib/server/http_server_test.go | 8 ++ tm2/pkg/bft/rpc/lib/server/parse_test.go | 8 ++ tm2/pkg/bft/rpc/lib/types/types_test.go | 6 + tm2/pkg/bft/state/execution_test.go | 16 +++ tm2/pkg/bft/state/state_test.go | 32 +++++ tm2/pkg/bft/state/store_test.go | 2 + tm2/pkg/bft/state/validation_test.go | 4 + tm2/pkg/bft/store/store_test.go | 12 ++ tm2/pkg/bft/types/block_test.go | 38 ++++++ tm2/pkg/bft/types/evidence_test.go | 16 +++ tm2/pkg/bft/types/genesis_test.go | 8 ++ tm2/pkg/bft/types/params_test.go | 6 + tm2/pkg/bft/types/part_set_test.go | 12 ++ tm2/pkg/bft/types/proposal_test.go | 10 ++ tm2/pkg/bft/types/results_test.go | 4 + tm2/pkg/bft/types/time/time_test.go | 2 + tm2/pkg/bft/types/tx_test.go | 8 ++ tm2/pkg/bft/types/validator_set_test.go | 52 +++++++- tm2/pkg/bft/types/vote_set_test.go | 12 ++ tm2/pkg/bft/types/vote_test.go | 24 ++++ tm2/pkg/bft/wal/wal_test.go | 8 ++ tm2/pkg/bitarray/bit_array_test.go | 20 ++++ tm2/pkg/clist/clist_test.go | 113 ++---------------- tm2/pkg/cmap/cmap_test.go | 4 + tm2/pkg/commands/commands_test.go | 25 ++-- tm2/pkg/crypto/bcrypt/bcrypt_test.go | 22 ++++ tm2/pkg/crypto/bech32_test.go | 4 + tm2/pkg/crypto/bip39/bip39_test.go | 10 ++ tm2/pkg/crypto/ed25519/ed25519_test.go | 2 + tm2/pkg/crypto/hd/fundraiser_test.go | 2 + tm2/pkg/crypto/hd/hdpath_test.go | 6 + tm2/pkg/crypto/keys/keybase_test.go | 18 +++ tm2/pkg/crypto/keys/types_test.go | 2 + tm2/pkg/crypto/merkle/proof_key_path_test.go | 2 + tm2/pkg/crypto/merkle/proof_test.go | 2 + tm2/pkg/crypto/merkle/rfc6962_test.go | 6 + tm2/pkg/crypto/merkle/simple_map_test.go | 2 + tm2/pkg/crypto/merkle/simple_proof_test.go | 4 + tm2/pkg/crypto/merkle/simple_tree_test.go | 6 + tm2/pkg/crypto/mock/mock_test.go | 2 + .../bitarray/compact_bit_array_test.go | 16 +++ .../crypto/multisig/threshold_pubkey_test.go | 10 ++ tm2/pkg/crypto/random_test.go | 2 + .../crypto/secp256k1/secp256k1_cgo_test.go | 4 + .../secp256k1/secp256k1_internal_test.go | 4 + .../crypto/secp256k1/secp256k1_nocgo_test.go | 2 + tm2/pkg/crypto/secp256k1/secp256k1_test.go | 10 ++ tm2/pkg/crypto/tmhash/hash_test.go | 4 + .../crypto/xchacha20poly1305/vector_test.go | 4 + .../xchacha20poly1305/xchachapoly_test.go | 2 + .../xsalsa20symmetric/symmetric_test.go | 4 + tm2/pkg/db/backend_test.go | 12 +- tm2/pkg/db/boltdb_test.go | 2 + tm2/pkg/db/c_level_db_test.go | 4 + tm2/pkg/db/db_test.go | 26 ++++ tm2/pkg/db/go_level_db_test.go | 2 + tm2/pkg/db/gorocks_db_test.go | 4 + tm2/pkg/db/grocks_db_test.go | 4 + tm2/pkg/db/prefix_db_test.go | 24 ++++ tm2/pkg/db/util_test.go | 20 ++++ tm2/pkg/errors/errors_test.go | 16 +++ tm2/pkg/events/events_test.go | 12 ++ tm2/pkg/flow/io_test.go | 4 + tm2/pkg/iavl/basic_test.go | 16 +++ tm2/pkg/iavl/common/random_test.go | 4 + tm2/pkg/iavl/proof_forgery_test.go | 2 + tm2/pkg/iavl/proof_test.go | 6 + tm2/pkg/iavl/tree_dotgraph_test.go | 2 + tm2/pkg/iavl/tree_fuzz_test.go | 2 + tm2/pkg/iavl/tree_test.go | 64 ++++++++++ tm2/pkg/log/tm_logger_test.go | 2 + tm2/pkg/os/net_test.go | 2 + tm2/pkg/p2p/conn/connection_test.go | 28 +++++ tm2/pkg/p2p/conn/secret_connection_test.go | 18 +++ tm2/pkg/p2p/key_test.go | 6 +- tm2/pkg/p2p/netaddress_test.go | 16 +++ tm2/pkg/p2p/node_info_test.go | 4 + tm2/pkg/p2p/peer_test.go | 4 + tm2/pkg/p2p/switch_test.go | 28 +++++ tm2/pkg/p2p/transport_test.go | 22 ++++ tm2/pkg/random/random_test.go | 8 ++ tm2/pkg/sdk/auth/ante_test.go | 41 ++++++- tm2/pkg/sdk/auth/keeper_test.go | 4 + tm2/pkg/sdk/bank/handler_test.go | 6 + tm2/pkg/sdk/bank/keeper_test.go | 6 + tm2/pkg/sdk/baseapp_test.go | 51 ++++++-- tm2/pkg/service/service_test.go | 4 + tm2/pkg/std/coin_test.go | 62 ++++++++++ tm2/pkg/std/kvpair_test.go | 4 + tm2/pkg/store/cache/store_test.go | 20 ++++ tm2/pkg/store/gas/store_test.go | 8 ++ tm2/pkg/store/iavl/store_test.go | 26 ++++ tm2/pkg/store/prefix/store_test.go | 30 +++++ tm2/pkg/store/rootmulti/proof_test.go | 8 ++ tm2/pkg/store/rootmulti/store_test.go | 14 +++ tm2/pkg/store/types/gas_test.go | 4 + tm2/pkg/strings/string_test.go | 8 ++ tm2/pkg/timer/throttle_timer_test.go | 2 + 161 files changed, 1765 insertions(+), 143 deletions(-) diff --git a/gno.land/cmd/gnoland/start_test.go b/gno.land/cmd/gnoland/start_test.go index 27ef2f572ea..6606d88ba2e 100644 --- a/gno.land/cmd/gnoland/start_test.go +++ b/gno.land/cmd/gnoland/start_test.go @@ -13,6 +13,8 @@ import ( ) func TestStartInitialize(t *testing.T) { + t.Parallel() + cases := []struct { args []string }{ @@ -23,8 +25,11 @@ func TestStartInitialize(t *testing.T) { os.Chdir(filepath.Join("..", "..")) // go to repo's root dir for _, tc := range cases { + tc := tc name := strings.Join(tc.args, " ") t.Run(name, func(t *testing.T) { + t.Parallel() + mockOut := bytes.NewBufferString("") mockErr := bytes.NewBufferString("") io := commands.NewTestIO() diff --git a/gno.land/pkg/integration/integration_test.go b/gno.land/pkg/integration/integration_test.go index a474791de2e..f88707f2b90 100644 --- a/gno.land/pkg/integration/integration_test.go +++ b/gno.land/pkg/integration/integration_test.go @@ -5,5 +5,7 @@ import ( ) func TestTestdata(t *testing.T) { + t.Parallel() + RunGnolandTestscripts(t, "testdata") } diff --git a/gnovm/pkg/gnolang/alloc_test.go b/gnovm/pkg/gnolang/alloc_test.go index e3b9f1cb069..dbb3903f862 100644 --- a/gnovm/pkg/gnolang/alloc_test.go +++ b/gnovm/pkg/gnolang/alloc_test.go @@ -6,6 +6,8 @@ import ( ) func TestAllocSizes(t *testing.T) { + t.Parallel() + // go elemental println("_allocPointer", unsafe.Sizeof(&StructValue{})) println("_allocSlice", unsafe.Sizeof([]byte("12345678901234567890123456789012345678901234567890"))) diff --git a/gnovm/pkg/gnolang/gno_test.go b/gnovm/pkg/gnolang/gno_test.go index 5ed5971c836..37b590b1c4c 100644 --- a/gnovm/pkg/gnolang/gno_test.go +++ b/gnovm/pkg/gnolang/gno_test.go @@ -13,6 +13,8 @@ import ( // run empty main(). func TestRunEmptyMain(t *testing.T) { + t.Parallel() + m := NewMachine("test", nil) main := FuncD("main", nil, nil, nil) m.RunDeclaration(main) @@ -21,6 +23,8 @@ func TestRunEmptyMain(t *testing.T) { // run main() with a for loop. func TestRunLoopyMain(t *testing.T) { + t.Parallel() + m := NewMachine("test", nil) c := `package test func main() { @@ -36,6 +40,8 @@ func main() { } func TestEval(t *testing.T) { + t.Parallel() + m := NewMachine("test", nil) c := `package test func next(i int) int { @@ -64,6 +70,8 @@ func assertOutput(t *testing.T, input string, output string) { } func TestRunMakeStruct(t *testing.T) { + t.Parallel() + assertOutput(t, `package test type Outfit struct { Scarf string @@ -90,6 +98,8 @@ func main() { } func TestRunReturnStruct(t *testing.T) { + t.Parallel() + assertOutput(t, `package test type MyStruct struct { FieldA string @@ -160,6 +170,8 @@ type Struct1 struct { } func TestModifyTypeAsserted(t *testing.T) { + t.Parallel() + x := Struct1{1, 1} var v interface{} = x x2 := v.(Struct1) @@ -176,6 +188,8 @@ type Interface1 interface { } func TestTypeConversion(t *testing.T) { + t.Parallel() + x := 1 var v interface{} = x if _, ok := v.(Interface1); ok { @@ -193,6 +207,8 @@ func TestTypeConversion(t *testing.T) { } func TestSomething(t *testing.T) { + t.Parallel() + type Foo struct { X interface{} } @@ -210,6 +226,8 @@ func TestSomething(t *testing.T) { // XXX is there a way to test in Go as well as Gno? func TestDeferOrder(t *testing.T) { + t.Parallel() + a := func() func(int, int) int { fmt.Println("a constructed") return func(x int, y int) int { @@ -238,6 +256,8 @@ func TestDeferOrder(t *testing.T) { // XXX is there a way to test in Go as well as Gno? func TestCallOrder(t *testing.T) { + t.Parallel() + a := func() func(int, int) int { fmt.Println("a constructed") return func(x int, y int) int { @@ -264,6 +284,8 @@ func TestCallOrder(t *testing.T) { // XXX is there a way to test in Go as well as Gno? func TestBinaryShortCircuit(t *testing.T) { + t.Parallel() + tr := func() bool { fmt.Println("t called") return true @@ -281,6 +303,8 @@ func TestBinaryShortCircuit(t *testing.T) { // XXX is there a way to test in Go as well as Gno? func TestSwitchDefine(t *testing.T) { + t.Parallel() + var x interface{} = 1 switch y := x.(type) { case int: @@ -292,6 +316,8 @@ func TestSwitchDefine(t *testing.T) { // XXX is there a way to test in Go as well as Gno? func TestBinaryCircuit(t *testing.T) { + t.Parallel() + tr := func() bool { fmt.Println("tr() called") return true @@ -316,6 +342,8 @@ func TestBinaryCircuit(t *testing.T) { } func TestMultiAssignment(t *testing.T) { + t.Parallel() + buf := make([]int, 4) ref := func(i int) *int { fmt.Printf("ref(%v) called\n", i) @@ -342,6 +370,8 @@ func TestMultiAssignment(t *testing.T) { // XXX is there a way to test in Go as well as Gno? func TestCallLHS(t *testing.T) { + t.Parallel() + x := 1 xptr := func() *int { return &x @@ -352,6 +382,8 @@ func TestCallLHS(t *testing.T) { // XXX is there a way to test in Go as well as Gno? func TestCallFieldLHS(t *testing.T) { + t.Parallel() + type str struct { X int } diff --git a/gnovm/pkg/gnolang/go2gno_test.go b/gnovm/pkg/gnolang/go2gno_test.go index 6a1413a07e1..d5b94c618b0 100644 --- a/gnovm/pkg/gnolang/go2gno_test.go +++ b/gnovm/pkg/gnolang/go2gno_test.go @@ -8,6 +8,8 @@ import ( ) func TestParseForLoop(t *testing.T) { + t.Parallel() + gocode := `package main func main(){ for i:=0; i<10; i++ { diff --git a/gnovm/pkg/gnolang/gonative_test.go b/gnovm/pkg/gnolang/gonative_test.go index b9b659aae99..e348ffe9c22 100644 --- a/gnovm/pkg/gnolang/gonative_test.go +++ b/gnovm/pkg/gnolang/gonative_test.go @@ -98,6 +98,8 @@ D: } func TestGoNativeDefine3(t *testing.T) { + t.Parallel() + // Create package foo and define Foo. out := new(bytes.Buffer) pkg := NewPackageNode("foo", "test.foo", nil) @@ -135,6 +137,8 @@ D: } func TestCrypto(t *testing.T) { + t.Parallel() + addr := crypto.Address{} store := gonativeTestStore() tv := Go2GnoValue(nilAllocator, store, reflect.ValueOf(addr)) diff --git a/gnovm/pkg/gnolang/package_test.go b/gnovm/pkg/gnolang/package_test.go index 47efd736bac..f219ba9b23f 100644 --- a/gnovm/pkg/gnolang/package_test.go +++ b/gnovm/pkg/gnolang/package_test.go @@ -12,6 +12,8 @@ import ( // Tries to reproduce the bug #1036 on all registered types func TestAminoJSONRegisteredTypes(t *testing.T) { + t.Parallel() + for _, typ := range Package.Types { // Instantiate registered type x := reflect.New(typ.Type).Interface() diff --git a/gnovm/pkg/gnolang/precompile_test.go b/gnovm/pkg/gnolang/precompile_test.go index 3d50353505f..e2cb5e92d86 100644 --- a/gnovm/pkg/gnolang/precompile_test.go +++ b/gnovm/pkg/gnolang/precompile_test.go @@ -12,6 +12,8 @@ import ( ) func TestPrecompile(t *testing.T) { + t.Parallel() + cases := []struct { name string source string @@ -56,6 +58,8 @@ func TestPrecompile(t *testing.T) { for _, c := range cases { c := c // scopelint t.Run(c.name, func(t *testing.T) { + t.Parallel() + // parse gno fset := token.NewFileSet() f, err := parser.ParseFile(fset, "foo.go", c.source, parser.ParseComments) diff --git a/gnovm/pkg/gnolang/values_conversions_test.go b/gnovm/pkg/gnolang/values_conversions_test.go index b9ac9e68d68..e92496c1ac2 100644 --- a/gnovm/pkg/gnolang/values_conversions_test.go +++ b/gnovm/pkg/gnolang/values_conversions_test.go @@ -9,6 +9,8 @@ import ( ) func TestConvertUntypedBigdecToFloat(t *testing.T) { + t.Parallel() + dst := &TypedValue{} dec, err := apd.New(-math.MaxInt64, -4).SetFloat64(math.SmallestNonzeroFloat64 / 2) diff --git a/gnovm/pkg/repl/repl_test.go b/gnovm/pkg/repl/repl_test.go index 3c4d1f7c6c6..09c350dd49a 100644 --- a/gnovm/pkg/repl/repl_test.go +++ b/gnovm/pkg/repl/repl_test.go @@ -199,6 +199,8 @@ func TestRepl(t *testing.T) { } func TestReplOpts(t *testing.T) { + t.Parallel() + require := require.New(t) r := NewRepl(WithStd(nil, nil, nil), WithStore(nil)) @@ -212,6 +214,8 @@ func TestReplOpts(t *testing.T) { } func TestReplReset(t *testing.T) { + t.Parallel() + require := require.New(t) r := NewRepl() diff --git a/gnovm/tests/selector_test.go b/gnovm/tests/selector_test.go index 4d6e9c587b0..1f0b400555b 100644 --- a/gnovm/tests/selector_test.go +++ b/gnovm/tests/selector_test.go @@ -52,6 +52,8 @@ func _printValue(x interface{}) { } func TestSelectors(t *testing.T) { + t.Parallel() + x0 := struct{ F0 int }{1} _printValue(x0.F0) // *ST.F0 // F:0 diff --git a/misc/docker-integration/integration_test.go b/misc/docker-integration/integration_test.go index 6ae0ea1d36e..1142709cc16 100644 --- a/misc/docker-integration/integration_test.go +++ b/misc/docker-integration/integration_test.go @@ -29,6 +29,8 @@ const ( ) func TestDockerIntegration(t *testing.T) { + t.Parallel() + tmpdir, err := os.MkdirTemp(os.TempDir(), "*-gnoland-integration") require.NoError(t, err) diff --git a/tm2/pkg/amino/amino_test.go b/tm2/pkg/amino/amino_test.go index a06601a43da..d7dd0dc5b98 100644 --- a/tm2/pkg/amino/amino_test.go +++ b/tm2/pkg/amino/amino_test.go @@ -10,6 +10,8 @@ import ( ) func TestMarshal(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() type SimpleStruct struct { @@ -35,6 +37,8 @@ func TestMarshal(t *testing.T) { } func TestUnmarshalReader(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() type SimpleStruct struct { @@ -65,6 +69,8 @@ type stringWrapper struct { } func TestUnmarshalReaderSize(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() s1 := stringWrapper{"foo"} @@ -82,6 +88,8 @@ func TestUnmarshalReaderSize(t *testing.T) { } func TestUnmarshalReaderSizeLimit(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() s1 := stringWrapper{"foo"} @@ -101,6 +109,8 @@ func TestUnmarshalReaderSizeLimit(t *testing.T) { } func TestUnmarshalReaderTooLong(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() type SimpleStruct struct { @@ -125,6 +135,8 @@ func TestUnmarshalReaderTooLong(t *testing.T) { } func TestUnmarshalBufferedWritesReads(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() buf := bytes.NewBuffer(nil) @@ -155,6 +167,8 @@ func TestUnmarshalBufferedWritesReads(t *testing.T) { } func TestBoolPointers(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() type SimpleStruct struct { BoolPtrTrue *bool diff --git a/tm2/pkg/amino/binary_encode_test.go b/tm2/pkg/amino/binary_encode_test.go index 8208bb74c67..a775a911cf6 100644 --- a/tm2/pkg/amino/binary_encode_test.go +++ b/tm2/pkg/amino/binary_encode_test.go @@ -8,6 +8,8 @@ import ( ) func TestEncodeFieldNumberAndTyp3_1(t *testing.T) { + t.Parallel() + buf := new(bytes.Buffer) err := encodeFieldNumberAndTyp3(buf, 1, Typ3ByteLength) assert.Nil(t, err) @@ -15,6 +17,8 @@ func TestEncodeFieldNumberAndTyp3_1(t *testing.T) { } func TestEncodeFieldNumberAndTyp3_2(t *testing.T) { + t.Parallel() + buf := new(bytes.Buffer) err := encodeFieldNumberAndTyp3(buf, 2, Typ3ByteLength) assert.Nil(t, err) diff --git a/tm2/pkg/amino/binary_test.go b/tm2/pkg/amino/binary_test.go index 8516ac2e1fa..e50427afeef 100644 --- a/tm2/pkg/amino/binary_test.go +++ b/tm2/pkg/amino/binary_test.go @@ -12,6 +12,8 @@ import ( ) func TestNilSliceEmptySlice(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() type TestStruct struct { @@ -59,6 +61,8 @@ func TestNilSliceEmptySlice(t *testing.T) { } func TestNewFieldBackwardsCompatibility(t *testing.T) { + t.Parallel() + type V1 struct { String string String2 string @@ -109,6 +113,8 @@ func TestNewFieldBackwardsCompatibility(t *testing.T) { } func TestWriteEmpty(t *testing.T) { + t.Parallel() + type Inner struct { Val int } @@ -136,6 +142,8 @@ func TestWriteEmpty(t *testing.T) { } func TestForceWriteEmpty(t *testing.T) { + t.Parallel() + type InnerWriteEmpty struct { // sth. that isn't zero-len if default, e.g. fixed32: ValIn int32 `amino:"write_empty" binary:"fixed32"` @@ -158,6 +166,8 @@ func TestForceWriteEmpty(t *testing.T) { } func TestStructSlice(t *testing.T) { + t.Parallel() + type Foo struct { A uint B uint @@ -182,6 +192,8 @@ func TestStructSlice(t *testing.T) { } func TestStructPointerSlice1(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() type Foo struct { @@ -220,6 +232,8 @@ func TestStructPointerSlice1(t *testing.T) { // Like TestStructPointerSlice2, but without nil_elements field tag. func TestStructPointerSlice2(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() type Foo struct { @@ -251,6 +265,8 @@ func TestStructPointerSlice2(t *testing.T) { } func TestBasicTypes(t *testing.T) { + t.Parallel() + // we explicitly disallow type definitions like the following: type byteAlias []byte @@ -268,6 +284,8 @@ func TestBasicTypes(t *testing.T) { } func TestUnmarshalMapBinary(t *testing.T) { + t.Parallel() + obj := new(map[string]int) cdc := amino.NewCodec() @@ -291,6 +309,8 @@ func TestUnmarshalMapBinary(t *testing.T) { } func TestUnmarshalFuncBinary(t *testing.T) { + t.Parallel() + obj := func() {} cdc := amino.NewCodec() // Binary doesn't support decoding to a func... @@ -316,6 +336,8 @@ func TestUnmarshalFuncBinary(t *testing.T) { } func TestDuration(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() d0 := time.Duration(0) bz := cdc.MustMarshal(d0) diff --git a/tm2/pkg/amino/byteslice_test.go b/tm2/pkg/amino/byteslice_test.go index 310b294a8b7..80faca8e4e9 100644 --- a/tm2/pkg/amino/byteslice_test.go +++ b/tm2/pkg/amino/byteslice_test.go @@ -6,6 +6,8 @@ import ( ) func TestReadByteSliceEquality(t *testing.T) { + t.Parallel() + var encoded []byte var err error cdc := NewCodec() diff --git a/tm2/pkg/amino/codec_test.go b/tm2/pkg/amino/codec_test.go index 18bc8f2cd5d..9368d4ef40e 100644 --- a/tm2/pkg/amino/codec_test.go +++ b/tm2/pkg/amino/codec_test.go @@ -29,6 +29,8 @@ func newSimpleStruct() SimpleStruct { } func TestMarshalUnmarshalPointer0(t *testing.T) { + t.Parallel() + s := newSimpleStruct() cdc := amino.NewCodec() b, err := cdc.MarshalSized(s) // no indirection @@ -41,6 +43,8 @@ func TestMarshalUnmarshalPointer0(t *testing.T) { } func TestMarshalUnmarshalPointer1(t *testing.T) { + t.Parallel() + s := newSimpleStruct() cdc := amino.NewCodec() b, err := cdc.MarshalSized(&s) // extra indirection @@ -53,6 +57,8 @@ func TestMarshalUnmarshalPointer1(t *testing.T) { } func TestMarshalUnmarshalPointer2(t *testing.T) { + t.Parallel() + s := newSimpleStruct() ptr := &s cdc := amino.NewCodec() @@ -63,6 +69,8 @@ func TestMarshalUnmarshalPointer2(t *testing.T) { } func TestMarshalUnmarshalPointer3(t *testing.T) { + t.Parallel() + s := newSimpleStruct() cdc := amino.NewCodec() b, err := cdc.MarshalSized(s) // no indirection @@ -75,6 +83,8 @@ func TestMarshalUnmarshalPointer3(t *testing.T) { } func TestDecodeVarint8(t *testing.T) { + t.Parallel() + // DecodeVarint8 uses binary.Varint so we need to make // sure that all the values out of the range of [-128, 127] // return an error. @@ -122,6 +132,8 @@ func TestDecodeVarint8(t *testing.T) { } func TestDecodeVarint16(t *testing.T) { + t.Parallel() + // DecodeVarint16 uses binary.Varint so we need to make // sure that all the values out of the range of [-32768, 32767] // return an error. @@ -170,6 +182,8 @@ func TestDecodeVarint16(t *testing.T) { } func TestEncodeDecodeString(t *testing.T) { + t.Parallel() + s := "🔌🎉⛵︎♠️⎍" bs := []byte(s) di := len(bs) * 3 / 4 @@ -214,6 +228,8 @@ func TestEncodeDecodeString(t *testing.T) { } func TestCodecSeal(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() cdc.Seal() diff --git a/tm2/pkg/amino/deep_copy_test.go b/tm2/pkg/amino/deep_copy_test.go index 55aff4c6a60..f2a793bfca1 100644 --- a/tm2/pkg/amino/deep_copy_test.go +++ b/tm2/pkg/amino/deep_copy_test.go @@ -15,6 +15,8 @@ func (dcf *DCFoo1) MarshalAmino() (string, error) { return dcf.a, nil } func (dcf *DCFoo1) UnmarshalAmino(s string) error { dcf.a = s; return nil } func TestDeepCopyFoo1(t *testing.T) { + t.Parallel() + dcf1 := newDCFoo1("foobar") dcf2 := amino.DeepCopy(dcf1).(*DCFoo1) assert.Equal(t, "foobar", dcf2.a) @@ -27,6 +29,8 @@ func (dcf DCFoo2) MarshalAmino() (string, error) { return dcf.a, nil } // non-p func (dcf *DCFoo2) UnmarshalAmino(s string) error { dcf.a = s; return nil } func TestDeepCopyFoo2(t *testing.T) { + t.Parallel() + dcf1 := newDCFoo2("foobar") dcf2 := amino.DeepCopy(dcf1).(*DCFoo2) assert.Equal(t, "foobar", dcf2.a) @@ -39,6 +43,8 @@ func (dcf DCFoo3) MarshalAmino() (string, error) { return dcf.a, nil } func (dcf *DCFoo3) UnmarshalAmino(s []byte) error { dcf.a = string(s); return nil } // mismatch type func TestDeepCopyFoo3(t *testing.T) { + t.Parallel() + dcf1 := newDCFoo3("foobar") dcf2 := amino.DeepCopy(dcf1).(*DCFoo3) assert.Equal(t, "", dcf2.a) @@ -52,6 +58,8 @@ func (dcf DCFoo4) MarshalAmino() (string, error) { return dcf.a, nil } func (dcf *DCFoo4) UnmarshalAmino(s string) error { dcf.a = s; return nil } // mismatch type func TestDeepCopyFoo4(t *testing.T) { + t.Parallel() + dcf1 := newDCFoo4("foobar") dcf2 := amino.DeepCopy(dcf1).(*DCFoo4) assert.Equal(t, "good", dcf2.a) @@ -65,6 +73,8 @@ func (dcf DCFoo5) MarshalAmino() (string, error) { return dcf.a, nil } func (dcf *DCFoo5) UnmarshalAmino(s string) error { dcf.a = s; return nil } // mismatch type func TestDeepCopyFoo5(t *testing.T) { + t.Parallel() + dcf1 := newDCFoo5("foobar") dcf2 := amino.DeepCopy(dcf1).(*DCFoo5) assert.Equal(t, "good", dcf2.a) @@ -76,6 +86,8 @@ func newDCFoo6(a string) *DCFoo6 { return &DCFoo6{a: a} } func (dcf *DCFoo6) DeepCopy() DCFoo6 { return DCFoo6{"good"} } func TestDeepCopyFoo6(t *testing.T) { + t.Parallel() + dcf1 := newDCFoo6("foobar") dcf2 := amino.DeepCopy(dcf1).(*DCFoo6) assert.Equal(t, "good", dcf2.a) @@ -87,6 +99,8 @@ func newDCFoo7(a string) *DCFoo7 { return &DCFoo7{a: a} } func (dcf DCFoo7) DeepCopy() *DCFoo7 { return &DCFoo7{"good"} } func TestDeepCopyFoo7(t *testing.T) { + t.Parallel() + dcf1 := newDCFoo7("foobar") dcf2 := amino.DeepCopy(dcf1).(*DCFoo7) assert.Equal(t, "good", dcf2.a) @@ -99,6 +113,8 @@ func (dcf DCFoo8) MarshalAmino() (string, error) { return "", errors.New("uh oh func (dcf *DCFoo8) UnmarshalAmino(s string) error { dcf.a = s; return nil } func TestDeepCopyFoo8(t *testing.T) { + t.Parallel() + dcf1 := newDCFoo8("foobar") assert.Panics(t, func() { amino.DeepCopy(dcf1) }) } @@ -110,6 +126,8 @@ func (dcf DCFoo9) MarshalAmino() (string, error) { return dcf.a, nil } func (dcf *DCFoo9) UnmarshalAmino(s string) error { return errors.New("uh oh") } // error func TestDeepCopyFoo9(t *testing.T) { + t.Parallel() + dcf1 := newDCFoo9("foobar") assert.Panics(t, func() { amino.DeepCopy(dcf1) }) } @@ -119,12 +137,16 @@ type DCInterface1 struct { } func TestDeepCopyInterface1(t *testing.T) { + t.Parallel() + dci1 := DCInterface1{Foo: nil} dci2 := amino.DeepCopy(dci1).(DCInterface1) assert.Nil(t, dci2.Foo) } func TestDeepCopyInterface2(t *testing.T) { + t.Parallel() + dci1 := DCInterface1{Foo: "foo"} dci2 := amino.DeepCopy(dci1).(DCInterface1) assert.Equal(t, "foo", dci2.Foo) diff --git a/tm2/pkg/amino/encoder_test.go b/tm2/pkg/amino/encoder_test.go index 5c8afc4833d..02ece6fd667 100644 --- a/tm2/pkg/amino/encoder_test.go +++ b/tm2/pkg/amino/encoder_test.go @@ -7,6 +7,8 @@ import ( ) func TestUvarintSize(t *testing.T) { + t.Parallel() + testCases := []struct { name string u uint64 @@ -22,7 +24,10 @@ func TestUvarintSize(t *testing.T) { {"64 bits", 1 << 63, 10}, } for i, tc := range testCases { + tc := tc t.Run(tc.name, func(t *testing.T) { + t.Parallel() + require.Equal(t, tc.want, UvarintSize(tc.u), "#%d", i) //nolint:scopelint }) } diff --git a/tm2/pkg/amino/gengo/gengo_test.go b/tm2/pkg/amino/gengo/gengo_test.go index 88b25d9acdd..404b1c77c23 100644 --- a/tm2/pkg/amino/gengo/gengo_test.go +++ b/tm2/pkg/amino/gengo/gengo_test.go @@ -15,6 +15,8 @@ type SampleStruct struct { } func TestBasic(t *testing.T) { + t.Parallel() + p := press.NewPress() fmt.Println(p) ss := SampleStruct{"cat", "dog"} diff --git a/tm2/pkg/amino/genproto/bindings_test.go b/tm2/pkg/amino/genproto/bindings_test.go index 295c388def3..d1911d43542 100644 --- a/tm2/pkg/amino/genproto/bindings_test.go +++ b/tm2/pkg/amino/genproto/bindings_test.go @@ -11,6 +11,8 @@ import ( ) func TestGenerateProtoBindings(t *testing.T) { + t.Parallel() + file, err := GenerateProtoBindingsForTypes(tests.Package, tests.Package.ReflectTypes()...) assert.NoError(t, err) t.Logf("%v", file) diff --git a/tm2/pkg/amino/genproto/genproto_test.go b/tm2/pkg/amino/genproto/genproto_test.go index 20a45361519..2a52741c901 100644 --- a/tm2/pkg/amino/genproto/genproto_test.go +++ b/tm2/pkg/amino/genproto/genproto_test.go @@ -9,6 +9,8 @@ import ( ) func TestBasic(t *testing.T) { + t.Parallel() + p3c := NewP3Context() p3c.RegisterPackage(sm1.Package) p3doc := P3Doc{PackageName: "test"} diff --git a/tm2/pkg/amino/genproto/types_test.go b/tm2/pkg/amino/genproto/types_test.go index 8b7398ab184..4e57427e809 100644 --- a/tm2/pkg/amino/genproto/types_test.go +++ b/tm2/pkg/amino/genproto/types_test.go @@ -7,6 +7,8 @@ import ( ) func TestPrintP3Types(t *testing.T) { + t.Parallel() + doc := P3Doc{ Comment: "doc comment", Messages: []P3Message{ diff --git a/tm2/pkg/amino/json_test.go b/tm2/pkg/amino/json_test.go index 81118080d89..e3f7d413fcb 100644 --- a/tm2/pkg/amino/json_test.go +++ b/tm2/pkg/amino/json_test.go @@ -29,6 +29,8 @@ func registerTransports(cdc *amino.Codec) { } func TestMarshalJSON(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() registerTransports(cdc) cases := []struct { @@ -130,6 +132,8 @@ func TestMarshalJSON(t *testing.T) { } func TestMarshalJSONTime(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() registerTransports(cdc) @@ -180,6 +184,8 @@ type innerFP struct { // We don't support maps. func TestUnmarshalMap(t *testing.T) { + t.Parallel() + jsonBytes := []byte("dontcare") obj := new(map[string]int) cdc := amino.NewCodec() @@ -198,6 +204,8 @@ func TestUnmarshalMap(t *testing.T) { } func TestUnmarshalFunc(t *testing.T) { + t.Parallel() + jsonBytes := []byte(`"dontcare"`) obj := func() {} cdc := amino.NewCodec() @@ -218,6 +226,8 @@ func TestUnmarshalFunc(t *testing.T) { } func TestUnmarshalJSON(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() registerTransports(cdc) cases := []struct { @@ -310,6 +320,8 @@ func TestUnmarshalJSON(t *testing.T) { } func TestJSONCodecRoundTrip(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() registerTransports(cdc) type allInclusive struct { @@ -480,6 +492,8 @@ func interfacePtr(v interface{}) *interface{} { // Test to ensure that Amino codec's time encoding/decoding roundtrip // produces the same result as the standard library json's. func TestAminoJSONTimeEncodeDecodeRoundTrip(t *testing.T) { + t.Parallel() + loc, err := time.LoadLocation("America/Los_Angeles") require.NoError(t, err) din := time.Date(2008, 9, 15, 14, 13, 12, 11109876, loc).Round(time.Millisecond).UTC() @@ -503,6 +517,8 @@ func TestAminoJSONTimeEncodeDecodeRoundTrip(t *testing.T) { } func TestMarshalJSONIndent(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() registerTransports(cdc) obj := Transport{Vehicle: Car("Tesla")} diff --git a/tm2/pkg/amino/libs/press/press_test.go b/tm2/pkg/amino/libs/press/press_test.go index 3978e5a5f52..e05042f4556 100644 --- a/tm2/pkg/amino/libs/press/press_test.go +++ b/tm2/pkg/amino/libs/press/press_test.go @@ -7,11 +7,15 @@ import ( ) func TestEmpty(t *testing.T) { + t.Parallel() + p := NewPress() assert.Equal(t, p.Print(), "") } func TestBasic(t *testing.T) { + t.Parallel() + p := NewPress() p.P("this ") p.P("is ") @@ -20,6 +24,8 @@ func TestBasic(t *testing.T) { } func TestBasicLn(t *testing.T) { + t.Parallel() + p := NewPress() p.P("this ") p.P("is ") @@ -28,6 +34,8 @@ func TestBasicLn(t *testing.T) { } func TestNewlineStr(t *testing.T) { + t.Parallel() + p := NewPress().SetNewlineStr("\r\n") p.P("this ") p.P("is ") @@ -38,6 +46,8 @@ func TestNewlineStr(t *testing.T) { } func TestIndent(t *testing.T) { + t.Parallel() + p := NewPress() p.P("first line ") p.Pl("{").I(func(p *Press) { @@ -51,6 +61,8 @@ func TestIndent(t *testing.T) { } func TestIndent2(t *testing.T) { + t.Parallel() + p := NewPress() p.P("first line ") p.Pl("{").I(func(p *Press) { @@ -66,6 +78,8 @@ func TestIndent2(t *testing.T) { } func TestIndent3(t *testing.T) { + t.Parallel() + p := NewPress() p.P("first line ") p.Pl("{").I(func(p *Press) { @@ -78,6 +92,8 @@ func TestIndent3(t *testing.T) { } func TestIndentLn(t *testing.T) { + t.Parallel() + p := NewPress() p.P("first line ") p.Pl("{").I(func(p *Press) { @@ -92,6 +108,8 @@ func TestIndentLn(t *testing.T) { } func TestNestedIndent(t *testing.T) { + t.Parallel() + p := NewPress() p.P("first line ") p.Pl("{").I(func(p *Press) { diff --git a/tm2/pkg/amino/pkg/pkg_test.go b/tm2/pkg/amino/pkg/pkg_test.go index 2be0b0cefe3..1be87e88f4e 100644 --- a/tm2/pkg/amino/pkg/pkg_test.go +++ b/tm2/pkg/amino/pkg/pkg_test.go @@ -14,6 +14,8 @@ type Foo struct { } func TestNewPackage(t *testing.T) { + t.Parallel() + // This should panic, as slashes in p3pkg is not allowed. assert.Panics(t, func() { NewPackage("foobar.com/some/path", "some/path", "").WithTypes(Foo{}) @@ -39,6 +41,8 @@ func TestNewPackage(t *testing.T) { } func TestFullNameForType(t *testing.T) { + t.Parallel() + // The Go package depends on how this test is invoked. // Sometimes it is "github.com/gnolang/gno/tm2/pkg/amino/packagepkg_test". // Sometimes it is "command-line-arguments" @@ -55,6 +59,8 @@ func TestFullNameForType(t *testing.T) { // If the struct wasn't registered, you can't get a name or type_url for it. func TestFullNameForUnexpectedType(t *testing.T) { + t.Parallel() + gopkg := reflect.TypeOf(Foo{}).PkgPath() pkg := NewPackage(gopkg, "some.path", "") diff --git a/tm2/pkg/amino/reflect_test.go b/tm2/pkg/amino/reflect_test.go index c5c7b6b5c83..9adfa0b35d0 100644 --- a/tm2/pkg/amino/reflect_test.go +++ b/tm2/pkg/amino/reflect_test.go @@ -18,44 +18,70 @@ import ( "github.com/gnolang/gno/tm2/pkg/amino/tests" ) -//------------------------------------- +// ------------------------------------- // Non-interface Google fuzz tests func TestCodecStruct(t *testing.T) { + t.Parallel() + for _, ptr := range tests.StructTypes { t.Logf("case %v", reflect.TypeOf(ptr)) rt := getTypeFromPointer(ptr) name := rt.Name() - t.Run(name+":binary", func(t *testing.T) { _testCodec(t, rt, "binary") }) - t.Run(name+":json", func(t *testing.T) { _testCodec(t, rt, "json") }) + t.Run(name+":binary", func(t *testing.T) { + t.Parallel() + _testCodec(t, rt, "binary") + }) + t.Run(name+":json", func(t *testing.T) { + t.Parallel() + _testCodec(t, rt, "json") + }) } } func TestCodecDef(t *testing.T) { + t.Parallel() + for _, ptr := range tests.DefTypes { t.Logf("case %v", reflect.TypeOf(ptr)) rt := getTypeFromPointer(ptr) name := rt.Name() - t.Run(name+":binary", func(t *testing.T) { _testCodec(t, rt, "binary") }) - t.Run(name+":json", func(t *testing.T) { _testCodec(t, rt, "json") }) + t.Run(name+":binary", func(t *testing.T) { + t.Parallel() + _testCodec(t, rt, "binary") + }) + t.Run(name+":json", func(t *testing.T) { + t.Parallel() + _testCodec(t, rt, "json") + }) } } func TestDeepCopyStruct(t *testing.T) { + t.Parallel() + for _, ptr := range tests.StructTypes { t.Logf("case %v", reflect.TypeOf(ptr)) rt := getTypeFromPointer(ptr) name := rt.Name() - t.Run(name+":deepcopy", func(t *testing.T) { _testDeepCopy(t, rt) }) + t.Run(name+":deepcopy", func(t *testing.T) { + t.Parallel() + _testDeepCopy(t, rt) + }) } } func TestDeepCopyDef(t *testing.T) { + t.Parallel() + for _, ptr := range tests.DefTypes { t.Logf("case %v", reflect.TypeOf(ptr)) rt := getTypeFromPointer(ptr) name := rt.Name() - t.Run(name+":deepcopy", func(t *testing.T) { _testDeepCopy(t, rt) }) + t.Run(name+":deepcopy", func(t *testing.T) { + t.Parallel() + _testDeepCopy(t, rt) + }) } } @@ -190,10 +216,12 @@ func _testDeepCopy(t *testing.T, rt reflect.Type) { } } -//---------------------------------------- +// ---------------------------------------- // Register/interface tests func TestCodecMashalFailsOnUnregisteredConcrete(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() bz, err := cdc.Marshal(struct{ tests.Interface1 }{tests.Concrete1{}}) @@ -202,6 +230,8 @@ func TestCodecMashalFailsOnUnregisteredConcrete(t *testing.T) { } func TestCodecMarshalPassesOnRegistered(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() cdc.RegisterTypeFrom(reflect.TypeOf(tests.Concrete1{}), tests.Package) @@ -218,6 +248,8 @@ func TestCodecMarshalPassesOnRegistered(t *testing.T) { } func TestCodecRegisterAndMarshalMultipleConcrete(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() cdc.RegisterTypeFrom(reflect.TypeOf(tests.Concrete1{}), tests.Package) cdc.RegisterTypeFrom(reflect.TypeOf(tests.Concrete2{}), tests.Package) @@ -251,6 +283,8 @@ func TestCodecRegisterAndMarshalMultipleConcrete(t *testing.T) { // Serialize and deserialize a registered typedef. func TestCodecRoundtripNonNilRegisteredTypeDef(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() cdc.RegisterTypeFrom(reflect.TypeOf(tests.ConcreteTypeDef{}), tests.Package) @@ -322,6 +356,8 @@ func TestCodecRoundtripNonNilRegisteredTypeDef(t *testing.T) { // Exactly like TestCodecRoundtripNonNilRegisteredTypeDef but with struct // around the value instead of a type def. func TestCodecRoundtripNonNilRegisteredWrappedValue(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() cdc.RegisterTypeFrom(reflect.TypeOf(tests.ConcreteWrappedBytes{}), tests.Package) @@ -351,6 +387,8 @@ func TestCodecRoundtripNonNilRegisteredWrappedValue(t *testing.T) { // MarshalAny(msg) and Marshal(&msg) are the same. func TestCodecMarshalAny(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() cdc.RegisterTypeFrom(reflect.TypeOf(tests.ConcreteWrappedBytes{}), tests.Package) @@ -368,6 +406,8 @@ func TestCodecMarshalAny(t *testing.T) { // Like TestCodecRoundtripNonNilRegisteredTypeDef, but JSON. func TestCodecJSONRoundtripNonNilRegisteredTypeDef(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() cdc.RegisterTypeFrom(reflect.TypeOf(tests.ConcreteTypeDef{}), tests.Package) @@ -388,6 +428,8 @@ func TestCodecJSONRoundtripNonNilRegisteredTypeDef(t *testing.T) { // Like TestCodecRoundtripNonNilRegisteredTypeDef, but serialize the concrete value directly. func TestCodecRoundtripMarshalOnConcreteNonNilRegisteredTypeDef(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() cdc.RegisterTypeFrom(reflect.TypeOf(tests.ConcreteTypeDef{}), tests.Package) @@ -418,6 +460,8 @@ func TestCodecRoundtripMarshalOnConcreteNonNilRegisteredTypeDef(t *testing.T) { // Like TestCodecRoundtripNonNilRegisteredTypeDef but read into concrete var. func TestCodecRoundtripUnmarshalOnConcreteNonNilRegisteredTypeDef(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() cdc.RegisterTypeFrom(reflect.TypeOf(tests.ConcreteTypeDef{}), tests.Package) @@ -437,6 +481,8 @@ func TestCodecRoundtripUnmarshalOnConcreteNonNilRegisteredTypeDef(t *testing.T) } func TestCodecBinaryStructFieldNilInterface(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() cdc.RegisterTypeFrom(reflect.TypeOf(tests.InterfaceFieldsStruct{}), tests.Package) @@ -451,7 +497,7 @@ func TestCodecBinaryStructFieldNilInterface(t *testing.T) { require.Equal(t, i2, i1, "i1 and i2 should be the same after decoding") } -//---------------------------------------- +// ---------------------------------------- // Misc. func spw(o interface{}) string { @@ -613,7 +659,7 @@ func getTypeFromPointer(ptr interface{}) reflect.Type { return rt.Elem() } -//---------------------------------------- +// ---------------------------------------- // From https://github.com/google/gofuzz/blob/master/fuzz.go // (Apache2.0 License) diff --git a/tm2/pkg/amino/repr_test.go b/tm2/pkg/amino/repr_test.go index 5fb31515fb6..4be50b5d93d 100644 --- a/tm2/pkg/amino/repr_test.go +++ b/tm2/pkg/amino/repr_test.go @@ -55,6 +55,8 @@ var ( ) func TestMarshalAminoBinary(t *testing.T) { + t.Parallel() + cdc := NewCodec() cdc.RegisterPackage(testPackage) @@ -78,6 +80,8 @@ func TestMarshalAminoBinary(t *testing.T) { } func TestMarshalAminoJSON(t *testing.T) { + t.Parallel() + cdc := NewCodec() cdc.RegisterPackage(testPackage) diff --git a/tm2/pkg/amino/tests/proto3/proto3_compat_test.go b/tm2/pkg/amino/tests/proto3/proto3_compat_test.go index bd2a51825da..8f9e04fc35c 100644 --- a/tm2/pkg/amino/tests/proto3/proto3_compat_test.go +++ b/tm2/pkg/amino/tests/proto3/proto3_compat_test.go @@ -36,6 +36,8 @@ func init() { } func TestFixed32Roundtrip(t *testing.T) { + t.Parallel() + // amino fixed32 (int32) <-> protbuf fixed32 (uint32) type testi32 struct { Int32 int32 `binary:"fixed32"` @@ -61,6 +63,8 @@ func TestFixed32Roundtrip(t *testing.T) { } func TestVarintZigzagRoundtrip(t *testing.T) { + t.Parallel() + t.Skip("zigzag encoding isn't default anymore for (unsigned) ints") // amino varint (int) <-> protobuf zigzag32 (int32 in go sint32 in proto file) type testInt32Varint struct { @@ -85,6 +89,8 @@ func TestVarintZigzagRoundtrip(t *testing.T) { } func TestFixedU64Roundtrip(t *testing.T) { + t.Parallel() + type testFixed64Uint struct { Int64 uint64 `binary:"fixed64"` } @@ -111,6 +117,8 @@ func TestFixedU64Roundtrip(t *testing.T) { } func TestMultidimensionalSlices(t *testing.T) { + t.Parallel() + s := [][]int8{ {1, 2}, {3, 4, 5}, @@ -121,6 +129,8 @@ func TestMultidimensionalSlices(t *testing.T) { } func TestMultidimensionalArrays(t *testing.T) { + t.Parallel() + arr := [2][2]int8{ {1, 2}, {3, 4}, @@ -131,6 +141,8 @@ func TestMultidimensionalArrays(t *testing.T) { } func TestMultidimensionalByteArraysAndSlices(t *testing.T) { + t.Parallel() + arr := [2][2]byte{ {1, 2}, {3, 4}, @@ -157,6 +169,8 @@ func TestMultidimensionalByteArraysAndSlices(t *testing.T) { } func TestProto3CompatPtrsRoundtrip(t *testing.T) { + t.Parallel() + s := p3.SomeStruct{} ab, err := cdc.Marshal(s) @@ -214,6 +228,8 @@ type goAminoGotTime struct { } func TestProto3CompatEmptyTimestamp(t *testing.T) { + t.Parallel() + empty := p3.ProtoGotTime{} // protobuf also marshals to empty bytes here: pb, err := proto.Marshal(&empty) @@ -235,6 +251,8 @@ func TestProto3CompatEmptyTimestamp(t *testing.T) { } func TestProto3CompatTimestampNow(t *testing.T) { + t.Parallel() + // test with current time: now := time.Now() ptts, err := ptypes.TimestampProto(now) @@ -267,6 +285,8 @@ func TestProto3CompatTimestampNow(t *testing.T) { } func TestProto3EpochTime(t *testing.T) { + t.Parallel() + pbRes := p3.ProtoGotTime{} // amino encode epoch (1970) and decode using proto; expect the resulting time to be epoch again: ab, err := cdc.Marshal(goAminoGotTime{T: &epoch}) @@ -279,6 +299,8 @@ func TestProto3EpochTime(t *testing.T) { } func TestProtoNegativeSeconds(t *testing.T) { + t.Parallel() + pbRes := p3.ProtoGotTime{} // test with negative seconds (0001-01-01 -> seconds = -62135596800, nanos = 0): ntm, err := time.Parse("2006-01-02 15:04:05 +0000 UTC", "0001-01-01 00:00:00 +0000 UTC") @@ -296,6 +318,8 @@ func TestProtoNegativeSeconds(t *testing.T) { } func TestIntVarintCompat(t *testing.T) { + t.Parallel() + tcs := []struct { val32 int32 val64 int64 @@ -382,6 +406,8 @@ func TestIntVarintCompat(t *testing.T) { // See if encoding of type def types matches the proto3 encoding func TestTypeDefCompatibility(t *testing.T) { + t.Parallel() + pNow := ptypes.TimestampNow() now, err := ptypes.Timestamp(pNow) require.NoError(t, err) diff --git a/tm2/pkg/amino/time2_test.go b/tm2/pkg/amino/time2_test.go index c40e2fc660e..b8d73f37d55 100644 --- a/tm2/pkg/amino/time2_test.go +++ b/tm2/pkg/amino/time2_test.go @@ -18,6 +18,8 @@ type testTime struct { } func TestDecodeSkippedFieldsInTime(t *testing.T) { + t.Parallel() + tm, err := time.Parse("2006-01-02 15:04:05 +0000 UTC", "1970-01-01 00:00:00 +0000 UTC") assert.NoError(t, err) @@ -62,6 +64,8 @@ func TestDecodeSkippedFieldsInTime(t *testing.T) { } func TestMinMaxTimeEncode(t *testing.T) { + t.Parallel() + tMin, err := time.Parse("2006-01-02 15:04:05 +0000 UTC", "0001-01-01 00:00:00 +0000 UTC") assert.NoError(t, err) tm := testTime{tMin} diff --git a/tm2/pkg/amino/wellknown_test.go b/tm2/pkg/amino/wellknown_test.go index 3b91ffc77a5..345466bd285 100644 --- a/tm2/pkg/amino/wellknown_test.go +++ b/tm2/pkg/amino/wellknown_test.go @@ -9,6 +9,8 @@ import ( ) func TestAnyWellKnownNative(t *testing.T) { + t.Parallel() + cdc := amino.NewCodec() s1 := tests.InterfaceFieldsStruct{ diff --git a/tm2/pkg/async/async_test.go b/tm2/pkg/async/async_test.go index f82e32312f0..255ce6b8d51 100644 --- a/tm2/pkg/async/async_test.go +++ b/tm2/pkg/async/async_test.go @@ -12,6 +12,8 @@ import ( ) func TestParallel(t *testing.T) { + t.Parallel() + // Create tasks. counter := new(int32) tasks := make([]Task, 100*1000) @@ -52,6 +54,8 @@ func TestParallel(t *testing.T) { } func TestParallelAbort(t *testing.T) { + t.Parallel() + flow1 := make(chan struct{}, 1) flow2 := make(chan struct{}, 1) flow3 := make(chan struct{}, 1) // Cap must be > 0 to prevent blocking. @@ -103,6 +107,8 @@ func TestParallelAbort(t *testing.T) { } func TestParallelRecover(t *testing.T) { + t.Parallel() + // Create tasks. tasks := []Task{ func(i int) (res interface{}, err error, abort bool) { @@ -155,7 +161,7 @@ func waitTimeout(t *testing.T, taskResultCh TaskResultCh, taskName string) { } else { assert.Fail(t, "TaskResultCh unexpectedly returned for %v", taskName) } - case <-time.After(1 * time.Second): // TODO use deterministic time? + case <-time.After(200 * time.Millisecond): // TODO use deterministic time? // Good! } } diff --git a/tm2/pkg/autofile/group_test.go b/tm2/pkg/autofile/group_test.go index 6face4630d1..1bf79894b93 100644 --- a/tm2/pkg/autofile/group_test.go +++ b/tm2/pkg/autofile/group_test.go @@ -47,6 +47,8 @@ func assertGroupInfo(t *testing.T, gInfo GroupInfo, minIndex, maxIndex int, tota } func TestCheckHeadSizeLimit(t *testing.T) { + t.Parallel() + g := createTestGroupWithHeadSizeLimit(t, 1000*1000) // At first, there are no files. @@ -93,6 +95,8 @@ func TestCheckHeadSizeLimit(t *testing.T) { } func TestRotateFile(t *testing.T) { + t.Parallel() + g := createTestGroupWithHeadSizeLimit(t, 0) g.WriteLine("Line 1") g.WriteLine("Line 2") @@ -123,6 +127,8 @@ func TestRotateFile(t *testing.T) { } func TestWrite(t *testing.T) { + t.Parallel() + g := createTestGroupWithHeadSizeLimit(t, 0) written := []byte("Medusa") @@ -144,6 +150,8 @@ func TestWrite(t *testing.T) { // test that Read reads the required amount of bytes from all the files in the // group and returns no error if n == size of the given slice. func TestGroupReaderRead(t *testing.T) { + t.Parallel() + g := createTestGroupWithHeadSizeLimit(t, 0) professor := []byte("Professor Monster") @@ -173,6 +181,8 @@ func TestGroupReaderRead(t *testing.T) { // test that Read returns an error if number of bytes read < size of // the given slice. Subsequent call should return 0, io.EOF. func TestGroupReaderRead2(t *testing.T) { + t.Parallel() + g := createTestGroupWithHeadSizeLimit(t, 0) professor := []byte("Professor Monster") @@ -204,6 +214,8 @@ func TestGroupReaderRead2(t *testing.T) { } func TestMinIndex(t *testing.T) { + t.Parallel() + g := createTestGroupWithHeadSizeLimit(t, 0) assert.Zero(t, g.MinIndex(), "MinIndex should be zero at the beginning") @@ -213,6 +225,8 @@ func TestMinIndex(t *testing.T) { } func TestMaxIndex(t *testing.T) { + t.Parallel() + g := createTestGroupWithHeadSizeLimit(t, 0) assert.Zero(t, g.MaxIndex(), "MaxIndex should be zero at the beginning") diff --git a/tm2/pkg/bech32/bech32_test.go b/tm2/pkg/bech32/bech32_test.go index 557507cef57..361a18116ab 100644 --- a/tm2/pkg/bech32/bech32_test.go +++ b/tm2/pkg/bech32/bech32_test.go @@ -12,6 +12,8 @@ import ( ) func TestEncodeAndDecode(t *testing.T) { + t.Parallel() + sum := sha256.Sum256([]byte("hello world\n")) bech, err := bech32.ConvertAndEncode("shasum", sum[:]) @@ -39,6 +41,8 @@ var ( ) func TestEncode(t *testing.T) { + t.Parallel() + bz, err := hex.DecodeString(pubkeyBytes) assert.NoError(t, err) @@ -49,6 +53,8 @@ func TestEncode(t *testing.T) { } func TestDecode(t *testing.T) { + t.Parallel() + hrp, b1, err := bech32.Decode(pubkeyBech32) assert.NoError(t, err) diff --git a/tm2/pkg/bft/blockchain/pool_test.go b/tm2/pkg/bft/blockchain/pool_test.go index 79205bff5ce..39c17d8428f 100644 --- a/tm2/pkg/bft/blockchain/pool_test.go +++ b/tm2/pkg/bft/blockchain/pool_test.go @@ -72,6 +72,8 @@ func makePeers(numPeers int, minHeight, maxHeight int64) testPeers { } func TestBlockPoolBasic(t *testing.T) { + t.Parallel() + start := int64(42) peers := makePeers(10, start+1, 1000) errorsCh := make(chan peerError, 1000) @@ -128,6 +130,8 @@ func TestBlockPoolBasic(t *testing.T) { } func TestBlockPoolTimeout(t *testing.T) { + t.Parallel() + start := int64(42) peers := makePeers(10, start+1, 1000) errorsCh := make(chan peerError, 1000) @@ -187,6 +191,8 @@ func TestBlockPoolTimeout(t *testing.T) { } func TestBlockPoolRemovePeer(t *testing.T) { + t.Parallel() + peers := make(testPeers, 10) for i := 0; i < 10; i++ { peerID := p2p.ID(fmt.Sprintf("%d", i+1)) diff --git a/tm2/pkg/bft/blockchain/reactor_test.go b/tm2/pkg/bft/blockchain/reactor_test.go index f4265e0f78d..fef640b0f82 100644 --- a/tm2/pkg/bft/blockchain/reactor_test.go +++ b/tm2/pkg/bft/blockchain/reactor_test.go @@ -115,6 +115,8 @@ func newBlockchainReactor(logger log.Logger, genDoc *types.GenesisDoc, privVals } func TestNoBlockResponse(t *testing.T) { + t.Parallel() + config = cfg.ResetTestRoot("blockchain_reactor_test") defer os.RemoveAll(config.RootDir) genDoc, privVals := randGenesisDoc(1, false, 30) @@ -174,6 +176,8 @@ func TestNoBlockResponse(t *testing.T) { // Alternatively we could actually dial a TCP conn but // that seems extreme. func TestFlappyBadBlockStopsPeer(t *testing.T) { + t.Parallel() + testutils.FilterStability(t, testutils.Flappy) config = cfg.ResetTestRoot("blockchain_reactor_test") @@ -245,6 +249,8 @@ func TestFlappyBadBlockStopsPeer(t *testing.T) { } func TestBcBlockRequestMessageValidateBasic(t *testing.T) { + t.Parallel() + testCases := []struct { testName string requestHeight int64 @@ -258,6 +264,8 @@ func TestBcBlockRequestMessageValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + request := bcBlockRequestMessage{Height: tc.requestHeight} assert.Equal(t, tc.expectErr, request.ValidateBasic() != nil, "Validate Basic had an unexpected result") }) @@ -265,6 +273,8 @@ func TestBcBlockRequestMessageValidateBasic(t *testing.T) { } func TestBcNoBlockResponseMessageValidateBasic(t *testing.T) { + t.Parallel() + testCases := []struct { testName string nonResponseHeight int64 @@ -278,6 +288,8 @@ func TestBcNoBlockResponseMessageValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + nonResponse := bcNoBlockResponseMessage{Height: tc.nonResponseHeight} assert.Equal(t, tc.expectErr, nonResponse.ValidateBasic() != nil, "Validate Basic had an unexpected result") }) @@ -285,6 +297,8 @@ func TestBcNoBlockResponseMessageValidateBasic(t *testing.T) { } func TestBcStatusRequestMessageValidateBasic(t *testing.T) { + t.Parallel() + testCases := []struct { testName string requestHeight int64 @@ -298,6 +312,8 @@ func TestBcStatusRequestMessageValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + request := bcStatusRequestMessage{Height: tc.requestHeight} assert.Equal(t, tc.expectErr, request.ValidateBasic() != nil, "Validate Basic had an unexpected result") }) @@ -305,6 +321,8 @@ func TestBcStatusRequestMessageValidateBasic(t *testing.T) { } func TestBcStatusResponseMessageValidateBasic(t *testing.T) { + t.Parallel() + testCases := []struct { testName string responseHeight int64 @@ -318,13 +336,15 @@ func TestBcStatusResponseMessageValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + response := bcStatusResponseMessage{Height: tc.responseHeight} assert.Equal(t, tc.expectErr, response.ValidateBasic() != nil, "Validate Basic had an unexpected result") }) } } -//---------------------------------------------- +// ---------------------------------------------- // utility funcs func makeTxs(height int64) (txs []types.Tx) { diff --git a/tm2/pkg/bft/config/toml_test.go b/tm2/pkg/bft/config/toml_test.go index da6a720ecd4..d1d70155cb8 100644 --- a/tm2/pkg/bft/config/toml_test.go +++ b/tm2/pkg/bft/config/toml_test.go @@ -22,6 +22,8 @@ func ensureFiles(t *testing.T, rootDir string, files ...string) { } func TestEnsureRoot(t *testing.T) { + t.Parallel() + require := require.New(t) // setup temp dir for test @@ -46,6 +48,8 @@ func TestEnsureRoot(t *testing.T) { } func TestEnsureTestRoot(t *testing.T) { + t.Parallel() + require := require.New(t) testName := "ensureTestRoot" diff --git a/tm2/pkg/bft/consensus/mempool_test.go b/tm2/pkg/bft/consensus/mempool_test.go index b9c04cabbed..85914262903 100644 --- a/tm2/pkg/bft/consensus/mempool_test.go +++ b/tm2/pkg/bft/consensus/mempool_test.go @@ -24,6 +24,8 @@ func assertMempool(txn txNotifier) mempl.Mempool { } func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) { + t.Parallel() + config := ResetConfig("consensus_mempool_no_progress_until_txs_available") defer os.RemoveAll(config.RootDir) config.Consensus.CreateEmptyBlocks = false @@ -71,6 +73,8 @@ func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) { } func TestMempoolProgressInHigherRound(t *testing.T) { + t.Parallel() + config := ResetConfig("consensus_mempool_progress_in_higher_round") defer os.RemoveAll(config.RootDir) config.Consensus.CreateEmptyBlocks = false @@ -138,6 +142,8 @@ func deliverTxsRange(cs *ConsensusState, start, end int) { } func TestMempoolTxConcurrentWithCommit(t *testing.T) { + t.Parallel() + state, privVals := randGenesisState(1, false, 10) blockDB := dbm.NewMemDB() app := NewCounterApplication() @@ -169,6 +175,8 @@ func TestMempoolTxConcurrentWithCommit(t *testing.T) { } func TestMempoolRmBadTx(t *testing.T) { + t.Parallel() + state, privVals := randGenesisState(1, false, 10) app := NewCounterApplication() blockDB := dbm.NewMemDB() diff --git a/tm2/pkg/bft/consensus/reactor_test.go b/tm2/pkg/bft/consensus/reactor_test.go index 2194d4d007d..db084b61395 100644 --- a/tm2/pkg/bft/consensus/reactor_test.go +++ b/tm2/pkg/bft/consensus/reactor_test.go @@ -86,6 +86,8 @@ func stopConsensusNet(logger log.Logger, reactors []*ConsensusReactor, eventSwit // Ensure a testnet makes blocks func TestReactorBasic(t *testing.T) { + t.Parallel() + N := 4 css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter) defer cleanup() @@ -101,6 +103,8 @@ func TestReactorBasic(t *testing.T) { // Ensure a testnet makes blocks when there are txs func TestReactorCreatesBlockWhenEmptyBlocksFalse(t *testing.T) { + t.Parallel() + N := 4 css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter, func(c *cfg.Config) { @@ -122,6 +126,8 @@ func TestReactorCreatesBlockWhenEmptyBlocksFalse(t *testing.T) { } func TestReactorReceiveDoesNotPanicIfAddPeerHasntBeenCalledYet(t *testing.T) { + t.Parallel() + N := 1 css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter) defer cleanup() @@ -144,6 +150,8 @@ func TestReactorReceiveDoesNotPanicIfAddPeerHasntBeenCalledYet(t *testing.T) { } func TestReactorReceivePanicsIfInitPeerHasntBeenCalledYet(t *testing.T) { + t.Parallel() + N := 1 css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter) defer cleanup() @@ -166,6 +174,8 @@ func TestReactorReceivePanicsIfInitPeerHasntBeenCalledYet(t *testing.T) { // Test we record stats about votes and block parts from other peers. func TestFlappyReactorRecordsVotesAndBlockParts(t *testing.T) { + t.Parallel() + testutils.FilterStability(t, testutils.Flappy) N := 4 @@ -192,6 +202,8 @@ func TestFlappyReactorRecordsVotesAndBlockParts(t *testing.T) { // ensure we can make blocks despite cycling a validator set func TestReactorVotingPowerChange(t *testing.T) { + t.Parallel() + nVals := 4 logger := log.TestingLogger() css, cleanup := randConsensusNet(nVals, "consensus_voting_power_changes_test", newMockTickerFunc(true), newPersistentKVStore) @@ -254,6 +266,8 @@ func TestReactorVotingPowerChange(t *testing.T) { } func TestReactorValidatorSetChanges(t *testing.T) { + t.Parallel() + nPeers := 7 nVals := 4 css, _, _, cleanup := randConsensusNetWithPeers(nVals, nPeers, "consensus_val_set_changes_test", newMockTickerFunc(true), newPersistentKVStoreWithPath) @@ -350,6 +364,8 @@ func TestReactorValidatorSetChanges(t *testing.T) { // Check we can make blocks with skip_timeout_commit=false func TestReactorWithTimeoutCommit(t *testing.T) { + t.Parallel() + N := 4 css, cleanup := randConsensusNet(N, "consensus_reactor_with_timeout_commit_test", newMockTickerFunc(false), newCounter) defer cleanup() @@ -510,6 +526,8 @@ func timeoutWaitGroup(t *testing.T, n int, f func(int), css []*ConsensusState) { // Ensure basic validation of structs is functioning func TestNewRoundStepMessageValidateBasic(t *testing.T) { + t.Parallel() + testCases := []struct { testName string messageHeight int64 @@ -529,6 +547,8 @@ func TestNewRoundStepMessageValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + message := NewRoundStepMessage{ Height: tc.messageHeight, Round: tc.messageRound, @@ -542,6 +562,8 @@ func TestNewRoundStepMessageValidateBasic(t *testing.T) { } func TestNewValidBlockMessageValidateBasic(t *testing.T) { + t.Parallel() + testCases := []struct { malleateFn func(*NewValidBlockMessage) expErr string @@ -569,6 +591,8 @@ func TestNewValidBlockMessageValidateBasic(t *testing.T) { for i, tc := range testCases { tc := tc t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { + t.Parallel() + msg := &NewValidBlockMessage{ Height: 1, Round: 0, @@ -588,6 +612,8 @@ func TestNewValidBlockMessageValidateBasic(t *testing.T) { } func TestProposalPOLMessageValidateBasic(t *testing.T) { + t.Parallel() + testCases := []struct { malleateFn func(*ProposalPOLMessage) expErr string @@ -605,6 +631,8 @@ func TestProposalPOLMessageValidateBasic(t *testing.T) { for i, tc := range testCases { tc := tc t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { + t.Parallel() + msg := &ProposalPOLMessage{ Height: 1, ProposalPOLRound: 1, @@ -621,6 +649,8 @@ func TestProposalPOLMessageValidateBasic(t *testing.T) { } func TestBlockPartMessageValidateBasic(t *testing.T) { + t.Parallel() + testPart := new(types.Part) testPart.Proof.LeafHash = tmhash.Sum([]byte("leaf")) testCases := []struct { @@ -638,6 +668,8 @@ func TestBlockPartMessageValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + message := BlockPartMessage{ Height: tc.messageHeight, Round: tc.messageRound, @@ -655,6 +687,8 @@ func TestBlockPartMessageValidateBasic(t *testing.T) { } func TestHasVoteMessageValidateBasic(t *testing.T) { + t.Parallel() + const ( validSignedMsgType types.SignedMsgType = 0x01 invalidSignedMsgType types.SignedMsgType = 0x03 @@ -678,6 +712,8 @@ func TestHasVoteMessageValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + message := HasVoteMessage{ Height: tc.messageHeight, Round: tc.messageRound, @@ -691,6 +727,8 @@ func TestHasVoteMessageValidateBasic(t *testing.T) { } func TestVoteSetMaj23MessageValidateBasic(t *testing.T) { + t.Parallel() + const ( validSignedMsgType types.SignedMsgType = 0x01 invalidSignedMsgType types.SignedMsgType = 0x03 @@ -723,6 +761,8 @@ func TestVoteSetMaj23MessageValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + message := VoteSetMaj23Message{ Height: tc.messageHeight, Round: tc.messageRound, @@ -736,6 +776,8 @@ func TestVoteSetMaj23MessageValidateBasic(t *testing.T) { } func TestVoteSetBitsMessageValidateBasic(t *testing.T) { + t.Parallel() + testCases := []struct { //nolint: maligned malleateFn func(*VoteSetBitsMessage) expErr string @@ -762,6 +804,8 @@ func TestVoteSetBitsMessageValidateBasic(t *testing.T) { for i, tc := range testCases { tc := tc t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { + t.Parallel() + msg := &VoteSetBitsMessage{ Height: 1, Round: 0, diff --git a/tm2/pkg/bft/consensus/replay_test.go b/tm2/pkg/bft/consensus/replay_test.go index 556689ec3f4..d43a06f40c2 100644 --- a/tm2/pkg/bft/consensus/replay_test.go +++ b/tm2/pkg/bft/consensus/replay_test.go @@ -123,6 +123,8 @@ func sendTxs(ctx context.Context, cs *ConsensusState) { // TestWALCrash uses crashing WAL to test we can recover from any WAL failure. func TestWALCrash(t *testing.T) { + t.Parallel() + testCases := []struct { name string initFn func(dbm.DB, *ConsensusState, context.Context) @@ -146,6 +148,8 @@ func TestWALCrash(t *testing.T) { tc := tc consensusReplayConfig := ResetConfig(fmt.Sprintf("%s_%d", t.Name(), i)) t.Run(tc.name, func(t *testing.T) { + t.Parallel() + crashWALandCheckLiveness(t, consensusReplayConfig, tc.initFn, tc.lastBlockHeight) }) } @@ -506,6 +510,8 @@ func makeTestSim(t *testing.T, name string) (sim testSim) { // Sync from scratch func TestHandshakeReplayAll(t *testing.T) { + t.Parallel() + for _, m := range modes { testHandshakeReplay(t, config, 0, m, nil) } @@ -518,6 +524,8 @@ func TestHandshakeReplayAll(t *testing.T) { // Sync many, not from scratch func TestHandshakeReplaySome(t *testing.T) { + t.Parallel() + for _, m := range modes { testHandshakeReplay(t, config, 1, m, nil) } @@ -530,6 +538,8 @@ func TestHandshakeReplaySome(t *testing.T) { // Sync from lagging by one func TestHandshakeReplayOne(t *testing.T) { + t.Parallel() + for _, m := range modes { testHandshakeReplay(t, config, numBlocks-1, m, nil) } @@ -542,6 +552,8 @@ func TestHandshakeReplayOne(t *testing.T) { // Sync from caught up func TestFlappyHandshakeReplayNone(t *testing.T) { + t.Parallel() + testutils.FilterStability(t, testutils.Flappy) for _, m := range modes { @@ -556,6 +568,8 @@ func TestFlappyHandshakeReplayNone(t *testing.T) { // Test mockProxyApp should not panic when app return ABCIResponses with some empty ResponseDeliverTx func TestMockProxyApp(t *testing.T) { + t.Parallel() + logger := log.TestingLogger() validTxs, invalidTxs := 0, 0 txIndex := 0 @@ -810,6 +824,8 @@ func buildTMStateFromChain(config *cfg.Config, stateDB dbm.DB, state sm.State, c } func TestHandshakePanicsIfAppReturnsWrongAppHash(t *testing.T) { + t.Parallel() + // 1. Initialize tendermint and commit 3 blocks with the following app hashes: // - 0x01 // - 0x02 @@ -1089,6 +1105,8 @@ func (bs *mockBlockStore) LoadSeenCommit(height int64) *types.Commit { // Test handshake/init chain func TestHandshakeUpdatesValidators(t *testing.T) { + t.Parallel() + val, _ := types.RandValidator(true, 10) vals := types.NewValidatorSet([]*types.Validator{val}) app := &initChainApp{vals: vals.ABCIValidatorUpdates()} diff --git a/tm2/pkg/bft/consensus/state_test.go b/tm2/pkg/bft/consensus/state_test.go index 0e2e6b629a4..35877837ab3 100644 --- a/tm2/pkg/bft/consensus/state_test.go +++ b/tm2/pkg/bft/consensus/state_test.go @@ -63,6 +63,8 @@ x * TestHalt1 - if we see +2/3 precommits after timing out into new round, we sh // ProposeSuite func TestStateProposerSelection0(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) height, round := cs1.Height, cs1.Round @@ -103,6 +105,8 @@ func TestStateProposerSelection0(t *testing.T) { // Now let's do it all again, but starting from round 2 instead of 0 func TestStateProposerSelection2(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) // test needs more work for more than 3 validators height := cs1.Height newRoundCh := subscribe(cs1.evsw, cstypes.EventNewRound{}) @@ -138,6 +142,8 @@ func TestStateProposerSelection2(t *testing.T) { // a non-validator should timeout into the prevote round func TestStateEnterProposeNoPrivValidator(t *testing.T) { + t.Parallel() + cs, _ := randConsensusState(1) cs.SetPrivValidator(nil) height, round := cs.Height, cs.Round @@ -161,6 +167,8 @@ func TestStateEnterProposeNoPrivValidator(t *testing.T) { // a validator should not timeout of the prevote round (TODO: unless the block is really big!) func TestStateEnterProposeYesPrivValidator(t *testing.T) { + t.Parallel() + cs, _ := randConsensusState(1) height, round := cs.Height, cs.Round @@ -197,6 +205,8 @@ func TestStateEnterProposeYesPrivValidator(t *testing.T) { } func TestStateBadProposal(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(2) height, round := cs1.Height, cs1.Round vs2 := vss[1] @@ -260,6 +270,8 @@ func TestStateBadProposal(t *testing.T) { // propose, prevote, and precommit a block func TestStateFullRound1(t *testing.T) { + t.Parallel() + cs, vss := randConsensusState(1) height, round := cs.Height, cs.Round @@ -292,6 +304,8 @@ func TestStateFullRound1(t *testing.T) { // nil is proposed, so prevote and precommit nil func TestStateFullRoundNil(t *testing.T) { + t.Parallel() + cs, vss := randConsensusState(1) height, round := cs.Height, cs.Round cs.decideProposal = func(height int64, round int) { @@ -316,6 +330,8 @@ func TestStateFullRoundNil(t *testing.T) { // run through propose, prevote, precommit commit with two validators // where the first validator has to wait for votes from the second func TestStateFullRound2(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(2) vs2 := vss[1] height, round := cs1.Height, cs1.Round @@ -360,6 +376,8 @@ func TestStateFullRound2(t *testing.T) { // two validators, 4 rounds. // two vals take turns proposing. val1 locks on first one, precommits nil on everything else func TestStateLockNoPOL(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(2) vs2 := vss[1] height, round := cs1.Height, cs1.Round @@ -532,6 +550,8 @@ func TestStateLockNoPOL(t *testing.T) { // 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka func TestStateLockPOLRelock(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -627,6 +647,8 @@ func TestStateLockPOLRelock(t *testing.T) { // 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka func TestStateLockPOLUnlock(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -727,6 +749,8 @@ func TestStateLockPOLUnlock(t *testing.T) { // then a polka at round 2 that we lock on // then we see the polka from round 1 but shouldn't unlock func TestStateLockPOLSafety1(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -848,6 +872,8 @@ func TestStateLockPOLSafety1(t *testing.T) { // What we want: // dont see P0, lock on P1 at R1, dont unlock using P0 at R2 func TestStateLockPOLSafety2(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -943,6 +969,8 @@ func TestStateLockPOLSafety2(t *testing.T) { // What we want: // P0 proposes B0 at R3. func TestProposeValidBlock(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1038,6 +1066,8 @@ func TestProposeValidBlock(t *testing.T) { // What we want: // P0 miss to lock B but set valid block to B after receiving delayed prevote. func TestSetValidBlockOnDelayedPrevote(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1102,6 +1132,8 @@ func TestSetValidBlockOnDelayedPrevote(t *testing.T) { // P0 miss to lock B as Proposal Block is missing, but set valid block to B after // receiving delayed Block Proposal. func TestSetValidBlockOnDelayedProposal(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1160,6 +1192,8 @@ func TestSetValidBlockOnDelayedProposal(t *testing.T) { // What we want: // P0 waits for timeoutPrecommit before starting next round func TestWaitingTimeoutOnNilPolka(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1185,6 +1219,8 @@ func TestWaitingTimeoutOnNilPolka(t *testing.T) { // What we want: // P0 waits for timeoutPropose in the next round before entering prevote func TestWaitingTimeoutProposeOnNewRound(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1223,6 +1259,8 @@ func TestWaitingTimeoutProposeOnNewRound(t *testing.T) { // What we want: // P0 jump to higher round, precommit and start precommit wait func TestRoundSkipOnNilPolkaFromHigherRound(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1261,6 +1299,8 @@ func TestRoundSkipOnNilPolkaFromHigherRound(t *testing.T) { // What we want: // P0 wait for timeoutPropose to expire before sending prevote. func TestWaitTimeoutProposeOnNilPolkaForTheCurrentRound(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, 1 @@ -1290,6 +1330,8 @@ func TestWaitTimeoutProposeOnNilPolkaForTheCurrentRound(t *testing.T) { // What we want: // P0 emit NewValidBlock event upon receiving 2/3+ Precommit for B but hasn't received block B yet func TestEmitNewValidBlockEventOnCommitWithoutBlock(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, 1 @@ -1327,6 +1369,8 @@ func TestEmitNewValidBlockEventOnCommitWithoutBlock(t *testing.T) { // P0 receives 2/3+ Precommit for B for round 0, while being in round 1. It emits NewValidBlock event. // After receiving block, it executes block and moves to the next height. func TestCommitFromPreviousRound(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, 1 @@ -1439,6 +1483,8 @@ func TestStartNextHeightCorrectly(t *testing.T) { } func TestFlappyResetTimeoutPrecommitUponNewHeight(t *testing.T) { + t.Parallel() + testutils.FilterStability(t, testutils.Flappy) config.Consensus.SkipTimeoutCommit = false @@ -1502,6 +1548,8 @@ func TestFlappyResetTimeoutPrecommitUponNewHeight(t *testing.T) { /* func TestStateSlashingPrevotes(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(2) vs2 := vss[1] @@ -1537,6 +1585,8 @@ func TestStateSlashingPrevotes(t *testing.T) { } func TestStateSlashingPrecommits(t *testing.T) { + t.Parallel() + cs1, vss := randConsensusState(2) vs2 := vss[1] @@ -1582,6 +1632,8 @@ func TestStateSlashingPrecommits(t *testing.T) { // 4 vals. // we receive a final precommit after going into next round, but others might have gone to commit already! func TestFlappyStateHalt1(t *testing.T) { + t.Parallel() + testutils.FilterStability(t, testutils.Flappy) cs1, vss := randConsensusState(4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] @@ -1652,6 +1704,8 @@ func TestFlappyStateHalt1(t *testing.T) { } func TestStateOutputsBlockPartsStats(t *testing.T) { + t.Parallel() + // create dummy peer cs, _ := randConsensusState(1) peer := p2pmock.NewPeer(nil) @@ -1694,6 +1748,8 @@ func TestStateOutputsBlockPartsStats(t *testing.T) { } func TestStateOutputVoteStats(t *testing.T) { + t.Parallel() + cs, vss := randConsensusState(2) // create dummy peer peer := p2pmock.NewPeer(nil) diff --git a/tm2/pkg/bft/consensus/types/height_vote_set_test.go b/tm2/pkg/bft/consensus/types/height_vote_set_test.go index 86dc4ee84f6..4c315585daa 100644 --- a/tm2/pkg/bft/consensus/types/height_vote_set_test.go +++ b/tm2/pkg/bft/consensus/types/height_vote_set_test.go @@ -21,6 +21,8 @@ func TestMain(m *testing.M) { } func TestPeerCatchupRounds(t *testing.T) { + t.Parallel() + valSet, privVals := types.RandValidatorSet(10, 1) hvs := NewHeightVoteSet(config.ChainID(), 1, valSet) diff --git a/tm2/pkg/bft/consensus/wal_test.go b/tm2/pkg/bft/consensus/wal_test.go index 50f8f4c8b2a..55c9be03508 100644 --- a/tm2/pkg/bft/consensus/wal_test.go +++ b/tm2/pkg/bft/consensus/wal_test.go @@ -49,6 +49,8 @@ func makeTempWAL(t *testing.T, walChunkSize int64) (wal walm.WAL) { // ---------------------------------------- func TestWALTruncate(t *testing.T) { + t.Parallel() + const walChunkSize = 409610 // 4KB wal := makeTempWAL(t, walChunkSize) diff --git a/tm2/pkg/bft/mempool/cache_test.go b/tm2/pkg/bft/mempool/cache_test.go index 5f76d6875ea..2d523db37ae 100644 --- a/tm2/pkg/bft/mempool/cache_test.go +++ b/tm2/pkg/bft/mempool/cache_test.go @@ -13,6 +13,8 @@ import ( ) func TestCacheRemove(t *testing.T) { + t.Parallel() + cache := newMapTxCache(100) numTxs := 10 txs := make([][]byte, numTxs) @@ -35,6 +37,8 @@ func TestCacheRemove(t *testing.T) { } func TestCacheAfterUpdate(t *testing.T) { + t.Parallel() + app := kvstore.NewKVStoreApplication() cc := proxy.NewLocalClientCreator(app) mempool, cleanup := newMempoolWithApp(cc) diff --git a/tm2/pkg/bft/mempool/reactor_test.go b/tm2/pkg/bft/mempool/reactor_test.go index c3b77fb46df..154cb1a7132 100644 --- a/tm2/pkg/bft/mempool/reactor_test.go +++ b/tm2/pkg/bft/mempool/reactor_test.go @@ -140,6 +140,8 @@ const ( ) func TestReactorBroadcastTxMessage(t *testing.T) { + t.Parallel() + mconfig := memcfg.TestMempoolConfig() pconfig := p2pcfg.TestP2PConfig() const N = 4 @@ -162,6 +164,8 @@ func TestReactorBroadcastTxMessage(t *testing.T) { } func TestReactorNoBroadcastToSender(t *testing.T) { + t.Parallel() + mconfig := memcfg.TestMempoolConfig() pconfig := p2pcfg.TestP2PConfig() const N = 2 @@ -179,6 +183,8 @@ func TestReactorNoBroadcastToSender(t *testing.T) { } func TestFlappyBroadcastTxForPeerStopsWhenPeerStops(t *testing.T) { + t.Parallel() + testutils.FilterStability(t, testutils.Flappy) if testing.Short() { @@ -205,6 +211,8 @@ func TestFlappyBroadcastTxForPeerStopsWhenPeerStops(t *testing.T) { } func TestFlappyBroadcastTxForPeerStopsWhenReactorStops(t *testing.T) { + t.Parallel() + testutils.FilterStability(t, testutils.Flappy) if testing.Short() { @@ -227,6 +235,8 @@ func TestFlappyBroadcastTxForPeerStopsWhenReactorStops(t *testing.T) { } func TestMempoolIDsBasic(t *testing.T) { + t.Parallel() + ids := newMempoolIDs() peer := mock.NewPeer(net.IP{127, 0, 0, 1}) @@ -241,6 +251,8 @@ func TestMempoolIDsBasic(t *testing.T) { } func TestMempoolIDsPanicsIfNodeRequestsOvermaxActiveIDs(t *testing.T) { + t.Parallel() + if testing.Short() { return } diff --git a/tm2/pkg/bft/privval/file_test.go b/tm2/pkg/bft/privval/file_test.go index 36979e19ea3..a798a7ddc64 100644 --- a/tm2/pkg/bft/privval/file_test.go +++ b/tm2/pkg/bft/privval/file_test.go @@ -17,6 +17,8 @@ import ( ) func TestGenLoadValidator(t *testing.T) { + t.Parallel() + assert := assert.New(t) tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") @@ -37,6 +39,8 @@ func TestGenLoadValidator(t *testing.T) { } func TestResetValidator(t *testing.T) { + t.Parallel() + tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") require.Nil(t, err) tempStateFile, err := os.CreateTemp("", "priv_validator_state_") @@ -65,6 +69,8 @@ func TestResetValidator(t *testing.T) { } func TestLoadOrGenValidator(t *testing.T) { + t.Parallel() + assert := assert.New(t) tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") @@ -88,6 +94,8 @@ func TestLoadOrGenValidator(t *testing.T) { } func TestUnmarshalValidatorState(t *testing.T) { + t.Parallel() + assert, require := assert.New(t), require.New(t) // create some fixed values @@ -113,6 +121,8 @@ func TestUnmarshalValidatorState(t *testing.T) { } func TestUnmarshalValidatorKey(t *testing.T) { + t.Parallel() + assert, require := assert.New(t), require.New(t) // create some fixed values @@ -157,6 +167,8 @@ func TestUnmarshalValidatorKey(t *testing.T) { } func TestSignVote(t *testing.T) { + t.Parallel() + assert := assert.New(t) tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") @@ -203,6 +215,8 @@ func TestSignVote(t *testing.T) { } func TestSignProposal(t *testing.T) { + t.Parallel() + assert := assert.New(t) tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") @@ -247,6 +261,8 @@ func TestSignProposal(t *testing.T) { } func TestDifferByTimestamp(t *testing.T) { + t.Parallel() + tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") require.Nil(t, err) tempStateFile, err := os.CreateTemp("", "priv_validator_state_") diff --git a/tm2/pkg/bft/privval/signer_client_test.go b/tm2/pkg/bft/privval/signer_client_test.go index 1ba6b2e08d5..a896547aec3 100644 --- a/tm2/pkg/bft/privval/signer_client_test.go +++ b/tm2/pkg/bft/privval/signer_client_test.go @@ -53,6 +53,8 @@ func getSignerTestCases(t *testing.T) []signerTestCase { } func TestSignerClose(t *testing.T) { + t.Parallel() + for _, tc := range getSignerTestCases(t) { err := tc.signerClient.Close() assert.NoError(t, err) @@ -63,6 +65,8 @@ func TestSignerClose(t *testing.T) { } func TestSignerPing(t *testing.T) { + t.Parallel() + for _, tc := range getSignerTestCases(t) { defer tc.signerServer.Stop() defer tc.signerClient.Close() @@ -73,6 +77,8 @@ func TestSignerPing(t *testing.T) { } func TestSignerGetPubKey(t *testing.T) { + t.Parallel() + for _, tc := range getSignerTestCases(t) { defer tc.signerServer.Stop() defer tc.signerClient.Close() @@ -90,6 +96,8 @@ func TestSignerGetPubKey(t *testing.T) { } func TestSignerProposal(t *testing.T) { + t.Parallel() + for _, tc := range getSignerTestCases(t) { ts := time.Now() want := &types.Proposal{Timestamp: ts} @@ -106,6 +114,8 @@ func TestSignerProposal(t *testing.T) { } func TestSignerVote(t *testing.T) { + t.Parallel() + for _, tc := range getSignerTestCases(t) { ts := time.Now() want := &types.Vote{Timestamp: ts, Type: types.PrecommitType} @@ -122,6 +132,8 @@ func TestSignerVote(t *testing.T) { } func TestSignerVoteResetDeadline(t *testing.T) { + t.Parallel() + for _, tc := range getSignerTestCases(t) { ts := time.Now() want := &types.Vote{Timestamp: ts, Type: types.PrecommitType} @@ -148,6 +160,8 @@ func TestSignerVoteResetDeadline(t *testing.T) { } func TestFlappySignerVoteKeepAlive(t *testing.T) { + t.Parallel() + testutils.FilterStability(t, testutils.Flappy) for _, tc := range getSignerTestCases(t) { @@ -175,6 +189,8 @@ func TestFlappySignerVoteKeepAlive(t *testing.T) { } func TestSignerSignProposalErrors(t *testing.T) { + t.Parallel() + for _, tc := range getSignerTestCases(t) { // Replace service with a mock that always fails tc.signerServer.privVal = types.NewErroringMockPV() @@ -197,6 +213,8 @@ func TestSignerSignProposalErrors(t *testing.T) { } func TestSignerSignVoteErrors(t *testing.T) { + t.Parallel() + for _, tc := range getSignerTestCases(t) { ts := time.Now() vote := &types.Vote{Timestamp: ts, Type: types.PrecommitType} @@ -243,6 +261,8 @@ func brokenHandler(privVal types.PrivValidator, request SignerMessage, chainID s } func TestSignerUnexpectedResponse(t *testing.T) { + t.Parallel() + for _, tc := range getSignerTestCases(t) { tc.signerServer.privVal = types.NewMockPV() tc.mockPV = types.NewMockPV() diff --git a/tm2/pkg/bft/privval/signer_listener_endpoint_test.go b/tm2/pkg/bft/privval/signer_listener_endpoint_test.go index c2d89660baf..16640583364 100644 --- a/tm2/pkg/bft/privval/signer_listener_endpoint_test.go +++ b/tm2/pkg/bft/privval/signer_listener_endpoint_test.go @@ -32,6 +32,8 @@ type dialerTestCase struct { // SignerDialerEndpoint.dialer() call inside SignerDialerEndpoint.acceptNewConnection() to return // successfully immediately, putting an instant stop to any retry attempts. func TestSignerRemoteRetryTCPOnly(t *testing.T) { + t.Parallel() + var ( attemptCh = make(chan int) retries = 10 @@ -83,6 +85,8 @@ func TestSignerRemoteRetryTCPOnly(t *testing.T) { } func TestRetryConnToRemoteSigner(t *testing.T) { + t.Parallel() + for _, tc := range getDialerTestCases(t) { var ( logger = log.TestingLogger() diff --git a/tm2/pkg/bft/privval/socket_dialers_test.go b/tm2/pkg/bft/privval/socket_dialers_test.go index 150b9218575..a2f2cf9743b 100644 --- a/tm2/pkg/bft/privval/socket_dialers_test.go +++ b/tm2/pkg/bft/privval/socket_dialers_test.go @@ -40,6 +40,8 @@ func getDialerTestCases(t *testing.T) []dialerTestCase { } func TestIsConnTimeoutForFundamentalTimeouts(t *testing.T) { + t.Parallel() + // Generate a networking timeout tcpAddr := "127.0.0.1:34985" dialer := DialTCPFn(tcpAddr, time.Millisecond, ed25519.GenPrivKey()) @@ -49,6 +51,8 @@ func TestIsConnTimeoutForFundamentalTimeouts(t *testing.T) { } func TestIsConnTimeoutForWrappedConnTimeouts(t *testing.T) { + t.Parallel() + tcpAddr := "127.0.0.1:34985" dialer := DialTCPFn(tcpAddr, time.Millisecond, ed25519.GenPrivKey()) _, err := dialer() diff --git a/tm2/pkg/bft/privval/socket_listeners_test.go b/tm2/pkg/bft/privval/socket_listeners_test.go index 6ca7863d1fd..f43ec6e1636 100644 --- a/tm2/pkg/bft/privval/socket_listeners_test.go +++ b/tm2/pkg/bft/privval/socket_listeners_test.go @@ -88,6 +88,8 @@ func listenerTestCases(t *testing.T, timeoutAccept, timeoutReadWrite time.Durati } func TestListenerTimeoutAccept(t *testing.T) { + t.Parallel() + for _, tc := range listenerTestCases(t, time.Millisecond, time.Second) { _, err := tc.listener.Accept() opErr, ok := err.(*net.OpError) @@ -102,6 +104,8 @@ func TestListenerTimeoutAccept(t *testing.T) { } func TestListenerTimeoutReadWrite(t *testing.T) { + t.Parallel() + const ( // This needs to be long enough s.t. the Accept will definitely succeed: timeoutAccept = time.Second diff --git a/tm2/pkg/bft/privval/utils_test.go b/tm2/pkg/bft/privval/utils_test.go index 6e5562e4cbd..63ee6a6076a 100644 --- a/tm2/pkg/bft/privval/utils_test.go +++ b/tm2/pkg/bft/privval/utils_test.go @@ -9,6 +9,8 @@ import ( ) func TestIsConnTimeoutForNonTimeoutErrors(t *testing.T) { + t.Parallel() + assert.False(t, IsConnTimeout(errors.Wrap(ErrDialRetryMax, "max retries exceeded"))) assert.False(t, IsConnTimeout(errors.New("completely irrelevant error"))) } diff --git a/tm2/pkg/bft/rpc/client/helpers_test.go b/tm2/pkg/bft/rpc/client/helpers_test.go index a58ed5adfd6..4d0b54c2358 100644 --- a/tm2/pkg/bft/rpc/client/helpers_test.go +++ b/tm2/pkg/bft/rpc/client/helpers_test.go @@ -15,6 +15,8 @@ import ( ) func TestWaitForHeight(t *testing.T) { + t.Parallel() + assert, require := assert.New(t), require.New(t) // test with error result - immediate failure diff --git a/tm2/pkg/bft/rpc/client/rpc_test.go b/tm2/pkg/bft/rpc/client/rpc_test.go index 7b649e1dda8..e09ae8d4466 100644 --- a/tm2/pkg/bft/rpc/client/rpc_test.go +++ b/tm2/pkg/bft/rpc/client/rpc_test.go @@ -35,6 +35,8 @@ func GetClients() []client.Client { } func TestNilCustomHTTPClient(t *testing.T) { + t.Parallel() + require.Panics(t, func() { client.NewHTTPWithClient("http://example.com", "/websocket", nil) }) @@ -44,6 +46,8 @@ func TestNilCustomHTTPClient(t *testing.T) { } func TestCustomHTTPClient(t *testing.T) { + t.Parallel() + remote := rpctest.GetConfig().RPC.ListenAddress c := client.NewHTTPWithClient(remote, "/websocket", http.DefaultClient) status, err := c.Status() @@ -52,6 +56,8 @@ func TestCustomHTTPClient(t *testing.T) { } func TestCorsEnabled(t *testing.T) { + t.Parallel() + origin := rpctest.GetConfig().RPC.CORSAllowedOrigins[0] remote := strings.Replace(rpctest.GetConfig().RPC.ListenAddress, "tcp", "http", -1) @@ -68,6 +74,8 @@ func TestCorsEnabled(t *testing.T) { // Make sure status is correct (we connect properly) func TestStatus(t *testing.T) { + t.Parallel() + for i, c := range GetClients() { moniker := rpctest.GetConfig().Moniker status, err := c.Status() @@ -78,6 +86,8 @@ func TestStatus(t *testing.T) { // Make sure info is correct (we connect properly) func TestInfo(t *testing.T) { + t.Parallel() + for i, c := range GetClients() { // status, err := c.Status() // require.Nil(t, err, "%+v", err) @@ -90,6 +100,8 @@ func TestInfo(t *testing.T) { } func TestNetInfo(t *testing.T) { + t.Parallel() + for i, c := range GetClients() { nc, ok := c.(client.NetworkClient) require.True(t, ok, "%d", i) @@ -101,6 +113,8 @@ func TestNetInfo(t *testing.T) { } func TestDumpConsensusState(t *testing.T) { + t.Parallel() + for i, c := range GetClients() { // FIXME: fix server so it doesn't panic on invalid input nc, ok := c.(client.NetworkClient) @@ -113,6 +127,8 @@ func TestDumpConsensusState(t *testing.T) { } func TestConsensusState(t *testing.T) { + t.Parallel() + for i, c := range GetClients() { // FIXME: fix server so it doesn't panic on invalid input nc, ok := c.(client.NetworkClient) @@ -124,6 +140,8 @@ func TestConsensusState(t *testing.T) { } func TestHealth(t *testing.T) { + t.Parallel() + for i, c := range GetClients() { nc, ok := c.(client.NetworkClient) require.True(t, ok, "%d", i) @@ -133,6 +151,8 @@ func TestHealth(t *testing.T) { } func TestGenesisAndValidators(t *testing.T) { + t.Parallel() + for i, c := range GetClients() { // make sure this is the right genesis file gen, err := c.Genesis() @@ -173,6 +193,8 @@ func TestABCIQuery(t *testing.T) { // Make some app checks func TestAppCalls(t *testing.T) { + t.Parallel() + assert, require := assert.New(t), require.New(t) for i, c := range GetClients() { // get an offset of height to avoid racing and guessing @@ -265,6 +287,8 @@ func TestAppCalls(t *testing.T) { } func TestBroadcastTxSync(t *testing.T) { + t.Parallel() + require := require.New(t) // TODO (melekes): use mempool which is set on RPC rather than getting it from node @@ -344,6 +368,8 @@ func TestNumUnconfirmedTxs(t *testing.T) { /* func TestTx(t *testing.T) { + t.Parallel() + // first we broadcast a tx c := getHTTPClient() _, _, tx := MakeTxKV() @@ -398,6 +424,8 @@ func TestTx(t *testing.T) { } func TestTxSearch(t *testing.T) { + t.Parallel() + // first we broadcast a tx c := getHTTPClient() _, _, tx := MakeTxKV() @@ -519,6 +547,8 @@ func testBatchedJSONRPCCalls(t *testing.T, c *client.HTTP) { } func TestBatchedJSONRPCCallsCancellation(t *testing.T) { + t.Parallel() + c := getHTTPClient() _, _, tx1 := MakeTxKV() _, _, tx2 := MakeTxKV() @@ -537,6 +567,8 @@ func TestBatchedJSONRPCCallsCancellation(t *testing.T) { } func TestSendingEmptyJSONRPCRequestBatch(t *testing.T) { + t.Parallel() + c := getHTTPClient() batch := c.NewBatch() _, err := batch.Send() @@ -544,6 +576,8 @@ func TestSendingEmptyJSONRPCRequestBatch(t *testing.T) { } func TestClearingEmptyJSONRPCRequestBatch(t *testing.T) { + t.Parallel() + c := getHTTPClient() batch := c.NewBatch() require.Zero(t, batch.Clear(), "clearing an empty batch of JSON RPC requests should result in a 0 result") diff --git a/tm2/pkg/bft/rpc/core/blocks_test.go b/tm2/pkg/bft/rpc/core/blocks_test.go index a4d689ffd23..0fcd40f6d14 100644 --- a/tm2/pkg/bft/rpc/core/blocks_test.go +++ b/tm2/pkg/bft/rpc/core/blocks_test.go @@ -8,6 +8,8 @@ import ( ) func TestBlockchainInfo(t *testing.T) { + t.Parallel() + cases := []struct { min, max int64 height int64 diff --git a/tm2/pkg/bft/rpc/core/net_test.go b/tm2/pkg/bft/rpc/core/net_test.go index 42bf79fcce1..c3a8830cb1b 100644 --- a/tm2/pkg/bft/rpc/core/net_test.go +++ b/tm2/pkg/bft/rpc/core/net_test.go @@ -13,6 +13,8 @@ import ( ) func TestUnsafeDialSeeds(t *testing.T) { + t.Parallel() + sw := p2p.MakeSwitch(p2pcfg.DefaultP2PConfig(), 1, "testing", "123.123.123", func(n int, sw *p2p.Switch) *p2p.Switch { return sw }) err := sw.Start() @@ -43,6 +45,8 @@ func TestUnsafeDialSeeds(t *testing.T) { } func TestUnsafeDialPeers(t *testing.T) { + t.Parallel() + sw := p2p.MakeSwitch(p2pcfg.DefaultP2PConfig(), 1, "testing", "123.123.123", func(n int, sw *p2p.Switch) *p2p.Switch { return sw }) err := sw.Start() diff --git a/tm2/pkg/bft/rpc/core/pipe_test.go b/tm2/pkg/bft/rpc/core/pipe_test.go index 3147f600734..6136f66c9d8 100644 --- a/tm2/pkg/bft/rpc/core/pipe_test.go +++ b/tm2/pkg/bft/rpc/core/pipe_test.go @@ -8,6 +8,8 @@ import ( ) func TestPaginationPage(t *testing.T) { + t.Parallel() + cases := []struct { totalCount int perPage int @@ -51,6 +53,8 @@ func TestPaginationPage(t *testing.T) { } func TestPaginationPerPage(t *testing.T) { + t.Parallel() + cases := []struct { totalCount int perPage int diff --git a/tm2/pkg/bft/rpc/core/types/responses_test.go b/tm2/pkg/bft/rpc/core/types/responses_test.go index d309a6b63a1..268a8d25c34 100644 --- a/tm2/pkg/bft/rpc/core/types/responses_test.go +++ b/tm2/pkg/bft/rpc/core/types/responses_test.go @@ -9,6 +9,8 @@ import ( ) func TestStatusIndexer(t *testing.T) { + t.Parallel() + var status *ResultStatus assert.False(t, status.TxIndexEnabled()) diff --git a/tm2/pkg/bft/rpc/lib/client/args_test.go b/tm2/pkg/bft/rpc/lib/client/args_test.go index 8f44939f0aa..2a7e749f094 100644 --- a/tm2/pkg/bft/rpc/lib/client/args_test.go +++ b/tm2/pkg/bft/rpc/lib/client/args_test.go @@ -15,6 +15,8 @@ type Foo struct { } func TestArgToJSON(t *testing.T) { + t.Parallel() + assert := assert.New(t) require := require.New(t) diff --git a/tm2/pkg/bft/rpc/lib/client/http_client_test.go b/tm2/pkg/bft/rpc/lib/client/http_client_test.go index 9546a0c1d72..460f5b9947b 100644 --- a/tm2/pkg/bft/rpc/lib/client/http_client_test.go +++ b/tm2/pkg/bft/rpc/lib/client/http_client_test.go @@ -7,6 +7,8 @@ import ( ) func Test_parseRemoteAddr(t *testing.T) { + t.Parallel() + tt := []struct { remoteAddr string network, s, errContains string @@ -32,6 +34,8 @@ func Test_parseRemoteAddr(t *testing.T) { // and other protocols are left intact from parseRemoteAddr() func Test_makeHTTPDialer(t *testing.T) { + t.Parallel() + dl := makeHTTPDialer("https://.") _, err := dl("hello", "world") if assert.NotNil(t, err) { @@ -42,6 +46,8 @@ func Test_makeHTTPDialer(t *testing.T) { } func Test_makeHTTPDialer_noConvert(t *testing.T) { + t.Parallel() + dl := makeHTTPDialer("udp://.") _, err := dl("hello", "world") if assert.NotNil(t, err) { diff --git a/tm2/pkg/bft/rpc/lib/client/integration_test.go b/tm2/pkg/bft/rpc/lib/client/integration_test.go index 486540a989f..f3c705ecf98 100644 --- a/tm2/pkg/bft/rpc/lib/client/integration_test.go +++ b/tm2/pkg/bft/rpc/lib/client/integration_test.go @@ -19,6 +19,8 @@ import ( ) func TestWSClientReconnectWithJitter(t *testing.T) { + t.Parallel() + n := 8 maxReconnectAttempts := 3 // Max wait time is ceil(1+0.999) + ceil(2+0.999) + ceil(4+0.999) + ceil(...) = 2 + 3 + 5 = 10s + ... diff --git a/tm2/pkg/bft/rpc/lib/client/ws_client_test.go b/tm2/pkg/bft/rpc/lib/client/ws_client_test.go index b3a495f25b2..47c3a50ee63 100644 --- a/tm2/pkg/bft/rpc/lib/client/ws_client_test.go +++ b/tm2/pkg/bft/rpc/lib/client/ws_client_test.go @@ -58,6 +58,8 @@ func (h *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } func TestWSClientReconnectsAfterReadFailure(t *testing.T) { + t.Parallel() + var wg sync.WaitGroup // start server @@ -91,6 +93,8 @@ func TestWSClientReconnectsAfterReadFailure(t *testing.T) { } func TestWSClientReconnectsAfterWriteFailure(t *testing.T) { + t.Parallel() + var wg sync.WaitGroup // start server @@ -121,6 +125,8 @@ func TestWSClientReconnectsAfterWriteFailure(t *testing.T) { } func TestWSClientReconnectFailure(t *testing.T) { + t.Parallel() + // start server h := &myHandler{} s := httptest.NewServer(h) @@ -172,6 +178,8 @@ func TestWSClientReconnectFailure(t *testing.T) { } func TestNotBlockingOnStop(t *testing.T) { + t.Parallel() + timeout := 2 * time.Second s := httptest.NewServer(&myHandler{}) c := startClient(t, s.Listener.Addr()) diff --git a/tm2/pkg/bft/rpc/lib/rpc_test.go b/tm2/pkg/bft/rpc/lib/rpc_test.go index 2c1aebaae14..a299417187a 100644 --- a/tm2/pkg/bft/rpc/lib/rpc_test.go +++ b/tm2/pkg/bft/rpc/lib/rpc_test.go @@ -280,6 +280,8 @@ func testWithWSClient(t *testing.T, cl *client.WSClient) { // ------------- func TestServersAndClientsBasic(t *testing.T) { + t.Parallel() + serverAddrs := [...]string{tcpAddr, unixAddr} for _, addr := range serverAddrs { cl1 := client.NewURIClient(addr) @@ -309,6 +311,8 @@ func TestServersAndClientsBasic(t *testing.T) { } func TestHexStringArg(t *testing.T) { + t.Parallel() + cl := client.NewURIClient(tcpAddr) // should NOT be handled as hex val := "0xabc" @@ -318,6 +322,8 @@ func TestHexStringArg(t *testing.T) { } func TestQuotedStringArg(t *testing.T) { + t.Parallel() + cl := client.NewURIClient(tcpAddr) // should NOT be unquoted val := "\"abc\"" @@ -327,6 +333,8 @@ func TestQuotedStringArg(t *testing.T) { } func TestWSNewWSRPCFunc(t *testing.T) { + t.Parallel() + cl := client.NewWSClient(tcpAddr, websocketEndpoint) cl.SetLogger(log.TestingLogger()) err := cl.Start() @@ -352,6 +360,8 @@ func TestWSNewWSRPCFunc(t *testing.T) { } func TestWSHandlesArrayParams(t *testing.T) { + t.Parallel() + cl := client.NewWSClient(tcpAddr, websocketEndpoint) cl.SetLogger(log.TestingLogger()) err := cl.Start() @@ -377,6 +387,8 @@ func TestWSHandlesArrayParams(t *testing.T) { // TestWSClientPingPong checks that a client & server exchange pings // & pongs so connection stays alive. func TestWSClientPingPong(t *testing.T) { + t.Parallel() + cl := client.NewWSClient(tcpAddr, websocketEndpoint) cl.SetLogger(log.TestingLogger()) err := cl.Start() diff --git a/tm2/pkg/bft/rpc/lib/server/handlers_test.go b/tm2/pkg/bft/rpc/lib/server/handlers_test.go index 05f92a3b719..e09a8a7cf96 100644 --- a/tm2/pkg/bft/rpc/lib/server/handlers_test.go +++ b/tm2/pkg/bft/rpc/lib/server/handlers_test.go @@ -43,6 +43,8 @@ func statusOK(code int) bool { return code >= 200 && code <= 299 } // do not crash our RPC handlers. // See Issue https://github.com/gnolang/gno/tm2/pkg/bft/issues/708. func TestRPCParams(t *testing.T) { + t.Parallel() + mux := testMux() tests := []struct { payload string @@ -91,6 +93,8 @@ func TestRPCParams(t *testing.T) { } func TestJSONRPCID(t *testing.T) { + t.Parallel() + mux := testMux() tests := []struct { payload string @@ -138,6 +142,8 @@ func TestJSONRPCID(t *testing.T) { } func TestRPCNotification(t *testing.T) { + t.Parallel() + mux := testMux() body := strings.NewReader(`{"jsonrpc": "2.0", "id": ""}`) req, _ := http.NewRequest("POST", "http://localhost/", body) @@ -153,6 +159,8 @@ func TestRPCNotification(t *testing.T) { } func TestRPCNotificationInBatch(t *testing.T) { + t.Parallel() + mux := testMux() tests := []struct { payload string @@ -219,6 +227,8 @@ func TestRPCNotificationInBatch(t *testing.T) { } func TestUnknownRPCPath(t *testing.T) { + t.Parallel() + mux := testMux() req, _ := http.NewRequest("GET", "http://localhost/unknownrpcpath", nil) rec := httptest.NewRecorder() @@ -233,6 +243,8 @@ func TestUnknownRPCPath(t *testing.T) { // JSON-RPC over WEBSOCKETS func TestWebsocketManagerHandler(t *testing.T) { + t.Parallel() + s := newWSServer() defer s.Close() diff --git a/tm2/pkg/bft/rpc/lib/server/http_server_test.go b/tm2/pkg/bft/rpc/lib/server/http_server_test.go index aaf817e6d85..5ab8d2890ae 100644 --- a/tm2/pkg/bft/rpc/lib/server/http_server_test.go +++ b/tm2/pkg/bft/rpc/lib/server/http_server_test.go @@ -21,6 +21,8 @@ import ( ) func TestMaxOpenConnections(t *testing.T) { + t.Parallel() + const max = 5 // max simultaneous connections // Start the server. @@ -70,6 +72,8 @@ func TestMaxOpenConnections(t *testing.T) { } func TestStartHTTPAndTLSServer(t *testing.T) { + t.Parallel() + ln, err := net.Listen("tcp", "localhost:0") require.NoError(t, err) defer ln.Close() @@ -96,6 +100,8 @@ func TestStartHTTPAndTLSServer(t *testing.T) { } func TestRecoverAndLogHandler(t *testing.T) { + t.Parallel() + tests := []struct { name string panicArg any @@ -163,6 +169,8 @@ func TestRecoverAndLogHandler(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + var ( req, _ = http.NewRequest(http.MethodGet, "", nil) resp = httptest.NewRecorder() diff --git a/tm2/pkg/bft/rpc/lib/server/parse_test.go b/tm2/pkg/bft/rpc/lib/server/parse_test.go index a28dd255f23..aece3f20f3a 100644 --- a/tm2/pkg/bft/rpc/lib/server/parse_test.go +++ b/tm2/pkg/bft/rpc/lib/server/parse_test.go @@ -13,6 +13,8 @@ import ( ) func TestParseJSONMap(t *testing.T) { + t.Parallel() + input := []byte(`{"value":"1234","height":22}`) // naive is float,string @@ -101,6 +103,8 @@ func TestParseJSONMap(t *testing.T) { } func TestParseJSONArray(t *testing.T) { + t.Parallel() + input := []byte(`["1234",22]`) // naive is float,string @@ -134,6 +138,8 @@ func TestParseJSONArray(t *testing.T) { } func TestParseJSONRPC(t *testing.T) { + t.Parallel() + demo := func(ctx *types.Context, height int, name string) {} call := NewRPCFunc(demo, "height,name") @@ -170,6 +176,8 @@ func TestParseJSONRPC(t *testing.T) { } func TestParseURI(t *testing.T) { + t.Parallel() + demo := func(ctx *types.Context, height int, name string) {} call := NewRPCFunc(demo, "height,name") diff --git a/tm2/pkg/bft/rpc/lib/types/types_test.go b/tm2/pkg/bft/rpc/lib/types/types_test.go index e047c69bd77..55ee8ed3945 100644 --- a/tm2/pkg/bft/rpc/lib/types/types_test.go +++ b/tm2/pkg/bft/rpc/lib/types/types_test.go @@ -31,6 +31,8 @@ var responseTests = []responseTest{ } func TestResponses(t *testing.T) { + t.Parallel() + assert := assert.New(t) for _, tt := range responseTests { jsonid := tt.id @@ -52,6 +54,8 @@ func TestResponses(t *testing.T) { } func TestUnmarshallResponses(t *testing.T) { + t.Parallel() + assert := assert.New(t) for _, tt := range responseTests { response := &RPCResponse{} @@ -66,6 +70,8 @@ func TestUnmarshallResponses(t *testing.T) { } func TestRPCError(t *testing.T) { + t.Parallel() + assert.Equal(t, "RPC error 12 - Badness: One worse than a code 11", fmt.Sprintf("%v", &RPCError{ Code: 12, diff --git a/tm2/pkg/bft/state/execution_test.go b/tm2/pkg/bft/state/execution_test.go index 849c87d3359..25217ffccbe 100644 --- a/tm2/pkg/bft/state/execution_test.go +++ b/tm2/pkg/bft/state/execution_test.go @@ -29,6 +29,8 @@ var ( ) func TestApplyBlock(t *testing.T) { + t.Parallel() + cc := proxy.NewLocalClientCreator(kvstore.NewKVStoreApplication()) proxyApp := proxy.NewAppConns(cc) err := proxyApp.Start() @@ -53,6 +55,8 @@ func TestApplyBlock(t *testing.T) { // TestBeginBlockValidators ensures we send absent validators list. func TestBeginBlockValidators(t *testing.T) { + t.Parallel() + app := &testApp{} cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc) @@ -104,6 +108,8 @@ func TestBeginBlockValidators(t *testing.T) { } func TestValidateValidatorUpdates(t *testing.T) { + t.Parallel() + pubkey1 := ed25519.GenPrivKey().PubKey() pubkey2 := ed25519.GenPrivKey().PubKey() @@ -164,6 +170,8 @@ func TestValidateValidatorUpdates(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { + t.Parallel() + err := sm.ValidateValidatorUpdates(tc.abciUpdates, tc.validatorParams) if tc.shouldErr { assert.Error(t, err) @@ -175,6 +183,8 @@ func TestValidateValidatorUpdates(t *testing.T) { } func TestUpdateValidators(t *testing.T) { + t.Parallel() + pubkey1 := ed25519.GenPrivKey().PubKey() val1 := types.NewValidator(pubkey1, 10) pubkey2 := ed25519.GenPrivKey().PubKey() @@ -230,6 +240,8 @@ func TestUpdateValidators(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { + t.Parallel() + err := tc.currentSet.UpdateWithABCIValidatorUpdates(tc.abciUpdates) if tc.shouldErr { assert.Error(t, err) @@ -250,6 +262,8 @@ func TestUpdateValidators(t *testing.T) { // TestEndBlockValidatorUpdates ensures we update validator set and send an event. func TestEndBlockValidatorUpdates(t *testing.T) { + t.Parallel() + app := &testApp{} cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc) @@ -316,6 +330,8 @@ LOOP: // TestEndBlockValidatorUpdatesResultingInEmptySet checks that processing validator updates that // would result in empty set causes no panic, an error is raised and NextValidators is not updated func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) { + t.Parallel() + app := &testApp{} cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc) diff --git a/tm2/pkg/bft/state/state_test.go b/tm2/pkg/bft/state/state_test.go index a48f4f0a3e4..d19b8526d98 100644 --- a/tm2/pkg/bft/state/state_test.go +++ b/tm2/pkg/bft/state/state_test.go @@ -42,6 +42,8 @@ func setupTestCase(t *testing.T) (func(t *testing.T), dbm.DB, sm.State) { // TestStateCopy tests the correct copying behaviour of State. func TestStateCopy(t *testing.T) { + t.Parallel() + t.Helper() tearDown, _, state := setupTestCase(t) @@ -62,6 +64,8 @@ func TestStateCopy(t *testing.T) { // TestMakeGenesisStateNilValidators tests state's consistency when genesis file's validators field is nil. func TestMakeGenesisStateNilValidators(t *testing.T) { + t.Parallel() + doc := types.GenesisDoc{ ChainID: "dummy", Validators: nil, @@ -75,6 +79,8 @@ func TestMakeGenesisStateNilValidators(t *testing.T) { // TestStateSaveLoad tests saving and loading State from a db. func TestStateSaveLoad(t *testing.T) { + t.Parallel() + tearDown, stateDB, state := setupTestCase(t) defer tearDown(t) //nolint: vetshadow @@ -91,6 +97,8 @@ func TestStateSaveLoad(t *testing.T) { // TestABCIResponsesSaveLoad tests saving and loading ABCIResponses. func TestABCIResponsesSaveLoad1(t *testing.T) { + t.Parallel() + tearDown, stateDB, state := setupTestCase(t) defer tearDown(t) //nolint: vetshadow @@ -129,6 +137,8 @@ func TestABCIResponsesSaveLoad1(t *testing.T) { // TestResultsSaveLoad tests saving and loading ABCI results. func TestABCIResponsesSaveLoad2(t *testing.T) { + t.Parallel() + tearDown, stateDB, _ := setupTestCase(t) defer tearDown(t) //nolint: vetshadow @@ -223,6 +233,8 @@ func TestABCIResponsesSaveLoad2(t *testing.T) { // TestValidatorSimpleSaveLoad tests saving and loading validators. func TestValidatorSimpleSaveLoad(t *testing.T) { + t.Parallel() + tearDown, stateDB, state := setupTestCase(t) defer tearDown(t) //nolint: vetshadow @@ -256,6 +268,8 @@ func TestValidatorSimpleSaveLoad(t *testing.T) { // TestValidatorChangesSaveLoad tests saving and loading a validator set with changes. func TestOneValidatorChangesSaveLoad(t *testing.T) { + t.Parallel() + tearDown, stateDB, state := setupTestCase(t) defer tearDown(t) @@ -309,6 +323,8 @@ func TestOneValidatorChangesSaveLoad(t *testing.T) { } func TestProposerFrequency(t *testing.T) { + t.Parallel() + // some explicit test cases testCases := []struct { powers []int64 @@ -432,6 +448,8 @@ func testProposerFreq(t *testing.T, caseNum int, valSet *types.ValidatorSet) { // TestProposerPriorityDoesNotGetResetToZero assert that we preserve accum when calling updateState // see https://github.com/tendermint/classic/issues/2718 func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) { + t.Parallel() + tearDown, _, state := setupTestCase(t) defer tearDown(t) val1VotingPower := int64(10) @@ -534,6 +552,8 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) { } func TestProposerPriorityProposerAlternates(t *testing.T) { + t.Parallel() + // Regression test that would fail if the inner workings of // IncrementProposerPriority change. // Additionally, make sure that same power validators alternate if both @@ -670,6 +690,8 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { } func TestLargeGenesisValidator(t *testing.T) { + t.Parallel() + tearDown, _, state := setupTestCase(t) defer tearDown(t) @@ -822,6 +844,8 @@ func TestLargeGenesisValidator(t *testing.T) { } func TestStoreLoadValidatorsIncrementsProposerPriority(t *testing.T) { + t.Parallel() + const valSetSize = 2 tearDown, stateDB, state := setupTestCase(t) defer tearDown(t) @@ -845,6 +869,8 @@ func TestStoreLoadValidatorsIncrementsProposerPriority(t *testing.T) { // TestValidatorChangesSaveLoad tests saving and loading a validator set with // changes. func TestManyValidatorChangesSaveLoad(t *testing.T) { + t.Parallel() + const valSetSize = 7 tearDown, stateDB, state := setupTestCase(t) defer tearDown(t) @@ -890,6 +916,8 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) { } func TestStateMakeBlock(t *testing.T) { + t.Parallel() + tearDown, _, state := setupTestCase(t) defer tearDown(t) @@ -905,6 +933,8 @@ func TestStateMakeBlock(t *testing.T) { // TestConsensusParamsChangesSaveLoad tests saving and loading consensus params // with changes. func TestConsensusParamsChangesSaveLoad(t *testing.T) { + t.Parallel() + tearDown, stateDB, state := setupTestCase(t) defer tearDown(t) @@ -964,6 +994,8 @@ func TestConsensusParamsChangesSaveLoad(t *testing.T) { } func TestApplyUpdates(t *testing.T) { + t.Parallel() + initParams := makeConsensusParams(1, 2, 3, 3, 4) cases := [...]struct { diff --git a/tm2/pkg/bft/state/store_test.go b/tm2/pkg/bft/state/store_test.go index 79282e6a311..ed3b8e63311 100644 --- a/tm2/pkg/bft/state/store_test.go +++ b/tm2/pkg/bft/state/store_test.go @@ -15,6 +15,8 @@ import ( ) func TestStoreLoadValidators(t *testing.T) { + t.Parallel() + stateDB := dbm.NewMemDB() val, _ := types.RandValidator(true, 10) vals := types.NewValidatorSet([]*types.Validator{val}) diff --git a/tm2/pkg/bft/state/validation_test.go b/tm2/pkg/bft/state/validation_test.go index 94aafe92694..c1941381de7 100644 --- a/tm2/pkg/bft/state/validation_test.go +++ b/tm2/pkg/bft/state/validation_test.go @@ -19,6 +19,8 @@ import ( const validationTestsStopHeight int64 = 10 func TestValidateBlockHeader(t *testing.T) { + t.Parallel() + proxyApp := newTestApp() require.NoError(t, proxyApp.Start()) defer proxyApp.Stop() @@ -80,6 +82,8 @@ func TestValidateBlockHeader(t *testing.T) { } func TestValidateBlockCommit(t *testing.T) { + t.Parallel() + proxyApp := newTestApp() require.NoError(t, proxyApp.Start()) defer proxyApp.Stop() diff --git a/tm2/pkg/bft/store/store_test.go b/tm2/pkg/bft/store/store_test.go index 1dc0bda833c..fce566903c3 100644 --- a/tm2/pkg/bft/store/store_test.go +++ b/tm2/pkg/bft/store/store_test.go @@ -58,6 +58,8 @@ func makeStateAndBlockStore(logger log.Logger) (sm.State, *BlockStore, cleanupFu } func TestLoadBlockStoreStateJSON(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() bsj := &BlockStoreStateJSON{Height: 1000} @@ -69,6 +71,8 @@ func TestLoadBlockStoreStateJSON(t *testing.T) { } func TestNewBlockStore(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() db.Set(blockStoreKey, []byte(`{"height": "10000"}`)) bs := NewBlockStore(db) @@ -129,6 +133,8 @@ func TestMain(m *testing.M) { // TODO: This test should be simplified ... func TestBlockStoreSaveLoadBlock(t *testing.T) { + t.Parallel() + state, bs, cleanup := makeStateAndBlockStore(log.NewTMLogger(new(bytes.Buffer))) defer cleanup() require.Equal(t, bs.Height(), int64(0), "initially the height should be zero") @@ -325,6 +331,8 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) { } func TestLoadBlockPart(t *testing.T) { + t.Parallel() + bs, db := freshBlockStore() height, index := int64(10), 1 loadPart := func() (interface{}, error) { @@ -354,6 +362,8 @@ func TestLoadBlockPart(t *testing.T) { } func TestLoadBlockMeta(t *testing.T) { + t.Parallel() + bs, db := freshBlockStore() height := int64(10) loadMeta := func() (interface{}, error) { @@ -384,6 +394,8 @@ func TestLoadBlockMeta(t *testing.T) { } func TestBlockFetchAtHeight(t *testing.T) { + t.Parallel() + state, bs, cleanup := makeStateAndBlockStore(log.NewTMLogger(new(bytes.Buffer))) defer cleanup() require.Equal(t, bs.Height(), int64(0), "initially the height should be zero") diff --git a/tm2/pkg/bft/types/block_test.go b/tm2/pkg/bft/types/block_test.go index 5b49e0c392e..3963378436b 100644 --- a/tm2/pkg/bft/types/block_test.go +++ b/tm2/pkg/bft/types/block_test.go @@ -21,6 +21,8 @@ import ( ) func TestBlockValidateBasic(t *testing.T) { + t.Parallel() + require.Error(t, (*Block)(nil).ValidateBasic()) txs := []Tx{Tx("foo"), Tx("bar")} @@ -57,6 +59,8 @@ func TestBlockValidateBasic(t *testing.T) { tc := tc i := i t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + block := MakeBlock(h, txs, commit) block.ProposerAddress = valSet.GetProposer().Address tc.malleateBlock(block) @@ -67,11 +71,15 @@ func TestBlockValidateBasic(t *testing.T) { } func TestBlockHash(t *testing.T) { + t.Parallel() + assert.Nil(t, (*Block)(nil).Hash()) assert.Nil(t, MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).Hash()) } func TestBlockMakePartSet(t *testing.T) { + t.Parallel() + assert.Nil(t, (*Block)(nil).MakePartSet(2)) partSet := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).MakePartSet(1024) @@ -80,6 +88,8 @@ func TestBlockMakePartSet(t *testing.T) { } func TestBlockHashesTo(t *testing.T) { + t.Parallel() + assert.False(t, (*Block)(nil).HashesTo(nil)) lastID := makeBlockIDRandom() @@ -96,6 +106,8 @@ func TestBlockHashesTo(t *testing.T) { } func TestBlockSize(t *testing.T) { + t.Parallel() + size := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).Size() if size <= 0 { t.Fatal("Size of the block is zero or negative") @@ -103,6 +115,8 @@ func TestBlockSize(t *testing.T) { } func TestBlockString(t *testing.T) { + t.Parallel() + assert.Equal(t, "nil-Block", (*Block)(nil).String()) assert.Equal(t, "nil-Block", (*Block)(nil).StringIndented("")) assert.Equal(t, "nil-Block", (*Block)(nil).StringShort()) @@ -135,16 +149,22 @@ func makeBlockID(hash []byte, partSetSize int, partSetHash []byte) BlockID { var nilBytes []byte func TestNilHeaderHashDoesntCrash(t *testing.T) { + t.Parallel() + assert.Equal(t, (*Header)(nil).Hash(), nilBytes) assert.Equal(t, (new(Header)).Hash(), nilBytes) } func TestNilDataHashDoesntCrash(t *testing.T) { + t.Parallel() + assert.Equal(t, (*Data)(nil).Hash(), nilBytes) assert.Equal(t, new(Data).Hash(), nilBytes) } func TestCommit(t *testing.T) { + t.Parallel() + lastID := makeBlockIDRandom() h := int64(3) voteSet, _, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1) @@ -166,6 +186,8 @@ func TestCommit(t *testing.T) { } func TestCommitValidateBasic(t *testing.T) { + t.Parallel() + testCases := []struct { testName string malleateCommit func(*Commit) @@ -181,6 +203,8 @@ func TestCommitValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + com := randCommit() tc.malleateCommit(com) assert.Equal(t, tc.expectErr, com.ValidateBasic() != nil, "Validate Basic had an unexpected result") @@ -189,6 +213,8 @@ func TestCommitValidateBasic(t *testing.T) { } func TestHeaderByteSize(t *testing.T) { + t.Parallel() + // Construct a UTF-8 string of MaxChainIDLen length using the supplementary // characters. // Each supplementary character takes 4 bytes. @@ -239,6 +265,8 @@ func randCommit() *Commit { } func TestCommitToVoteSet(t *testing.T) { + t.Parallel() + lastID := makeBlockIDRandom() h := int64(3) @@ -263,6 +291,8 @@ func TestCommitToVoteSet(t *testing.T) { } func TestCommitToVoteSetWithVotesForAnotherBlockOrNilBlock(t *testing.T) { + t.Parallel() + blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash")) blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash")) blockID3 := makeBlockID([]byte("blockhash3"), 10000, []byte("partshash")) @@ -320,6 +350,8 @@ func TestCommitToVoteSetWithVotesForAnotherBlockOrNilBlock(t *testing.T) { } func TestSignedHeaderValidateBasic(t *testing.T) { + t.Parallel() + commit := randCommit() chainID := "𠜎" timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) @@ -360,6 +392,8 @@ func TestSignedHeaderValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + sh := SignedHeader{ Header: tc.shHeader, Commit: tc.shCommit, @@ -370,6 +404,8 @@ func TestSignedHeaderValidateBasic(t *testing.T) { } func TestBlockIDValidateBasic(t *testing.T) { + t.Parallel() + validBlockID := BlockID{ Hash: []byte{}, PartsHeader: PartSetHeader{ @@ -400,6 +436,8 @@ func TestBlockIDValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + blockID := BlockID{ Hash: tc.blockIDHash, PartsHeader: tc.blockIDPartsHeader, diff --git a/tm2/pkg/bft/types/evidence_test.go b/tm2/pkg/bft/types/evidence_test.go index 4efc61f8be7..5c43c547b74 100644 --- a/tm2/pkg/bft/types/evidence_test.go +++ b/tm2/pkg/bft/types/evidence_test.go @@ -37,6 +37,8 @@ func makeVote(val PrivValidator, chainID string, valIndex int, height int64, rou } func TestEvidence(t *testing.T) { + t.Parallel() + val := NewMockPV() val2 := NewMockPV() @@ -83,6 +85,8 @@ func TestEvidence(t *testing.T) { } func TestDuplicatedVoteEvidence(t *testing.T) { + t.Parallel() + ev := randomDuplicatedVoteEvidence() assert.True(t, ev.Equal(ev)) @@ -90,6 +94,8 @@ func TestDuplicatedVoteEvidence(t *testing.T) { } func TestEvidenceList(t *testing.T) { + t.Parallel() + ev := randomDuplicatedVoteEvidence() evl := EvidenceList([]Evidence{ev}) @@ -99,6 +105,8 @@ func TestEvidenceList(t *testing.T) { } func TestEvidenceByteSize(t *testing.T) { + t.Parallel() + val := NewMockPV() blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) @@ -127,6 +135,8 @@ func randomDuplicatedVoteEvidence() *DuplicateVoteEvidence { } func TestDuplicateVoteEvidenceValidation(t *testing.T) { + t.Parallel() + val := NewMockPV() blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) @@ -151,6 +161,8 @@ func TestDuplicateVoteEvidenceValidation(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + ev := &DuplicateVoteEvidence{ PubKey: secp256k1.GenPrivKey().PubKey(), VoteA: makeVote(val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0x02, blockID), @@ -163,11 +175,15 @@ func TestDuplicateVoteEvidenceValidation(t *testing.T) { } func TestMockGoodEvidenceValidateBasic(t *testing.T) { + t.Parallel() + goodEvidence := NewMockGoodEvidence(int64(1), 1, crypto.AddressFromPreimage([]byte{1})) assert.Nil(t, goodEvidence.ValidateBasic()) } func TestMockBadEvidenceValidateBasic(t *testing.T) { + t.Parallel() + badEvidence := MockBadEvidence{MockGoodEvidence: NewMockGoodEvidence(int64(1), 1, crypto.AddressFromPreimage([]byte{1}))} assert.Nil(t, badEvidence.ValidateBasic()) } diff --git a/tm2/pkg/bft/types/genesis_test.go b/tm2/pkg/bft/types/genesis_test.go index f8d19324eb5..24c69c6a28e 100644 --- a/tm2/pkg/bft/types/genesis_test.go +++ b/tm2/pkg/bft/types/genesis_test.go @@ -14,6 +14,8 @@ import ( ) func TestGenesisBad(t *testing.T) { + t.Parallel() + // test some bad ones from raw json testCases := [][]byte{ {}, // empty @@ -37,6 +39,8 @@ func TestGenesisBad(t *testing.T) { } func TestGenesisGood(t *testing.T) { + t.Parallel() + // test a good one by raw json genDocBytes := []byte(`{"genesis_time":"0001-01-01T00:00:00Z","chain_id":"test-chain-QDKdJr","consensus_params":null,"validators":[{"pub_key":{"@type":"/tm.PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="},"power":"10","name":""}],"app_hash":"","app_state":{"@type":"/tm.MockAppState","account_owner":"Bob"}}`) _, err := GenesisDocFromJSON(genDocBytes) @@ -87,6 +91,8 @@ func TestGenesisGood(t *testing.T) { } func TestGenesisSaveAs(t *testing.T) { + t.Parallel() + tmpfile, err := os.CreateTemp("", "genesis") require.NoError(t, err) defer os.Remove(tmpfile.Name()) @@ -114,6 +120,8 @@ func TestGenesisSaveAs(t *testing.T) { } func TestGenesisValidatorHash(t *testing.T) { + t.Parallel() + genDoc := randomGenesisDoc() assert.NotEmpty(t, genDoc.ValidatorHash()) } diff --git a/tm2/pkg/bft/types/params_test.go b/tm2/pkg/bft/types/params_test.go index cb5f3244e8d..141a67b903c 100644 --- a/tm2/pkg/bft/types/params_test.go +++ b/tm2/pkg/bft/types/params_test.go @@ -16,6 +16,8 @@ var ( ) func TestConsensusParamsValidation(t *testing.T) { + t.Parallel() + testCases := []struct { params abci.ConsensusParams valid bool @@ -63,6 +65,8 @@ func makeParams( } func TestConsensusParamsHash(t *testing.T) { + t.Parallel() + params := []abci.ConsensusParams{ makeParams(4, 1024, 2, 10, valEd25519), makeParams(1, 1024, 4, 10, valEd25519), @@ -90,6 +94,8 @@ func TestConsensusParamsHash(t *testing.T) { } func TestConsensusParamsUpdate(t *testing.T) { + t.Parallel() + testCases := []struct { params abci.ConsensusParams updates abci.ConsensusParams diff --git a/tm2/pkg/bft/types/part_set_test.go b/tm2/pkg/bft/types/part_set_test.go index c4e30c89372..13ebb2f0bba 100644 --- a/tm2/pkg/bft/types/part_set_test.go +++ b/tm2/pkg/bft/types/part_set_test.go @@ -16,6 +16,8 @@ const ( ) func TestBasicPartSet(t *testing.T) { + t.Parallel() + // Construct random data of size partSize * 100 data := random.RandBytes(testPartSize * 100) partSet := NewPartSetFromData(data, testPartSize) @@ -61,6 +63,8 @@ func TestBasicPartSet(t *testing.T) { } func TestWrongProof(t *testing.T) { + t.Parallel() + // Construct random data of size partSize * 100 data := random.RandBytes(testPartSize * 100) partSet := NewPartSetFromData(data, testPartSize) @@ -86,6 +90,8 @@ func TestWrongProof(t *testing.T) { } func TestPartSetHeaderValidateBasic(t *testing.T) { + t.Parallel() + testCases := []struct { testName string malleatePartSetHeader func(*PartSetHeader) @@ -98,6 +104,8 @@ func TestPartSetHeaderValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + data := random.RandBytes(testPartSize * 100) ps := NewPartSetFromData(data, testPartSize) psHeader := ps.Header() @@ -108,6 +116,8 @@ func TestPartSetHeaderValidateBasic(t *testing.T) { } func TestPartValidateBasic(t *testing.T) { + t.Parallel() + testCases := []struct { testName string malleatePart func(*Part) @@ -128,6 +138,8 @@ func TestPartValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + data := random.RandBytes(testPartSize * 100) ps := NewPartSetFromData(data, testPartSize) part := ps.GetPart(0) diff --git a/tm2/pkg/bft/types/proposal_test.go b/tm2/pkg/bft/types/proposal_test.go index ebda33298d1..0692e9bdd6f 100644 --- a/tm2/pkg/bft/types/proposal_test.go +++ b/tm2/pkg/bft/types/proposal_test.go @@ -29,6 +29,8 @@ func init() { } func TestProposalSignable(t *testing.T) { + t.Parallel() + chainID := "test_chain_id" signBytes := testProposal.SignBytes(chainID) @@ -38,6 +40,8 @@ func TestProposalSignable(t *testing.T) { } func TestProposalString(t *testing.T) { + t.Parallel() + str := testProposal.String() expected := `Proposal{12345/23456 (010203:111:626C6F636B70, -1) 000000000000 @ 2018-02-11T07:09:22.765Z}` if str != expected { @@ -46,6 +50,8 @@ func TestProposalString(t *testing.T) { } func TestProposalVerifySignature(t *testing.T) { + t.Parallel() + privVal := NewMockPV() pubKey := privVal.GetPubKey() @@ -104,6 +110,8 @@ func BenchmarkProposalVerifySignature(b *testing.B) { } func TestProposalValidateBasic(t *testing.T) { + t.Parallel() + privVal := NewMockPV() testCases := []struct { testName string @@ -130,6 +138,8 @@ func TestProposalValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + prop := NewProposal( 4, 2, 2, blockID) diff --git a/tm2/pkg/bft/types/results_test.go b/tm2/pkg/bft/types/results_test.go index 6db7044f6ad..6b375413ac6 100644 --- a/tm2/pkg/bft/types/results_test.go +++ b/tm2/pkg/bft/types/results_test.go @@ -10,6 +10,8 @@ import ( ) func TestABCIResults(t *testing.T) { + t.Parallel() + a := ABCIResult{Error: nil, Data: nil} b := ABCIResult{Error: nil, Data: []byte{}} c := ABCIResult{Error: nil, Data: []byte("one")} @@ -46,6 +48,8 @@ func TestABCIResults(t *testing.T) { } func TestABCIResultsBytes(t *testing.T) { + t.Parallel() + results := NewResults([]abci.ResponseDeliverTx{ {ResponseBase: abci.ResponseBase{Error: nil, Data: []byte{}}}, {ResponseBase: abci.ResponseBase{Error: nil, Data: []byte("one")}}, diff --git a/tm2/pkg/bft/types/time/time_test.go b/tm2/pkg/bft/types/time/time_test.go index 1b1a30e5058..bf53e313fef 100644 --- a/tm2/pkg/bft/types/time/time_test.go +++ b/tm2/pkg/bft/types/time/time_test.go @@ -8,6 +8,8 @@ import ( ) func TestWeightedMedian(t *testing.T) { + t.Parallel() + m := make([]*WeightedTime, 3) t1 := Now() diff --git a/tm2/pkg/bft/types/tx_test.go b/tm2/pkg/bft/types/tx_test.go index 1470fab024d..375783f874f 100644 --- a/tm2/pkg/bft/types/tx_test.go +++ b/tm2/pkg/bft/types/tx_test.go @@ -25,6 +25,8 @@ func randInt(low, high int) int { } func TestTxIndex(t *testing.T) { + t.Parallel() + for i := 0; i < 20; i++ { txs := makeTxs(15, 60) for j := 0; j < len(txs); j++ { @@ -38,6 +40,8 @@ func TestTxIndex(t *testing.T) { } func TestTxIndexByHash(t *testing.T) { + t.Parallel() + for i := 0; i < 20; i++ { txs := makeTxs(15, 60) for j := 0; j < len(txs); j++ { @@ -51,6 +55,8 @@ func TestTxIndexByHash(t *testing.T) { } func TestValidTxProof(t *testing.T) { + t.Parallel() + cases := []struct { txs Txs }{ @@ -90,6 +96,8 @@ func TestValidTxProof(t *testing.T) { } func TestTxProofUnchangable(t *testing.T) { + t.Parallel() + // run the other test a bunch... for i := 0; i < 40; i++ { testTxProofUnchangable(t) diff --git a/tm2/pkg/bft/types/validator_set_test.go b/tm2/pkg/bft/types/validator_set_test.go index a2c38026ed8..0fafb6fca9e 100644 --- a/tm2/pkg/bft/types/validator_set_test.go +++ b/tm2/pkg/bft/types/validator_set_test.go @@ -20,6 +20,8 @@ import ( ) func TestValidatorSetBasic(t *testing.T) { + t.Parallel() + // empty or nil validator lists are allowed, // but attempting to IncrementProposerPriority on them will panic. vset := NewValidatorSet([]*Validator{}) @@ -76,6 +78,8 @@ func TestValidatorSetBasic(t *testing.T) { } func TestCopy(t *testing.T) { + t.Parallel() + vset := randValidatorSet(10) vsetHash := vset.Hash() if len(vsetHash) == 0 { @@ -92,6 +96,8 @@ func TestCopy(t *testing.T) { // Test that IncrementProposerPriority requires positive times. func TestIncrementProposerPriorityPositiveTimes(t *testing.T) { + t.Parallel() + vset := NewValidatorSet([]*Validator{ newValidator([]byte("foo"), 1000), newValidator([]byte("bar"), 300), @@ -122,9 +128,11 @@ func BenchmarkValidatorSetCopy(b *testing.B) { } } -//------------------------------------------------------------------- +// ------------------------------------------------------------------- func TestProposerSelection1(t *testing.T) { + t.Parallel() + vset := NewValidatorSet([]*Validator{ newValidator([]byte("foo"), 1000), newValidator([]byte("bar"), 300), @@ -143,6 +151,8 @@ func TestProposerSelection1(t *testing.T) { } func TestProposerSelection2(t *testing.T) { + t.Parallel() + addr0 := []byte{1} addr1 := []byte{2} addr2 := []byte{3} @@ -217,6 +227,8 @@ func TestProposerSelection2(t *testing.T) { } func TestProposerSelection3(t *testing.T) { + t.Parallel() + vset := NewValidatorSet([]*Validator{ newValidator([]byte("a"), 1), newValidator([]byte("b"), 1), @@ -321,9 +333,11 @@ func (vals *ValidatorSet) fromBytes(b []byte) { } } -//------------------------------------------------------------------- +// ------------------------------------------------------------------- func TestValidatorSetTotalVotingPowerPanicsOnOverflow(t *testing.T) { + t.Parallel() + // NewValidatorSet calls IncrementProposerPriority which calls TotalVotingPower() // which should panic on overflows: shouldPanic := func() { @@ -338,6 +352,8 @@ func TestValidatorSetTotalVotingPowerPanicsOnOverflow(t *testing.T) { } func TestAvgProposerPriority(t *testing.T) { + t.Parallel() + // Create Validator set without calling IncrementProposerPriority: tcs := []struct { vs ValidatorSet @@ -356,6 +372,8 @@ func TestAvgProposerPriority(t *testing.T) { } func TestAveragingInIncrementProposerPriority(t *testing.T) { + t.Parallel() + // Test that the averaging works as expected inside of IncrementProposerPriority. // Each validator comes with zero voting power which simplifies reasoning about // the expected ProposerPriority. @@ -408,6 +426,8 @@ func TestAveragingInIncrementProposerPriority(t *testing.T) { } func TestAveragingInIncrementProposerPriorityWithVotingPower(t *testing.T) { + t.Parallel() + // Other than TestAveragingInIncrementProposerPriority this is a more complete test showing // how each ProposerPriority changes in relation to the validator's voting power respectively. // average is zero in each round: @@ -558,6 +578,8 @@ func TestAveragingInIncrementProposerPriorityWithVotingPower(t *testing.T) { } func TestSafeAdd(t *testing.T) { + t.Parallel() + f := func(a, b int64) bool { c, overflow := safeAdd(a, b) return overflow || (!overflow && c == a+b) @@ -568,21 +590,27 @@ func TestSafeAdd(t *testing.T) { } func TestSafeAddClip(t *testing.T) { + t.Parallel() + assert.EqualValues(t, math.MaxInt64, safeAddClip(math.MaxInt64, 10)) assert.EqualValues(t, math.MaxInt64, safeAddClip(math.MaxInt64, math.MaxInt64)) assert.EqualValues(t, math.MinInt64, safeAddClip(math.MinInt64, -10)) } func TestSafeSubClip(t *testing.T) { + t.Parallel() + assert.EqualValues(t, math.MinInt64, safeSubClip(math.MinInt64, 10)) assert.EqualValues(t, 0, safeSubClip(math.MinInt64, math.MinInt64)) assert.EqualValues(t, math.MinInt64, safeSubClip(math.MinInt64, math.MaxInt64)) assert.EqualValues(t, math.MaxInt64, safeSubClip(math.MaxInt64, -10)) } -//------------------------------------------------------------------- +// ------------------------------------------------------------------- func TestValidatorSetVerifyCommit(t *testing.T) { + t.Parallel() + privKey := mock.GenPrivKey() pubKey := privKey.PubKey() v1 := NewValidator(pubKey, 1000) @@ -635,6 +663,8 @@ func TestValidatorSetVerifyCommit(t *testing.T) { } func TestEmptySet(t *testing.T) { + t.Parallel() + var valList []*Validator valSet := NewValidatorSet(valList) assert.Panics(t, func() { valSet.IncrementProposerPriority(1) }) @@ -661,6 +691,8 @@ func TestEmptySet(t *testing.T) { } func TestUpdatesForNewValidatorSet(t *testing.T) { + t.Parallel() + v1 := newValidator([]byte("v1"), 100) v2 := newValidator([]byte("v2"), 100) valList := []*Validator{v1, v2} @@ -793,6 +825,8 @@ func executeValSetErrTestCase(t *testing.T, idx int, tt valSetErrTestCase) { } func TestValSetUpdatesDuplicateEntries(t *testing.T) { + t.Parallel() + testCases := []valSetErrTestCase{ // Duplicate entries in changes { // first entry is duplicated change @@ -850,6 +884,8 @@ func TestValSetUpdatesDuplicateEntries(t *testing.T) { } func TestValSetUpdatesOverflows(t *testing.T) { + t.Parallel() + maxVP := MaxTotalVotingPower testCases := []valSetErrTestCase{ { // single update leading to overflow @@ -884,6 +920,8 @@ func TestValSetUpdatesOverflows(t *testing.T) { } func TestValSetUpdatesOtherErrors(t *testing.T) { + t.Parallel() + testCases := []valSetErrTestCase{ { // update with negative voting power testValSet(2, 10), @@ -909,6 +947,8 @@ func TestValSetUpdatesOtherErrors(t *testing.T) { } func TestValSetUpdatesBasicTestsExecute(t *testing.T) { + t.Parallel() + valSetUpdatesBasicTests := []struct { startVals []testVal updateVals []testVal @@ -970,6 +1010,8 @@ func TestValSetUpdatesBasicTestsExecute(t *testing.T) { // Test that different permutations of an update give the same result. func TestValSetUpdatesOrderIndependenceTestsExecute(t *testing.T) { + t.Parallel() + // startVals - initial validators to create the set with // updateVals - a sequence of updates to be applied to the set. // updateVals is shuffled a number of times during testing to check for same resulting validator set. @@ -1031,6 +1073,8 @@ func TestValSetUpdatesOrderIndependenceTestsExecute(t *testing.T) { // This tests the private function validator_set.go:applyUpdates() function, used only for additions and changes. // Should perform a proper merge of updatedVals and startVals func TestValSetApplyUpdatesTestsExecute(t *testing.T) { + t.Parallel() + valSetUpdatesBasicTests := []struct { startVals []testVal updateVals []testVal @@ -1174,6 +1218,8 @@ func applyChangesToValSet(t *testing.T, valSet *ValidatorSet, valsLists ...[]tes } func TestValSetUpdatePriorityOrderTests(t *testing.T) { + t.Parallel() + const nMaxElections = 5000 testCases := []testVSetCfg{ diff --git a/tm2/pkg/bft/types/vote_set_test.go b/tm2/pkg/bft/types/vote_set_test.go index e3199f83edc..ca5639f2406 100644 --- a/tm2/pkg/bft/types/vote_set_test.go +++ b/tm2/pkg/bft/types/vote_set_test.go @@ -61,6 +61,8 @@ func withBlockPartsHeader(vote *Vote, blockPartsHeader PartSetHeader) *Vote { } func TestAddVote(t *testing.T) { + t.Parallel() + height, round := int64(1), 0 voteSet, _, privValidators := randVoteSet(height, round, PrevoteType, 10, 1) val0 := privValidators[0] @@ -106,6 +108,8 @@ func TestAddVote(t *testing.T) { } func Test2_3Majority(t *testing.T) { + t.Parallel() + height, round := int64(1), 0 voteSet, _, privValidators := randVoteSet(height, round, PrevoteType, 10, 1) @@ -162,6 +166,8 @@ func Test2_3Majority(t *testing.T) { } func Test2_3MajorityRedux(t *testing.T) { + t.Parallel() + height, round := int64(1), 0 voteSet, _, privValidators := randVoteSet(height, round, PrevoteType, 100, 1) @@ -267,6 +273,8 @@ func Test2_3MajorityRedux(t *testing.T) { } func TestBadVotes(t *testing.T) { + t.Parallel() + height, round := int64(1), 0 voteSet, _, privValidators := randVoteSet(height, round, PrevoteType, 10, 1) @@ -332,6 +340,8 @@ func TestBadVotes(t *testing.T) { } func TestConflicts(t *testing.T) { + t.Parallel() + height, round := int64(1), 0 voteSet, _, privValidators := randVoteSet(height, round, PrevoteType, 4, 1) blockHash1 := random.RandBytes(32) @@ -465,6 +475,8 @@ func TestConflicts(t *testing.T) { } func TestMakeCommit(t *testing.T) { + t.Parallel() + height, round := int64(1), 0 voteSet, _, privValidators := randVoteSet(height, round, PrecommitType, 10, 1) blockHash, blockPartsHeader := crypto.CRandBytes(32), PartSetHeader{123, crypto.CRandBytes(32)} diff --git a/tm2/pkg/bft/types/vote_test.go b/tm2/pkg/bft/types/vote_test.go index 1028694ebc5..8b34e474fbd 100644 --- a/tm2/pkg/bft/types/vote_test.go +++ b/tm2/pkg/bft/types/vote_test.go @@ -50,6 +50,8 @@ func exampleVote(t byte) *Vote { // This test will fail and can be removed once CommitSig contains only sigs and // timestamps. func TestVoteEncoding(t *testing.T) { + t.Parallel() + vote := examplePrecommit() commitSig := vote.CommitSig() bz1 := amino.MustMarshal(vote) @@ -58,6 +60,8 @@ func TestVoteEncoding(t *testing.T) { } func TestVoteSignable(t *testing.T) { + t.Parallel() + vote := examplePrecommit() signBytes := vote.SignBytes("test_chain_id") @@ -68,6 +72,8 @@ func TestVoteSignable(t *testing.T) { } func TestVoteSignBytesTestVectors(t *testing.T) { + t.Parallel() + tests := []struct { chainID string vote *Vote @@ -147,6 +153,8 @@ func TestVoteSignBytesTestVectors(t *testing.T) { } func TestVoteProposalNotEq(t *testing.T) { + t.Parallel() + cv := CanonicalizeVote("", &Vote{Height: 1, Round: 1}) p := CanonicalizeProposal("", &Proposal{Height: 1, Round: 1}) vb, err := amino.MarshalSized(cv) @@ -157,6 +165,8 @@ func TestVoteProposalNotEq(t *testing.T) { } func TestVoteVerifySignature(t *testing.T) { + t.Parallel() + privVal := NewMockPV() pubkey := privVal.GetPubKey() @@ -186,6 +196,8 @@ func TestVoteVerifySignature(t *testing.T) { } func TestIsVoteTypeValid(t *testing.T) { + t.Parallel() + tc := []struct { name string in SignedMsgType @@ -199,6 +211,8 @@ func TestIsVoteTypeValid(t *testing.T) { for _, tt := range tc { tt := tt t.Run(tt.name, func(st *testing.T) { + st.Parallel() + if rs := IsVoteTypeValid(tt.in); rs != tt.out { t.Errorf("Got unexpected Vote type. Expected:\n%v\nGot:\n%v", rs, tt.out) } @@ -207,6 +221,8 @@ func TestIsVoteTypeValid(t *testing.T) { } func TestVoteVerify(t *testing.T) { + t.Parallel() + privVal := NewMockPV() pubkey := privVal.GetPubKey() @@ -225,6 +241,8 @@ func TestVoteVerify(t *testing.T) { } func TestMaxVoteBytes(t *testing.T) { + t.Parallel() + // time is varint encoded so need to pick the max. // year int, month Month, day, hour, min, sec, nsec int, loc *Location timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) @@ -256,6 +274,8 @@ func TestMaxVoteBytes(t *testing.T) { } func TestVoteString(t *testing.T) { + t.Parallel() + str := examplePrecommit().String() expected := `Vote{56789:6AF1F4111082 12345/02/2(Precommit) 8B01023386C3 000000000000 @ 2017-12-25T03:00:01.234Z}` if str != expected { @@ -270,6 +290,8 @@ func TestVoteString(t *testing.T) { } func TestVoteValidateBasic(t *testing.T) { + t.Parallel() + privVal := NewMockPV() testCases := []struct { @@ -289,6 +311,8 @@ func TestVoteValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + vote := examplePrecommit() err := privVal.SignVote("test_chain_id", vote) require.NoError(t, err) diff --git a/tm2/pkg/bft/wal/wal_test.go b/tm2/pkg/bft/wal/wal_test.go index a1a3e831a79..322ee82bc2b 100644 --- a/tm2/pkg/bft/wal/wal_test.go +++ b/tm2/pkg/bft/wal/wal_test.go @@ -39,6 +39,8 @@ var _ = amino.RegisterPackage(amino.NewPackage( )) func TestWALWriterReader(t *testing.T) { + t.Parallel() + now := tmtime.Now() msgs := []TimedWALMessage{ {Time: now, Msg: TestMessage{Duration: time.Second, Height: 1, Round: 1}}, @@ -96,6 +98,8 @@ func makeTempWAL(t *testing.T, maxMsgSize int64, walChunkSize int64) (wal *baseW } func TestWALWrite(t *testing.T) { + t.Parallel() + // Create WAL const walChunkSize = 100000 wal := makeTempWAL(t, maxTestMsgSize, walChunkSize) @@ -119,6 +123,8 @@ func TestWALWrite(t *testing.T) { } func TestWALSearchForHeight(t *testing.T) { + t.Parallel() + // Create WAL const numHeight, numRounds, dataSize = 100, 10000, 10 const walChunkSize = 100000 @@ -161,6 +167,8 @@ func TestWALSearchForHeight(t *testing.T) { } func TestWALPeriodicSync(t *testing.T) { + t.Parallel() + // Create WAL const numHeight, numRounds, dataSize = 100, 10000, 10 const walChunkSize = 100000 diff --git a/tm2/pkg/bitarray/bit_array_test.go b/tm2/pkg/bitarray/bit_array_test.go index a70de110790..614d56d22cc 100644 --- a/tm2/pkg/bitarray/bit_array_test.go +++ b/tm2/pkg/bitarray/bit_array_test.go @@ -28,6 +28,8 @@ func randBitArray(bits int) (*BitArray, []byte) { } func TestAnd(t *testing.T) { + t.Parallel() + bA1, _ := randBitArray(51) bA2, _ := randBitArray(31) bA3 := bA1.And(bA2) @@ -52,6 +54,8 @@ func TestAnd(t *testing.T) { } func TestOr(t *testing.T) { + t.Parallel() + bA1, _ := randBitArray(51) bA2, _ := randBitArray(31) bA3 := bA1.Or(bA2) @@ -76,6 +80,8 @@ func TestOr(t *testing.T) { } func TestSub(t *testing.T) { + t.Parallel() + testCases := []struct { initBA string subtractingBA string @@ -107,6 +113,8 @@ func TestSub(t *testing.T) { } func TestPickRandom(t *testing.T) { + t.Parallel() + empty16Bits := "________________" empty64Bits := empty16Bits + empty16Bits + empty16Bits + empty16Bits testCases := []struct { @@ -134,6 +142,8 @@ func TestPickRandom(t *testing.T) { } func TestBytes(t *testing.T) { + t.Parallel() + bA := NewBitArray(4) bA.SetIndex(0, true) check := func(bA *BitArray, bz []byte) { @@ -163,6 +173,8 @@ func TestBytes(t *testing.T) { } func TestEmptyFull(t *testing.T) { + t.Parallel() + ns := []int{47, 123} for _, n := range ns { bA := NewBitArray(n) @@ -179,6 +191,8 @@ func TestEmptyFull(t *testing.T) { } func TestUpdateNeverPanics(t *testing.T) { + t.Parallel() + newRandBitArray := func(n int) *BitArray { ba, _ := randBitArray(n) return ba @@ -201,6 +215,8 @@ func TestUpdateNeverPanics(t *testing.T) { } func TestNewBitArrayNeverCrashesOnNegatives(t *testing.T) { + t.Parallel() + bitList := []int{-127, -128, -1 << 31} for _, bits := range bitList { _ = NewBitArray(bits) @@ -208,6 +224,8 @@ func TestNewBitArrayNeverCrashesOnNegatives(t *testing.T) { } func TestJSONMarshalUnmarshal(t *testing.T) { + t.Parallel() + bA1 := NewBitArray(0) bA2 := NewBitArray(1) @@ -233,6 +251,8 @@ func TestJSONMarshalUnmarshal(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.bA.String(), func(t *testing.T) { + t.Parallel() + bz, err := json.Marshal(tc.bA) require.NoError(t, err) diff --git a/tm2/pkg/clist/clist_test.go b/tm2/pkg/clist/clist_test.go index 496966d2d61..2cef3ef847f 100644 --- a/tm2/pkg/clist/clist_test.go +++ b/tm2/pkg/clist/clist_test.go @@ -2,8 +2,6 @@ package clist import ( "fmt" - "runtime" - "sync/atomic" "testing" "time" @@ -12,6 +10,8 @@ import ( ) func TestPanicOnMaxLength(t *testing.T) { + t.Parallel() + maxLength := 1000 l := newWithMax(maxLength) @@ -24,6 +24,8 @@ func TestPanicOnMaxLength(t *testing.T) { } func TestSmall(t *testing.T) { + t.Parallel() + l := New() el1 := l.PushBack(1) el2 := l.PushBack(2) @@ -64,110 +66,9 @@ func TestSmall(t *testing.T) { } } -// This test is quite hacky because it relies on SetFinalizer -// which isn't guaranteed to run at all. -// -//nolint:unused,deadcode -func _TestGCFifo(t *testing.T) { - t.Helper() - - if runtime.GOARCH != "amd64" { - t.Skipf("Skipping on non-amd64 machine") - } - - const numElements = 1000000 - l := New() - gcCount := new(uint64) - - // SetFinalizer doesn't work well with circular structures, - // so we construct a trivial non-circular structure to - // track. - type value struct { - Int int - } - done := make(chan struct{}) - - for i := 0; i < numElements; i++ { - v := new(value) - v.Int = i - l.PushBack(v) - runtime.SetFinalizer(v, func(v *value) { - atomic.AddUint64(gcCount, 1) - }) - } - - for el := l.Front(); el != nil; { - l.Remove(el) - // oldEl := el - el = el.Next() - // oldEl.DetachPrev() - // oldEl.DetachNext() - } - - runtime.GC() - time.Sleep(time.Second * 3) - runtime.GC() - time.Sleep(time.Second * 3) - _ = done - - if *gcCount != numElements { - t.Errorf("Expected gcCount to be %v, got %v", numElements, - *gcCount) - } -} - -// This test is quite hacky because it relies on SetFinalizer -// which isn't guaranteed to run at all. -// -//nolint:unused,deadcode -func _TestGCRandom(t *testing.T) { - t.Helper() - - if runtime.GOARCH != "amd64" { - t.Skipf("Skipping on non-amd64 machine") - } - - const numElements = 1000000 - l := New() - gcCount := 0 - - // SetFinalizer doesn't work well with circular structures, - // so we construct a trivial non-circular structure to - // track. - type value struct { - Int int - } - - for i := 0; i < numElements; i++ { - v := new(value) - v.Int = i - l.PushBack(v) - runtime.SetFinalizer(v, func(v *value) { - gcCount++ - }) - } - - els := make([]*CElement, 0, numElements) - for el := l.Front(); el != nil; el = el.Next() { - els = append(els, el) - } - - for _, i := range random.RandPerm(numElements) { - el := els[i] - l.Remove(el) - _ = el.Next() - } - - runtime.GC() - time.Sleep(time.Second * 3) - - if gcCount != numElements { - t.Errorf("Expected gcCount to be %v, got %v", numElements, - gcCount) - } -} - func TestScanRightDeleteRandom(t *testing.T) { + t.Parallel() + const numElements = 1000 const numTimes = 100 const numScanners = 10 @@ -239,6 +140,8 @@ func TestScanRightDeleteRandom(t *testing.T) { } func TestWaitChan(t *testing.T) { + t.Parallel() + l := New() ch := l.WaitChan() diff --git a/tm2/pkg/cmap/cmap_test.go b/tm2/pkg/cmap/cmap_test.go index e0fc5a5dc4e..d9051ea18d6 100644 --- a/tm2/pkg/cmap/cmap_test.go +++ b/tm2/pkg/cmap/cmap_test.go @@ -9,6 +9,8 @@ import ( ) func TestIterateKeysWithValues(t *testing.T) { + t.Parallel() + cmap := NewCMap() for i := 1; i <= 10; i++ { @@ -39,6 +41,8 @@ func TestIterateKeysWithValues(t *testing.T) { } func TestContains(t *testing.T) { + t.Parallel() + cmap := NewCMap() cmap.Set("key1", "value1") diff --git a/tm2/pkg/commands/commands_test.go b/tm2/pkg/commands/commands_test.go index 96802b9d720..4879e667cf5 100644 --- a/tm2/pkg/commands/commands_test.go +++ b/tm2/pkg/commands/commands_test.go @@ -26,6 +26,8 @@ func (c *mockConfig) RegisterFlags(fs *flag.FlagSet) { } func TestCommandParseAndRun(t *testing.T) { + t.Parallel() + type flags struct { b bool s string @@ -215,7 +217,10 @@ func TestCommandParseAndRun(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + var ( invokedCmd string args []string @@ -416,9 +421,7 @@ func TestCommand_AddSubCommands(t *testing.T) { // Forked from peterbourgon/ff/ffcli func TestHelpUsage(t *testing.T) { - fs, _ := fftest.Pair() - var buf bytes.Buffer - fs.SetOutput(&buf) + t.Parallel() tests := []struct { name string @@ -432,7 +435,6 @@ func TestHelpUsage(t *testing.T) { shortUsage: "TestHelpUsage [flags] ", shortHelp: "Some short help", longHelp: "Some long help.", - flagSet: fs, }, expectedOutput: strings.TrimSpace(` USAGE @@ -455,7 +457,6 @@ FLAGS name: "TestHelpUsage", shortUsage: "TestHelpUsage [flags] ", shortHelp: "Some short help", - flagSet: fs, }, expectedOutput: strings.TrimSpace(` USAGE @@ -477,7 +478,6 @@ FLAGS command: &Command{ name: "TestHelpUsage", shortUsage: "TestHelpUsage [flags] ", - flagSet: fs, }, expectedOutput: strings.TrimSpace(` USAGE @@ -494,8 +494,15 @@ FLAGS }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { - buf.Reset() + t.Parallel() + + fs, _ := fftest.Pair() + var buf bytes.Buffer + fs.SetOutput(&buf) + + tt.command.flagSet = fs err := tt.command.ParseAndRun(context.Background(), []string{"-h"}) @@ -507,6 +514,8 @@ FLAGS // Forked from peterbourgon/ff/ffcli func TestNestedOutput(t *testing.T) { + t.Parallel() + var ( rootHelpOutput = "USAGE\n \n\nSUBCOMMANDS\n foo\n\n" fooHelpOutput = "USAGE\n foo\n\nSUBCOMMANDS\n bar\n\n" @@ -572,6 +581,8 @@ func TestNestedOutput(t *testing.T) { }, } { t.Run(testcase.name, func(t *testing.T) { + t.Parallel() + var ( rootfs = flag.NewFlagSet("root", flag.ContinueOnError) foofs = flag.NewFlagSet("foo", flag.ContinueOnError) diff --git a/tm2/pkg/crypto/bcrypt/bcrypt_test.go b/tm2/pkg/crypto/bcrypt/bcrypt_test.go index 96634260d65..92b296bfe52 100644 --- a/tm2/pkg/crypto/bcrypt/bcrypt_test.go +++ b/tm2/pkg/crypto/bcrypt/bcrypt_test.go @@ -12,6 +12,8 @@ import ( ) func TestBcryptingIsEasy(t *testing.T) { + t.Parallel() + pass := []byte("mypassword") salt := []byte("1234567890123456") hp, err := GenerateFromPassword(salt, pass, 0) @@ -31,6 +33,8 @@ func TestBcryptingIsEasy(t *testing.T) { } func TestBcryptingIsCorrect(t *testing.T) { + t.Parallel() + pass := []byte("allmine") salt := []byte("XajjQvNhvvRt5GSeFk1xFe") expectedHash := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga") @@ -56,6 +60,8 @@ func TestBcryptingIsCorrect(t *testing.T) { } func TestVeryShortPasswords(t *testing.T) { + t.Parallel() + key := []byte("k") salt := []byte("XajjQvNhvvRt5GSeFk1xFe") _, err := bcrypt(key, 10, salt) @@ -65,6 +71,8 @@ func TestVeryShortPasswords(t *testing.T) { } func TestTooLongPasswordsWork(t *testing.T) { + t.Parallel() + salt := []byte("XajjQvNhvvRt5GSeFk1xFe") // One byte over the usual 56 byte limit that blowfish has tooLongPass := []byte("012345678901234567890123456789012345678901234567890123456") @@ -92,6 +100,8 @@ var invalidTests = []InvalidHashTest{ } func TestInvalidHashErrors(t *testing.T) { + t.Parallel() + check := func(name string, expected, err error) { if err == nil { t.Errorf("%s: Should have returned an error", name) @@ -109,6 +119,8 @@ func TestInvalidHashErrors(t *testing.T) { } func TestUnpaddedBase64Encoding(t *testing.T) { + t.Parallel() + original := []byte{101, 201, 101, 75, 19, 227, 199, 20, 239, 236, 133, 32, 30, 109, 243, 30} encodedOriginal := []byte("XajjQvNhvvRt5GSeFk1xFe") @@ -129,6 +141,8 @@ func TestUnpaddedBase64Encoding(t *testing.T) { } func TestCost(t *testing.T) { + t.Parallel() + suffix := "XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C" for _, vers := range []string{"2a", "2"} { for _, cost := range []int{4, 10} { @@ -151,6 +165,8 @@ func TestCost(t *testing.T) { } func TestCostValidationInHash(t *testing.T) { + t.Parallel() + if testing.Short() { return } @@ -185,6 +201,8 @@ func TestCostValidationInHash(t *testing.T) { } func TestCostReturnsWithLeadingZeroes(t *testing.T) { + t.Parallel() + salt := []byte("1234567890123456") hp, _ := newFromPassword(salt, []byte("abcdefgh"), 7) cost := hp.Hash()[4:7] @@ -196,6 +214,8 @@ func TestCostReturnsWithLeadingZeroes(t *testing.T) { } func TestMinorNotRequired(t *testing.T) { + t.Parallel() + noMinorHash := []byte("$2$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga") h, err := newFromHash(noMinorHash) if err != nil { @@ -233,6 +253,8 @@ func BenchmarkDefaultCost(b *testing.B) { // See Issue https://github.com/golang/go/issues/20425. func TestNoSideEffectsFromCompare(t *testing.T) { + t.Parallel() + source := []byte("passw0rd123456") password := source[:len(source)-6] token := source[len(source)-6:] diff --git a/tm2/pkg/crypto/bech32_test.go b/tm2/pkg/crypto/bech32_test.go index 13bdaa8e816..f5bc3e9ed7c 100644 --- a/tm2/pkg/crypto/bech32_test.go +++ b/tm2/pkg/crypto/bech32_test.go @@ -21,6 +21,8 @@ var invalidStrs = []string{ } func TestEmptyAddresses(t *testing.T) { + t.Parallel() + require.Equal(t, (crypto.Address{}).String(), "g1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqluuxe") addr := crypto.AddressFromBytes(make([]byte, 20)) @@ -47,6 +49,8 @@ func testMarshal(t *testing.T, addr crypto.Address, marshal func(orig interface{ } func TestRandBech32AddrConsistency(t *testing.T) { + t.Parallel() + var pub ed25519.PubKeyEd25519 for i := 0; i < 1000; i++ { diff --git a/tm2/pkg/crypto/bip39/bip39_test.go b/tm2/pkg/crypto/bip39/bip39_test.go index cbe15be6c3f..7854db76f53 100644 --- a/tm2/pkg/crypto/bip39/bip39_test.go +++ b/tm2/pkg/crypto/bip39/bip39_test.go @@ -14,6 +14,8 @@ type Vector struct { } func TestBip39(t *testing.T) { + t.Parallel() + for _, vector := range testVectors() { entropy, err := hex.DecodeString(vector.entropy) assert.NoError(t, err) @@ -31,6 +33,8 @@ func TestBip39(t *testing.T) { } func TestIsMnemonicValid(t *testing.T) { + t.Parallel() + for _, vector := range badMnemonicSentences() { assert.Equal(t, IsMnemonicValid(vector.mnemonic), false) } @@ -41,6 +45,8 @@ func TestIsMnemonicValid(t *testing.T) { } func TestInvalidMnemonicFails(t *testing.T) { + t.Parallel() + for _, vector := range badMnemonicSentences() { _, err := MnemonicToByteArray(vector.mnemonic) assert.NotNil(t, err) @@ -48,6 +54,8 @@ func TestInvalidMnemonicFails(t *testing.T) { } func TestValidateEntropyWithChecksumBitSize(t *testing.T) { + t.Parallel() + // Good tests. for i := 1; i <= (12*32 + 12); i++ { err := validateEntropyWithChecksumBitSize(i) @@ -74,6 +82,8 @@ func TestValidateEntropyWithChecksumBitSize(t *testing.T) { } func TestNewEntropy(t *testing.T) { + t.Parallel() + // Good tests. for i := 128; i <= 256; i += 32 { _, err := NewEntropy(i) diff --git a/tm2/pkg/crypto/ed25519/ed25519_test.go b/tm2/pkg/crypto/ed25519/ed25519_test.go index c07b7ae2298..fdf269018c0 100644 --- a/tm2/pkg/crypto/ed25519/ed25519_test.go +++ b/tm2/pkg/crypto/ed25519/ed25519_test.go @@ -10,6 +10,8 @@ import ( ) func TestSignAndValidateEd25519(t *testing.T) { + t.Parallel() + privKey := ed25519.GenPrivKey() pubKey := privKey.PubKey() diff --git a/tm2/pkg/crypto/hd/fundraiser_test.go b/tm2/pkg/crypto/hd/fundraiser_test.go index dabfd670c37..884425c6c39 100644 --- a/tm2/pkg/crypto/hd/fundraiser_test.go +++ b/tm2/pkg/crypto/hd/fundraiser_test.go @@ -43,6 +43,8 @@ func initFundraiserTestVectors(t *testing.T) []addrData { } func TestFundraiserCompatibility(t *testing.T) { + t.Parallel() + hdToAddrTable := initFundraiserTestVectors(t) for i, d := range hdToAddrTable { diff --git a/tm2/pkg/crypto/hd/hdpath_test.go b/tm2/pkg/crypto/hd/hdpath_test.go index 1e66a9fba2c..31e806b2b1a 100644 --- a/tm2/pkg/crypto/hd/hdpath_test.go +++ b/tm2/pkg/crypto/hd/hdpath_test.go @@ -34,6 +34,8 @@ const ( ) func TestStringifyFundraiserPathParams(t *testing.T) { + t.Parallel() + path := NewFundraiserParams(4, testCoinType, 22) require.Equal(t, "44'/118'/4'/0/22", path.String()) @@ -45,6 +47,8 @@ func TestStringifyFundraiserPathParams(t *testing.T) { } func TestPathToArray(t *testing.T) { + t.Parallel() + path := NewParams(44, 118, 1, false, 4) require.Equal(t, "[44 118 1 0 4]", fmt.Sprintf("%v", path.DerivationPath())) @@ -53,6 +57,8 @@ func TestPathToArray(t *testing.T) { } func TestParamsFromPath(t *testing.T) { + t.Parallel() + goodCases := []struct { params *BIP44Params path string diff --git a/tm2/pkg/crypto/keys/keybase_test.go b/tm2/pkg/crypto/keys/keybase_test.go index 987a271881b..cae5f2af947 100644 --- a/tm2/pkg/crypto/keys/keybase_test.go +++ b/tm2/pkg/crypto/keys/keybase_test.go @@ -12,6 +12,8 @@ import ( ) func TestCreateAccountInvalidMnemonic(t *testing.T) { + t.Parallel() + kb := NewInMemory() _, err := kb.CreateAccount( "some_account", @@ -22,6 +24,8 @@ func TestCreateAccountInvalidMnemonic(t *testing.T) { } func TestCreateLedgerUnsupportedAlgo(t *testing.T) { + t.Parallel() + kb := NewInMemory() _, err := kb.CreateLedger("some_account", Ed25519, "cosmos", 0, 1) assert.Error(t, err) @@ -29,6 +33,8 @@ func TestCreateLedgerUnsupportedAlgo(t *testing.T) { } func TestCreateLedger(t *testing.T) { + t.Parallel() + kb := NewInMemory() // test_cover and test_unit will result in different answers @@ -65,6 +71,8 @@ func TestCreateLedger(t *testing.T) { // TestKeyManagement makes sure we can manipulate these keys well func TestKeyManagement(t *testing.T) { + t.Parallel() + // make the storage with reasonable defaults cstore := NewInMemory() @@ -147,6 +155,8 @@ func TestKeyManagement(t *testing.T) { // TestSignVerify does some detailed checks on how we sign and validate // signatures func TestSignVerify(t *testing.T) { + t.Parallel() + cstore := NewInMemory() n1, n2, n3 := "some dude", "a dudette", "dude-ish" @@ -233,6 +243,8 @@ func assertPassword(t *testing.T, cstore Keybase, name, pass, badpass string) { // TestExportImport tests exporting and importing func TestExportImport(t *testing.T) { + t.Parallel() + // make the storage with reasonable defaults cstore := NewInMemory() @@ -263,6 +275,8 @@ func TestExportImport(t *testing.T) { } func TestExportImportPubKey(t *testing.T) { + t.Parallel() + // make the storage with reasonable defaults cstore := NewInMemory() @@ -304,6 +318,8 @@ func TestExportImportPubKey(t *testing.T) { // TestAdvancedKeyManagement verifies update, import, export functionality func TestAdvancedKeyManagement(t *testing.T) { + t.Parallel() + // make the storage with reasonable defaults cstore := NewInMemory() @@ -352,6 +368,8 @@ func TestAdvancedKeyManagement(t *testing.T) { // TestSeedPhrase verifies restoring from a seed phrase func TestSeedPhrase(t *testing.T) { + t.Parallel() + // make the storage with reasonable defaults cstore := NewInMemory() diff --git a/tm2/pkg/crypto/keys/types_test.go b/tm2/pkg/crypto/keys/types_test.go index a0591819a88..2a2dd2c82f6 100644 --- a/tm2/pkg/crypto/keys/types_test.go +++ b/tm2/pkg/crypto/keys/types_test.go @@ -11,6 +11,8 @@ import ( ) func Test_writeReadLedgerInfo(t *testing.T) { + t.Parallel() + var tmpKey secp256k1.PubKeySecp256k1 bz, _ := hex.DecodeString("035AD6810A47F073553FF30D2FCC7E0D3B1C0B74B61A1AAA2582344037151E143A") copy(tmpKey[:], bz) diff --git a/tm2/pkg/crypto/merkle/proof_key_path_test.go b/tm2/pkg/crypto/merkle/proof_key_path_test.go index 22e3e21ca3d..669e8c5630c 100644 --- a/tm2/pkg/crypto/merkle/proof_key_path_test.go +++ b/tm2/pkg/crypto/merkle/proof_key_path_test.go @@ -10,6 +10,8 @@ import ( ) func TestKeyPath(t *testing.T) { + t.Parallel() + var path KeyPath keys := make([][]byte, 10) alphanum := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" diff --git a/tm2/pkg/crypto/merkle/proof_test.go b/tm2/pkg/crypto/merkle/proof_test.go index 3319963ce6c..0424ea351dd 100644 --- a/tm2/pkg/crypto/merkle/proof_test.go +++ b/tm2/pkg/crypto/merkle/proof_test.go @@ -53,6 +53,8 @@ func (dop DominoOp) GetKey() []byte { // ---------------------------------------- func TestProofOperators(t *testing.T) { + t.Parallel() + var err error // ProofRuntime setup diff --git a/tm2/pkg/crypto/merkle/rfc6962_test.go b/tm2/pkg/crypto/merkle/rfc6962_test.go index 917b09015b0..57f72cea311 100644 --- a/tm2/pkg/crypto/merkle/rfc6962_test.go +++ b/tm2/pkg/crypto/merkle/rfc6962_test.go @@ -24,6 +24,8 @@ import ( ) func TestRFC6962Hasher(t *testing.T) { + t.Parallel() + _, leafHashTrail := trailsFromByteSlices([][]byte{[]byte("L123456")}) leafHash := leafHashTrail.Hash _, leafHashTrail = trailsFromByteSlices([][]byte{{}}) @@ -58,6 +60,8 @@ func TestRFC6962Hasher(t *testing.T) { } { tc := tc t.Run(tc.desc, func(t *testing.T) { + t.Parallel() + wantBytes, err := hex.DecodeString(tc.want) if err != nil { t.Fatalf("hex.DecodeString(%x): %v", tc.want, err) @@ -70,6 +74,8 @@ func TestRFC6962Hasher(t *testing.T) { } func TestRFC6962HasherCollisions(t *testing.T) { + t.Parallel() + // Check that different leaves have different hashes. leaf1, leaf2 := []byte("Hello"), []byte("World") _, leafHashTrail := trailsFromByteSlices([][]byte{leaf1}) diff --git a/tm2/pkg/crypto/merkle/simple_map_test.go b/tm2/pkg/crypto/merkle/simple_map_test.go index 366d9f39099..6df8e0b967e 100644 --- a/tm2/pkg/crypto/merkle/simple_map_test.go +++ b/tm2/pkg/crypto/merkle/simple_map_test.go @@ -8,6 +8,8 @@ import ( ) func TestSimpleMap(t *testing.T) { + t.Parallel() + tests := []struct { keys []string values []string // each string gets converted to []byte in test diff --git a/tm2/pkg/crypto/merkle/simple_proof_test.go b/tm2/pkg/crypto/merkle/simple_proof_test.go index 1a517905b5e..88677e3fb0e 100644 --- a/tm2/pkg/crypto/merkle/simple_proof_test.go +++ b/tm2/pkg/crypto/merkle/simple_proof_test.go @@ -7,6 +7,8 @@ import ( ) func TestSimpleProofValidateBasic(t *testing.T) { + t.Parallel() + testCases := []struct { testName string malleateProof func(*SimpleProof) @@ -23,6 +25,8 @@ func TestSimpleProofValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + _, proofs := SimpleProofsFromByteSlices([][]byte{ []byte("apple"), []byte("watermelon"), diff --git a/tm2/pkg/crypto/merkle/simple_tree_test.go b/tm2/pkg/crypto/merkle/simple_tree_test.go index 8690bae6ac3..209df75b1b5 100644 --- a/tm2/pkg/crypto/merkle/simple_tree_test.go +++ b/tm2/pkg/crypto/merkle/simple_tree_test.go @@ -17,6 +17,8 @@ func (tI testItem) Hash() []byte { } func TestSimpleProof(t *testing.T) { + t.Parallel() + total := 100 items := make([][]byte, total) @@ -69,6 +71,8 @@ func TestSimpleProof(t *testing.T) { } func TestSimpleHashAlternatives(t *testing.T) { + t.Parallel() + total := 100 items := make([][]byte, total) @@ -104,6 +108,8 @@ func BenchmarkSimpleHashAlternatives(b *testing.B) { } func Test_getSplitPoint(t *testing.T) { + t.Parallel() + tests := []struct { length int want int diff --git a/tm2/pkg/crypto/mock/mock_test.go b/tm2/pkg/crypto/mock/mock_test.go index 2e5f1d776bd..3d7ac571faa 100644 --- a/tm2/pkg/crypto/mock/mock_test.go +++ b/tm2/pkg/crypto/mock/mock_test.go @@ -10,6 +10,8 @@ import ( ) func TestSignAndValidateMock(t *testing.T) { + t.Parallel() + privKey := mock.PrivKeyMock([]byte{0x01}) pubKey := privKey.PubKey() diff --git a/tm2/pkg/crypto/multisig/bitarray/compact_bit_array_test.go b/tm2/pkg/crypto/multisig/bitarray/compact_bit_array_test.go index ecbfb64005d..c41e8e3c87b 100644 --- a/tm2/pkg/crypto/multisig/bitarray/compact_bit_array_test.go +++ b/tm2/pkg/crypto/multisig/bitarray/compact_bit_array_test.go @@ -28,6 +28,8 @@ func randCompactBitArray(bits int) (*CompactBitArray, []byte) { } func TestNewBitArrayNeverCrashesOnNegatives(t *testing.T) { + t.Parallel() + bitList := []int{-127, -128, -1 << 31} for _, bits := range bitList { bA := NewCompactBitArray(bits) @@ -36,6 +38,8 @@ func TestNewBitArrayNeverCrashesOnNegatives(t *testing.T) { } func TestJSONMarshalUnmarshal(t *testing.T) { + t.Parallel() + bA1 := NewCompactBitArray(0) bA2 := NewCompactBitArray(1) @@ -73,6 +77,8 @@ func TestJSONMarshalUnmarshal(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.bA.String(), func(t *testing.T) { + t.Parallel() + bz, err := json.Marshal(tc.bA) require.NoError(t, err) @@ -96,6 +102,8 @@ func TestJSONMarshalUnmarshal(t *testing.T) { } func TestCompactMarshalUnmarshal(t *testing.T) { + t.Parallel() + bA1 := NewCompactBitArray(0) bA2 := NewCompactBitArray(1) @@ -133,6 +141,8 @@ func TestCompactMarshalUnmarshal(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.bA.String(), func(t *testing.T) { + t.Parallel() + bz := tc.bA.CompactMarshal() assert.Equal(t, tc.marshalledBA, bz) @@ -153,6 +163,8 @@ func TestCompactMarshalUnmarshal(t *testing.T) { } func TestCompactBitArrayNumOfTrueBitsBefore(t *testing.T) { + t.Parallel() + testCases := []struct { marshalledBA string bAIndex []int @@ -169,6 +181,8 @@ func TestCompactBitArrayNumOfTrueBitsBefore(t *testing.T) { tc := tc tcIndex := tcIndex t.Run(tc.marshalledBA, func(t *testing.T) { + t.Parallel() + var bA *CompactBitArray err := json.Unmarshal([]byte(tc.marshalledBA), &bA) require.NoError(t, err) @@ -181,6 +195,8 @@ func TestCompactBitArrayNumOfTrueBitsBefore(t *testing.T) { } func TestCompactBitArrayGetSetIndex(t *testing.T) { + t.Parallel() + r := rand.New(rand.NewSource(100)) numTests := 10 numBitsPerArr := 100 diff --git a/tm2/pkg/crypto/multisig/threshold_pubkey_test.go b/tm2/pkg/crypto/multisig/threshold_pubkey_test.go index 9195344f423..548e8df0a82 100644 --- a/tm2/pkg/crypto/multisig/threshold_pubkey_test.go +++ b/tm2/pkg/crypto/multisig/threshold_pubkey_test.go @@ -15,6 +15,8 @@ import ( // This tests multisig functionality, but it expects the first k signatures to be valid // TODO: Adapt it to give more flexibility about first k signatures being valid func TestThresholdMultisigValidCases(t *testing.T) { + t.Parallel() + pkSet1, sigSet1 := generatePubKeysAndSignatures(5, []byte{1, 2, 3, 4}) cases := []struct { msg []byte @@ -105,6 +107,8 @@ func TestThresholdMultisigValidCases(t *testing.T) { // TODO: Fully replace this test with table driven tests func TestThresholdMultisigDuplicateSignatures(t *testing.T) { + t.Parallel() + msg := []byte{1, 2, 3, 4, 5} pubkeys, sigs := generatePubKeysAndSignatures(5, msg) multisigKey := NewPubKeyMultisigThreshold(2, pubkeys) @@ -118,6 +122,8 @@ func TestThresholdMultisigDuplicateSignatures(t *testing.T) { // TODO: Fully replace this test with table driven tests func TestMultiSigPubKeyEquality(t *testing.T) { + t.Parallel() + msg := []byte{1, 2, 3, 4} pubkeys, _ := generatePubKeysAndSignatures(5, msg) multisigKey := NewPubKeyMultisigThreshold(2, pubkeys) @@ -135,6 +141,8 @@ func TestMultiSigPubKeyEquality(t *testing.T) { } func TestAddress(t *testing.T) { + t.Parallel() + msg := []byte{1, 2, 3, 4} pubkeys, _ := generatePubKeysAndSignatures(5, msg) multisigKey := NewPubKeyMultisigThreshold(2, pubkeys) @@ -142,6 +150,8 @@ func TestAddress(t *testing.T) { } func TestPubKeyMultisigThresholdAminoToIface(t *testing.T) { + t.Parallel() + msg := []byte{1, 2, 3, 4} pubkeys, _ := generatePubKeysAndSignatures(5, msg) multisigKey := NewPubKeyMultisigThreshold(2, pubkeys) diff --git a/tm2/pkg/crypto/random_test.go b/tm2/pkg/crypto/random_test.go index aab505cb61c..dd405c06859 100644 --- a/tm2/pkg/crypto/random_test.go +++ b/tm2/pkg/crypto/random_test.go @@ -11,6 +11,8 @@ import ( // the purpose of this test is primarily to ensure that the randomness // generation won't error. func TestRandomConsistency(t *testing.T) { + t.Parallel() + x1 := crypto.CRandBytes(256) x2 := crypto.CRandBytes(256) x3 := crypto.CRandBytes(256) diff --git a/tm2/pkg/crypto/secp256k1/secp256k1_cgo_test.go b/tm2/pkg/crypto/secp256k1/secp256k1_cgo_test.go index e5b584707e5..d0070ad9bbe 100644 --- a/tm2/pkg/crypto/secp256k1/secp256k1_cgo_test.go +++ b/tm2/pkg/crypto/secp256k1/secp256k1_cgo_test.go @@ -10,6 +10,8 @@ import ( ) func TestPrivKeySecp256k1SignVerify(t *testing.T) { + t.Parallel() + msg := []byte("A.1.2 ECC Key Pair Generation by Testing Candidates") priv := GenPrivKey() tests := []struct { @@ -23,6 +25,8 @@ func TestPrivKeySecp256k1SignVerify(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + got, err := tt.privKey.Sign(msg) if tt.wantSignErr { require.Error(t, err) diff --git a/tm2/pkg/crypto/secp256k1/secp256k1_internal_test.go b/tm2/pkg/crypto/secp256k1/secp256k1_internal_test.go index d680d24f6a9..d80bea83dba 100644 --- a/tm2/pkg/crypto/secp256k1/secp256k1_internal_test.go +++ b/tm2/pkg/crypto/secp256k1/secp256k1_internal_test.go @@ -11,6 +11,8 @@ import ( ) func Test_genPrivKey(t *testing.T) { + t.Parallel() + empty := make([]byte, 32) oneB := big.NewInt(1).Bytes() onePadded := make([]byte, 32) @@ -30,6 +32,8 @@ func Test_genPrivKey(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + if tt.shouldPanic { require.Panics(t, func() { genPrivKey(bytes.NewReader(tt.notSoRand)) diff --git a/tm2/pkg/crypto/secp256k1/secp256k1_nocgo_test.go b/tm2/pkg/crypto/secp256k1/secp256k1_nocgo_test.go index e75d5377670..aeaca9df47f 100644 --- a/tm2/pkg/crypto/secp256k1/secp256k1_nocgo_test.go +++ b/tm2/pkg/crypto/secp256k1/secp256k1_nocgo_test.go @@ -13,6 +13,8 @@ import ( // non-canonical signatures fail. // Note: run with CGO_ENABLED=0 or go test -tags !cgo. func TestSignatureVerificationAndRejectUpperS(t *testing.T) { + t.Parallel() + msg := []byte("We have lingered long enough on the shores of the cosmic ocean.") for i := 0; i < 500; i++ { priv := GenPrivKey() diff --git a/tm2/pkg/crypto/secp256k1/secp256k1_test.go b/tm2/pkg/crypto/secp256k1/secp256k1_test.go index 86aa058f95a..e04f622fdbb 100644 --- a/tm2/pkg/crypto/secp256k1/secp256k1_test.go +++ b/tm2/pkg/crypto/secp256k1/secp256k1_test.go @@ -30,6 +30,8 @@ var secpDataTable = []keyData{ } func TestPubKeySecp256k1Address(t *testing.T) { + t.Parallel() + for _, d := range secpDataTable { privB, _ := hex.DecodeString(d.priv) pubB, _ := hex.DecodeString(d.pub) @@ -50,6 +52,8 @@ func TestPubKeySecp256k1Address(t *testing.T) { } func TestSignAndValidateSecp256k1(t *testing.T) { + t.Parallel() + privKey := secp256k1.GenPrivKey() pubKey := privKey.PubKey() @@ -68,6 +72,8 @@ func TestSignAndValidateSecp256k1(t *testing.T) { // This test is intended to justify the removal of calls to the underlying library // in creating the privkey. func TestSecp256k1LoadPrivkeyAndSerializeIsIdentity(t *testing.T) { + t.Parallel() + numberOfTests := 256 for i := 0; i < numberOfTests; i++ { // Seed the test case with some random bytes @@ -87,6 +93,8 @@ func TestSecp256k1LoadPrivkeyAndSerializeIsIdentity(t *testing.T) { } func TestGenPrivKeySecp256k1(t *testing.T) { + t.Parallel() + // curve oder N N := underlyingSecp256k1.S256().N tests := []struct { @@ -102,6 +110,8 @@ func TestGenPrivKeySecp256k1(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + gotPrivKey := secp256k1.GenPrivKeySecp256k1(tt.secret) require.NotNil(t, gotPrivKey) // interpret as a big.Int and make sure it is a valid field element: diff --git a/tm2/pkg/crypto/tmhash/hash_test.go b/tm2/pkg/crypto/tmhash/hash_test.go index 4a129bb86ac..c69d86653b1 100644 --- a/tm2/pkg/crypto/tmhash/hash_test.go +++ b/tm2/pkg/crypto/tmhash/hash_test.go @@ -9,6 +9,8 @@ import ( ) func TestHash(t *testing.T) { + t.Parallel() + testVector := []byte("abc") hasher := tmhash.New() hasher.Write(testVector) @@ -25,6 +27,8 @@ func TestHash(t *testing.T) { } func TestHashTruncated(t *testing.T) { + t.Parallel() + testVector := []byte("abc") hasher := tmhash.NewTruncated() hasher.Write(testVector) diff --git a/tm2/pkg/crypto/xchacha20poly1305/vector_test.go b/tm2/pkg/crypto/xchacha20poly1305/vector_test.go index 3001217f41e..7ed186de19d 100644 --- a/tm2/pkg/crypto/xchacha20poly1305/vector_test.go +++ b/tm2/pkg/crypto/xchacha20poly1305/vector_test.go @@ -19,6 +19,8 @@ func fromHex(bits string) []byte { } func TestHChaCha20(t *testing.T) { + t.Parallel() + for i, v := range hChaCha20Vectors { var key [32]byte var nonce [16]byte @@ -63,6 +65,8 @@ var hChaCha20Vectors = []struct { } func TestVectors(t *testing.T) { + t.Parallel() + for i, v := range vectors { if len(v.plaintext) == 0 { v.plaintext = make([]byte, len(v.ciphertext)) diff --git a/tm2/pkg/crypto/xchacha20poly1305/xchachapoly_test.go b/tm2/pkg/crypto/xchacha20poly1305/xchachapoly_test.go index 5b92a7607e7..ea7b0bee1a4 100644 --- a/tm2/pkg/crypto/xchacha20poly1305/xchachapoly_test.go +++ b/tm2/pkg/crypto/xchacha20poly1305/xchachapoly_test.go @@ -14,6 +14,8 @@ import ( // Use of this source code is governed by a BSD-style // license that can be found at the bottom of this file. func TestRandom(t *testing.T) { + t.Parallel() + // Some random tests to verify Open(Seal) == Plaintext for i := 0; i < 256; i++ { var nonce [24]byte diff --git a/tm2/pkg/crypto/xsalsa20symmetric/symmetric_test.go b/tm2/pkg/crypto/xsalsa20symmetric/symmetric_test.go index dea965a4356..7460add5185 100644 --- a/tm2/pkg/crypto/xsalsa20symmetric/symmetric_test.go +++ b/tm2/pkg/crypto/xsalsa20symmetric/symmetric_test.go @@ -11,6 +11,8 @@ import ( ) func TestSimple(t *testing.T) { + t.Parallel() + plaintext := []byte("sometext") secret := []byte("somesecretoflengththirtytwo===32") ciphertext := EncryptSymmetric(plaintext, secret) @@ -21,6 +23,8 @@ func TestSimple(t *testing.T) { } func TestSimpleWithKDF(t *testing.T) { + t.Parallel() + salt := []byte("1234567890123456") plaintext := []byte("sometext") secretPass := []byte("somesecret") diff --git a/tm2/pkg/db/backend_test.go b/tm2/pkg/db/backend_test.go index b6cd3f026aa..fd03629fd58 100644 --- a/tm2/pkg/db/backend_test.go +++ b/tm2/pkg/db/backend_test.go @@ -41,8 +41,12 @@ func testBackendGetSetDelete(t *testing.T, backend BackendType) { } func TestBackendsGetSetDelete(t *testing.T) { + t.Parallel() + for dbType := range backends { t.Run(string(dbType), func(t *testing.T) { + t.Parallel() + testBackendGetSetDelete(t, dbType) }) } @@ -59,6 +63,8 @@ func withDB(t *testing.T, creator dbCreator, fn func(DB)) { } func TestBackendsNilKeys(t *testing.T) { + t.Parallel() + // Test all backends. for dbType, creator := range backends { withDB(t, creator, func(db DB) { @@ -137,6 +143,8 @@ func TestBackendsNilKeys(t *testing.T) { } func TestGoLevelDBBackend(t *testing.T) { + t.Parallel() + name := fmt.Sprintf("test_%x", randStr(12)) db, err := NewDB(name, GoLevelDBBackend, t.TempDir()) require.NoError(t, err) @@ -146,9 +154,11 @@ func TestGoLevelDBBackend(t *testing.T) { } func TestDBIterator(t *testing.T) { + t.Parallel() + for dbType := range backends { t.Run(fmt.Sprintf("%v", dbType), func(t *testing.T) { - t.Helper() + t.Parallel() testDBIterator(t, dbType) }) diff --git a/tm2/pkg/db/boltdb_test.go b/tm2/pkg/db/boltdb_test.go index 031023f275a..57091fb53a2 100644 --- a/tm2/pkg/db/boltdb_test.go +++ b/tm2/pkg/db/boltdb_test.go @@ -10,6 +10,8 @@ import ( ) func TestBoltDBNewBoltDB(t *testing.T) { + t.Parallel() + name := fmt.Sprintf("test_%x", randStr(12)) db, err := NewBoltDB(name, t.TempDir()) diff --git a/tm2/pkg/db/c_level_db_test.go b/tm2/pkg/db/c_level_db_test.go index 2bdffd14a83..7044ea0f4de 100644 --- a/tm2/pkg/db/c_level_db_test.go +++ b/tm2/pkg/db/c_level_db_test.go @@ -88,6 +88,8 @@ func bytes2Int64(buf []byte) int64 { */ func TestCLevelDBBackend(t *testing.T) { + t.Parallel() + name := fmt.Sprintf("test_%x", randStr(12)) // Can't use "" (current directory) or "./" here because levigo.Open returns: // "Error initializing DB: IO error: test_XXX.db: Invalid argument" @@ -99,6 +101,8 @@ func TestCLevelDBBackend(t *testing.T) { } func TestCLevelDBStats(t *testing.T) { + t.Parallel() + name := fmt.Sprintf("test_%x", randStr(12)) db, err := NewDB(name, CLevelDBBackend, t.TempDir()) require.NoError(t, err) diff --git a/tm2/pkg/db/db_test.go b/tm2/pkg/db/db_test.go index 3634fb4bf03..62231645613 100644 --- a/tm2/pkg/db/db_test.go +++ b/tm2/pkg/db/db_test.go @@ -8,8 +8,12 @@ import ( ) func TestDBIteratorSingleKey(t *testing.T) { + t.Parallel() + for backend := range backends { t.Run(fmt.Sprintf("Backend %s", backend), func(t *testing.T) { + t.Parallel() + db := newTempDB(t, backend) db.SetSync(bz("1"), bz("value_1")) @@ -27,8 +31,12 @@ func TestDBIteratorSingleKey(t *testing.T) { } func TestDBIteratorTwoKeys(t *testing.T) { + t.Parallel() + for backend := range backends { t.Run(fmt.Sprintf("Backend %s", backend), func(t *testing.T) { + t.Parallel() + db := newTempDB(t, backend) db.SetSync(bz("1"), bz("value_1")) @@ -54,8 +62,12 @@ func TestDBIteratorTwoKeys(t *testing.T) { } func TestDBIteratorMany(t *testing.T) { + t.Parallel() + for backend := range backends { t.Run(fmt.Sprintf("Backend %s", backend), func(t *testing.T) { + t.Parallel() + db := newTempDB(t, backend) keys := make([][]byte, 100) @@ -78,8 +90,12 @@ func TestDBIteratorMany(t *testing.T) { } func TestDBIteratorEmpty(t *testing.T) { + t.Parallel() + for backend := range backends { t.Run(fmt.Sprintf("Backend %s", backend), func(t *testing.T) { + t.Parallel() + db := newTempDB(t, backend) itr := db.Iterator(nil, nil) @@ -90,8 +106,12 @@ func TestDBIteratorEmpty(t *testing.T) { } func TestDBIteratorEmptyBeginAfter(t *testing.T) { + t.Parallel() + for backend := range backends { t.Run(fmt.Sprintf("Backend %s", backend), func(t *testing.T) { + t.Parallel() + db := newTempDB(t, backend) itr := db.Iterator(bz("1"), nil) @@ -102,8 +122,12 @@ func TestDBIteratorEmptyBeginAfter(t *testing.T) { } func TestDBIteratorNonemptyBeginAfter(t *testing.T) { + t.Parallel() + for backend := range backends { t.Run(fmt.Sprintf("Backend %s", backend), func(t *testing.T) { + t.Parallel() + db := newTempDB(t, backend) db.SetSync(bz("1"), bz("value_1")) @@ -115,6 +139,8 @@ func TestDBIteratorNonemptyBeginAfter(t *testing.T) { } func TestDBBatchWrite(t *testing.T) { + t.Parallel() + testCases := []struct { modify func(batch Batch) calls map[string]int diff --git a/tm2/pkg/db/go_level_db_test.go b/tm2/pkg/db/go_level_db_test.go index a85bb6e8713..677b8d86c08 100644 --- a/tm2/pkg/db/go_level_db_test.go +++ b/tm2/pkg/db/go_level_db_test.go @@ -9,6 +9,8 @@ import ( ) func TestGoLevelDBNewGoLevelDB(t *testing.T) { + t.Parallel() + dir := t.TempDir() name := fmt.Sprintf("test_%x", randStr(12)) diff --git a/tm2/pkg/db/gorocks_db_test.go b/tm2/pkg/db/gorocks_db_test.go index 9d1b10cef34..d4792424f39 100644 --- a/tm2/pkg/db/gorocks_db_test.go +++ b/tm2/pkg/db/gorocks_db_test.go @@ -10,6 +10,8 @@ import ( ) func TestGoRocksDBBackend(t *testing.T) { + t.Parallel() + name := fmt.Sprintf("test_%x", randStr(12)) db := NewDB(name, GoRocksDBBackend, t.TempDir()) @@ -18,6 +20,8 @@ func TestGoRocksDBBackend(t *testing.T) { } func TestGoRocksDBStats(t *testing.T) { + t.Parallel() + name := fmt.Sprintf("test_%x", randStr(12)) db := NewDB(name, GoRocksDBBackend, t.TempDir()) diff --git a/tm2/pkg/db/grocks_db_test.go b/tm2/pkg/db/grocks_db_test.go index 60592bc8d82..10b33026128 100644 --- a/tm2/pkg/db/grocks_db_test.go +++ b/tm2/pkg/db/grocks_db_test.go @@ -10,6 +10,8 @@ import ( ) func TestGRocksDBBackend(t *testing.T) { + t.Parallel() + name := fmt.Sprintf("test_%x", randStr(12)) db := NewDB(name, GRocksDBBackend, t.TempDir()) @@ -18,6 +20,8 @@ func TestGRocksDBBackend(t *testing.T) { } func TestGRocksDBStats(t *testing.T) { + t.Parallel() + name := fmt.Sprintf("test_%x", randStr(12)) db := NewDB(name, GRocksDBBackend, t.TempDir()) diff --git a/tm2/pkg/db/prefix_db_test.go b/tm2/pkg/db/prefix_db_test.go index e3e37c7d12c..0948cce98a5 100644 --- a/tm2/pkg/db/prefix_db_test.go +++ b/tm2/pkg/db/prefix_db_test.go @@ -18,6 +18,8 @@ func mockDBWithStuff() DB { } func TestPrefixDBSimple(t *testing.T) { + t.Parallel() + db := mockDBWithStuff() pdb := NewPrefixDB(db, bz("key")) @@ -36,6 +38,8 @@ func TestPrefixDBSimple(t *testing.T) { } func TestPrefixDBIterator1(t *testing.T) { + t.Parallel() + db := mockDBWithStuff() pdb := NewPrefixDB(db, bz("key")) @@ -54,6 +58,8 @@ func TestPrefixDBIterator1(t *testing.T) { } func TestPrefixDBIterator2(t *testing.T) { + t.Parallel() + db := mockDBWithStuff() pdb := NewPrefixDB(db, bz("key")) @@ -64,6 +70,8 @@ func TestPrefixDBIterator2(t *testing.T) { } func TestPrefixDBIterator3(t *testing.T) { + t.Parallel() + db := mockDBWithStuff() pdb := NewPrefixDB(db, bz("key")) @@ -82,6 +90,8 @@ func TestPrefixDBIterator3(t *testing.T) { } func TestPrefixDBIterator4(t *testing.T) { + t.Parallel() + db := mockDBWithStuff() pdb := NewPrefixDB(db, bz("key")) @@ -92,6 +102,8 @@ func TestPrefixDBIterator4(t *testing.T) { } func TestPrefixDBReverseIterator1(t *testing.T) { + t.Parallel() + db := mockDBWithStuff() pdb := NewPrefixDB(db, bz("key")) @@ -110,6 +122,8 @@ func TestPrefixDBReverseIterator1(t *testing.T) { } func TestPrefixDBReverseIterator2(t *testing.T) { + t.Parallel() + db := mockDBWithStuff() pdb := NewPrefixDB(db, bz("key")) @@ -128,6 +142,8 @@ func TestPrefixDBReverseIterator2(t *testing.T) { } func TestPrefixDBReverseIterator3(t *testing.T) { + t.Parallel() + db := mockDBWithStuff() pdb := NewPrefixDB(db, bz("key")) @@ -138,6 +154,8 @@ func TestPrefixDBReverseIterator3(t *testing.T) { } func TestPrefixDBReverseIterator4(t *testing.T) { + t.Parallel() + db := mockDBWithStuff() pdb := NewPrefixDB(db, bz("key")) @@ -148,6 +166,8 @@ func TestPrefixDBReverseIterator4(t *testing.T) { } func TestPrefixDBReverseIterator5(t *testing.T) { + t.Parallel() + db := mockDBWithStuff() pdb := NewPrefixDB(db, bz("key")) @@ -164,6 +184,8 @@ func TestPrefixDBReverseIterator5(t *testing.T) { } func TestPrefixDBReverseIterator6(t *testing.T) { + t.Parallel() + db := mockDBWithStuff() pdb := NewPrefixDB(db, bz("key")) @@ -178,6 +200,8 @@ func TestPrefixDBReverseIterator6(t *testing.T) { } func TestPrefixDBReverseIterator7(t *testing.T) { + t.Parallel() + db := mockDBWithStuff() pdb := NewPrefixDB(db, bz("key")) diff --git a/tm2/pkg/db/util_test.go b/tm2/pkg/db/util_test.go index adf52123290..f66fddde64e 100644 --- a/tm2/pkg/db/util_test.go +++ b/tm2/pkg/db/util_test.go @@ -7,8 +7,12 @@ import ( // Empty iterator for empty db. func TestPrefixIteratorNoMatchNil(t *testing.T) { + t.Parallel() + for backend := range backends { t.Run(fmt.Sprintf("Prefix w/ backend %s", backend), func(t *testing.T) { + t.Parallel() + db := newTempDB(t, backend) itr := IteratePrefix(db, []byte("2")) @@ -19,6 +23,8 @@ func TestPrefixIteratorNoMatchNil(t *testing.T) { // Empty iterator for db populated after iterator created. func TestPrefixIteratorNoMatch1(t *testing.T) { + t.Parallel() + for backend := range backends { if backend == BoltDBBackend { t.Log("bolt does not support concurrent writes while iterating") @@ -26,6 +32,8 @@ func TestPrefixIteratorNoMatch1(t *testing.T) { } t.Run(fmt.Sprintf("Prefix w/ backend %s", backend), func(t *testing.T) { + t.Parallel() + db := newTempDB(t, backend) itr := IteratePrefix(db, []byte("2")) db.SetSync(bz("1"), bz("value_1")) @@ -37,8 +45,12 @@ func TestPrefixIteratorNoMatch1(t *testing.T) { // Empty iterator for prefix starting after db entry. func TestPrefixIteratorNoMatch2(t *testing.T) { + t.Parallel() + for backend := range backends { t.Run(fmt.Sprintf("Prefix w/ backend %s", backend), func(t *testing.T) { + t.Parallel() + db := newTempDB(t, backend) db.SetSync(bz("3"), bz("value_3")) itr := IteratePrefix(db, []byte("4")) @@ -50,8 +62,12 @@ func TestPrefixIteratorNoMatch2(t *testing.T) { // Iterator with single val for db with single val, starting from that val. func TestPrefixIteratorMatch1(t *testing.T) { + t.Parallel() + for backend := range backends { t.Run(fmt.Sprintf("Prefix w/ backend %s", backend), func(t *testing.T) { + t.Parallel() + db := newTempDB(t, backend) db.SetSync(bz("2"), bz("value_2")) itr := IteratePrefix(db, bz("2")) @@ -68,8 +84,12 @@ func TestPrefixIteratorMatch1(t *testing.T) { // Iterator with prefix iterates over everything with same prefix. func TestPrefixIteratorMatches1N(t *testing.T) { + t.Parallel() + for backend := range backends { t.Run(fmt.Sprintf("Prefix w/ backend %s", backend), func(t *testing.T) { + t.Parallel() + db := newTempDB(t, backend) // prefixed diff --git a/tm2/pkg/errors/errors_test.go b/tm2/pkg/errors/errors_test.go index ddd2539738f..21115c21862 100644 --- a/tm2/pkg/errors/errors_test.go +++ b/tm2/pkg/errors/errors_test.go @@ -9,6 +9,8 @@ import ( ) func TestErrorPanic(t *testing.T) { + t.Parallel() + type pnk struct { msg string } @@ -31,6 +33,8 @@ func TestErrorPanic(t *testing.T) { } func TestWrapSomething(t *testing.T) { + t.Parallel() + err := Wrap("something", "formatter%v%v", 0, 1) assert.Equal(t, "something", err.Data()) @@ -40,6 +44,8 @@ func TestWrapSomething(t *testing.T) { } func TestWrapNothing(t *testing.T) { + t.Parallel() + err := Wrap(nil, "formatter%v%v", 0, 1) assert.Equal(t, @@ -51,6 +57,8 @@ func TestWrapNothing(t *testing.T) { } func TestErrorNew(t *testing.T) { + t.Parallel() + err := New("formatter%v%v", 0, 1) assert.Equal(t, @@ -62,6 +70,8 @@ func TestErrorNew(t *testing.T) { } func TestErrorNewWithDetails(t *testing.T) { + t.Parallel() + err := New("formatter%v%v", 0, 1) err.Trace(0, "trace %v", 1) err.Trace(0, "trace %v", 2) @@ -71,6 +81,8 @@ func TestErrorNewWithDetails(t *testing.T) { } func TestErrorNewWithStacktrace(t *testing.T) { + t.Parallel() + err := New("formatter%v%v", 0, 1).Stacktrace() assert.Equal(t, @@ -82,6 +94,8 @@ func TestErrorNewWithStacktrace(t *testing.T) { } func TestErrorNewWithTrace(t *testing.T) { + t.Parallel() + err := New("formatter%v%v", 0, 1) err.Trace(0, "trace %v", 1) err.Trace(0, "trace %v", 2) @@ -100,6 +114,8 @@ func TestErrorNewWithTrace(t *testing.T) { } func TestWrapError(t *testing.T) { + t.Parallel() + var err1 error = New("my message") var err2 error = Wrap(err1, "another message") assert.Equal(t, err1, err2) diff --git a/tm2/pkg/events/events_test.go b/tm2/pkg/events/events_test.go index f3b4aa2fd82..5232364b1c8 100644 --- a/tm2/pkg/events/events_test.go +++ b/tm2/pkg/events/events_test.go @@ -35,6 +35,8 @@ func TestAddListenerFireOnce(t *testing.T) { // TestAddListenerFireMany sets up an EventSwitch, subscribes a single // listener, and sends a thousand integers. func TestAddListenerFireMany(t *testing.T) { + t.Parallel() + evsw := NewEventSwitch() err := evsw.Start() require.NoError(t, err) @@ -62,6 +64,8 @@ func TestAddListenerFireMany(t *testing.T) { // TestAddListeners sets up an EventSwitch, subscribes three // listeners, and sends a thousand integers for each. func TestAddListeners(t *testing.T) { + t.Parallel() + evsw := NewEventSwitch() err := evsw.Start() require.NoError(t, err) @@ -100,6 +104,8 @@ func TestAddListeners(t *testing.T) { } func TestAddAndRemoveListenerConcurrency(t *testing.T) { + t.Parallel() + var ( stopInputEvent = false roundCount = 2000 @@ -145,6 +151,8 @@ func TestAddAndRemoveListenerConcurrency(t *testing.T) { } func TestAddAndRemoveListener(t *testing.T) { + t.Parallel() + evsw := NewEventSwitch() err := evsw.Start() require.NoError(t, err) @@ -192,6 +200,8 @@ func TestAddAndRemoveListener(t *testing.T) { // TestRemoveListener does basic tests on adding and removing func TestRemoveListener(t *testing.T) { + t.Parallel() + evsw := NewEventSwitch() err := evsw.Start() require.NoError(t, err) @@ -241,6 +251,8 @@ func TestRemoveListener(t *testing.T) { // NOTE: it is important to run this test with race conditions tracking on, // `go test -race`, to examine for possible race conditions. func TestRemoveListenersAsync(t *testing.T) { + t.Parallel() + evsw := NewEventSwitch() err := evsw.Start() require.NoError(t, err) diff --git a/tm2/pkg/flow/io_test.go b/tm2/pkg/flow/io_test.go index 196c7c65d9a..d023d32c347 100644 --- a/tm2/pkg/flow/io_test.go +++ b/tm2/pkg/flow/io_test.go @@ -32,6 +32,8 @@ func nextStatus(m *Monitor) Status { } func TestReader(t *testing.T) { + t.Parallel() + in := make([]byte, 100) for i := range in { in[i] = byte(i) @@ -101,6 +103,8 @@ func TestReader(t *testing.T) { } func TestWriter(t *testing.T) { + t.Parallel() + b := make([]byte, 100) for i := range b { b[i] = byte(i) diff --git a/tm2/pkg/iavl/basic_test.go b/tm2/pkg/iavl/basic_test.go index ab46792aee4..f684209a682 100644 --- a/tm2/pkg/iavl/basic_test.go +++ b/tm2/pkg/iavl/basic_test.go @@ -13,6 +13,8 @@ import ( ) func TestBasic(t *testing.T) { + t.Parallel() + tree := NewMutableTree(db.NewMemDB(), 0) up := tree.Set([]byte("1"), []byte("one")) if up { @@ -103,6 +105,8 @@ func TestBasic(t *testing.T) { } func TestUnit(t *testing.T) { + t.Parallel() + expectHash := func(tree *ImmutableTree, hashCount int64) { // ensure number of new hash calculations is as expected. hash, count := tree.hashWithCount() @@ -184,6 +188,8 @@ func TestUnit(t *testing.T) { } func TestRemove(t *testing.T) { + t.Parallel() + size := 10000 keyLen, dataLen := 16, 40 @@ -214,6 +220,8 @@ func TestRemove(t *testing.T) { } func TestIntegration(t *testing.T) { + t.Parallel() + type record struct { key string value string @@ -279,6 +287,8 @@ func TestIntegration(t *testing.T) { } func TestIterateRange(t *testing.T) { + t.Parallel() + type record struct { key string value string @@ -363,6 +373,8 @@ func TestIterateRange(t *testing.T) { } func TestPersistence(t *testing.T) { + t.Parallel() + db := db.NewMemDB() // Create some random key value pairs @@ -390,6 +402,8 @@ func TestPersistence(t *testing.T) { } func TestProof(t *testing.T) { + t.Parallel() + // Construct some random tree db := db.NewMemDB() tree := NewMutableTree(db, 100) @@ -420,6 +434,8 @@ func TestProof(t *testing.T) { } func TestTreeProof(t *testing.T) { + t.Parallel() + db := db.NewMemDB() tree := NewMutableTree(db, 100) assert.Equal(t, tree.Hash(), []byte(nil)) diff --git a/tm2/pkg/iavl/common/random_test.go b/tm2/pkg/iavl/common/random_test.go index 6ed73ab898c..4c1ee8024e0 100644 --- a/tm2/pkg/iavl/common/random_test.go +++ b/tm2/pkg/iavl/common/random_test.go @@ -11,12 +11,16 @@ import ( ) func TestRandStr(t *testing.T) { + t.Parallel() + l := 243 s := RandStr(l) assert.Equal(t, l, len(s)) } func TestRandBytes(t *testing.T) { + t.Parallel() + l := 243 b := RandBytes(l) assert.Equal(t, l, len(b)) diff --git a/tm2/pkg/iavl/proof_forgery_test.go b/tm2/pkg/iavl/proof_forgery_test.go index a742ad40fcc..028675f7c48 100644 --- a/tm2/pkg/iavl/proof_forgery_test.go +++ b/tm2/pkg/iavl/proof_forgery_test.go @@ -14,6 +14,8 @@ import ( ) func TestProofForgery(t *testing.T) { + t.Parallel() + source := rand.NewSource(0) r := rand.New(source) cacheSize := 0 diff --git a/tm2/pkg/iavl/proof_test.go b/tm2/pkg/iavl/proof_test.go index f67ea45b00a..ad4d85d1cd5 100644 --- a/tm2/pkg/iavl/proof_test.go +++ b/tm2/pkg/iavl/proof_test.go @@ -15,6 +15,8 @@ import ( ) func TestTreeGetWithProof(t *testing.T) { + t.Parallel() + tree := NewMutableTree(db.NewMemDB(), 0) require := require.New(t) for _, ikey := range []byte{0x11, 0x32, 0x50, 0x72, 0x99} { @@ -49,6 +51,8 @@ func TestTreeGetWithProof(t *testing.T) { } func TestTreeKeyExistsProof(t *testing.T) { + t.Parallel() + tree := NewMutableTree(db.NewMemDB(), 0) root := tree.WorkingHash() @@ -115,6 +119,8 @@ func TestTreeKeyExistsProof(t *testing.T) { } func TestTreeKeyInRangeProofs(t *testing.T) { + t.Parallel() + tree := NewMutableTree(db.NewMemDB(), 0) require := require.New(t) keys := []byte{0x0a, 0x11, 0x2e, 0x32, 0x50, 0x72, 0x99, 0xa1, 0xe4, 0xf7} // 10 total. diff --git a/tm2/pkg/iavl/tree_dotgraph_test.go b/tm2/pkg/iavl/tree_dotgraph_test.go index f3c2786cda3..3c0233f51fa 100644 --- a/tm2/pkg/iavl/tree_dotgraph_test.go +++ b/tm2/pkg/iavl/tree_dotgraph_test.go @@ -8,6 +8,8 @@ import ( ) func TestWriteDOTGraph(t *testing.T) { + t.Parallel() + tree := NewMutableTree(db.NewMemDB(), 0) for _, ikey := range []byte{ 0x0a, 0x11, 0x2e, 0x32, 0x50, 0x72, 0x99, 0xa1, 0xe4, 0xf7, diff --git a/tm2/pkg/iavl/tree_fuzz_test.go b/tm2/pkg/iavl/tree_fuzz_test.go index 7ea9bb50389..64e20d944a2 100644 --- a/tm2/pkg/iavl/tree_fuzz_test.go +++ b/tm2/pkg/iavl/tree_fuzz_test.go @@ -105,6 +105,8 @@ func genRandomProgram(size int) *program { // Generate many programs and run them. func TestMutableTreeFuzz(t *testing.T) { + t.Parallel() + maxIterations := testFuzzIterations progsPerIteration := 100000 iterations := 0 diff --git a/tm2/pkg/iavl/tree_test.go b/tm2/pkg/iavl/tree_test.go index f15a3276653..ba5bbe3e5ef 100644 --- a/tm2/pkg/iavl/tree_test.go +++ b/tm2/pkg/iavl/tree_test.go @@ -51,6 +51,8 @@ func getTestDB() (db.DB, func()) { } func TestVersionedRandomTree(t *testing.T) { + t.Parallel() + require := require.New(t) d, closeDB := getTestDB() @@ -105,6 +107,8 @@ func TestVersionedRandomTree(t *testing.T) { } func TestVersionedRandomTreeSmallKeys(t *testing.T) { + t.Parallel() + require := require.New(t) d, closeDB := getTestDB() defer closeDB() @@ -146,6 +150,8 @@ func TestVersionedRandomTreeSmallKeys(t *testing.T) { } func TestVersionedRandomTreeSmallKeysRandomDeletes(t *testing.T) { + t.Parallel() + require := require.New(t) d, closeDB := getTestDB() defer closeDB() @@ -187,6 +193,8 @@ func TestVersionedRandomTreeSmallKeysRandomDeletes(t *testing.T) { } func TestVersionedTreeSpecial1(t *testing.T) { + t.Parallel() + tree := NewMutableTree(db.NewMemDB(), 100) tree.Set([]byte("C"), []byte("so43QQFN")) @@ -209,6 +217,8 @@ func TestVersionedTreeSpecial1(t *testing.T) { } func TestVersionedRandomTreeSpecial2(t *testing.T) { + t.Parallel() + require := require.New(t) tree := NewMutableTree(db.NewMemDB(), 100) @@ -225,6 +235,8 @@ func TestVersionedRandomTreeSpecial2(t *testing.T) { } func TestVersionedEmptyTree(t *testing.T) { + t.Parallel() + require := require.New(t) d, closeDB := getTestDB() defer closeDB() @@ -281,6 +293,8 @@ func TestVersionedEmptyTree(t *testing.T) { } func TestVersionedTree(t *testing.T) { + t.Parallel() + require := require.New(t) d, closeDB := getTestDB() defer closeDB() @@ -468,6 +482,8 @@ func TestVersionedTree(t *testing.T) { } func TestVersionedTreeVersionDeletingEfficiency(t *testing.T) { + t.Parallel() + d, closeDB := getTestDB() defer closeDB() @@ -512,6 +528,8 @@ func TestVersionedTreeVersionDeletingEfficiency(t *testing.T) { } func TestVersionedTreeOrphanDeleting(t *testing.T) { + t.Parallel() + mdb := db.NewMemDB() tree := NewMutableTree(mdb, 0) @@ -550,6 +568,8 @@ func TestVersionedTreeOrphanDeleting(t *testing.T) { } func TestVersionedTreeSpecialCase(t *testing.T) { + t.Parallel() + require := require.New(t) tree := NewMutableTree(db.NewMemDB(), 100) @@ -571,6 +591,8 @@ func TestVersionedTreeSpecialCase(t *testing.T) { } func TestVersionedTreeSpecialCase2(t *testing.T) { + t.Parallel() + require := require.New(t) d := db.NewMemDB() @@ -598,6 +620,8 @@ func TestVersionedTreeSpecialCase2(t *testing.T) { } func TestVersionedTreeSpecialCase3(t *testing.T) { + t.Parallel() + require := require.New(t) tree := NewMutableTree(db.NewMemDB(), 0) @@ -626,6 +650,8 @@ func TestVersionedTreeSpecialCase3(t *testing.T) { } func TestVersionedTreeSaveAndLoad(t *testing.T) { + t.Parallel() + require := require.New(t) d := db.NewMemDB() tree := NewMutableTree(d, 0) @@ -677,6 +703,8 @@ func TestVersionedTreeSaveAndLoad(t *testing.T) { } func TestVersionedTreeErrors(t *testing.T) { + t.Parallel() + require := require.New(t) tree := NewMutableTree(db.NewMemDB(), 100) @@ -706,6 +734,8 @@ func TestVersionedTreeErrors(t *testing.T) { } func TestVersionedCheckpoints(t *testing.T) { + t.Parallel() + require := require.New(t) d, closeDB := getTestDB() defer closeDB() @@ -762,6 +792,8 @@ func TestVersionedCheckpoints(t *testing.T) { } func TestVersionedCheckpointsSpecialCase(t *testing.T) { + t.Parallel() + require := require.New(t) tree := NewMutableTree(db.NewMemDB(), 0) key := []byte("k") @@ -788,6 +820,8 @@ func TestVersionedCheckpointsSpecialCase(t *testing.T) { } func TestVersionedCheckpointsSpecialCase2(t *testing.T) { + t.Parallel() + tree := NewMutableTree(db.NewMemDB(), 0) tree.Set([]byte("U"), []byte("XamDUtiJ")) @@ -808,6 +842,8 @@ func TestVersionedCheckpointsSpecialCase2(t *testing.T) { } func TestVersionedCheckpointsSpecialCase3(t *testing.T) { + t.Parallel() + tree := NewMutableTree(db.NewMemDB(), 0) tree.Set([]byte("n"), []byte("2wUCUs8q")) @@ -828,6 +864,8 @@ func TestVersionedCheckpointsSpecialCase3(t *testing.T) { } func TestVersionedCheckpointsSpecialCase4(t *testing.T) { + t.Parallel() + tree := NewMutableTree(db.NewMemDB(), 0) tree.Set([]byte("U"), []byte("XamDUtiJ")) @@ -860,6 +898,8 @@ func TestVersionedCheckpointsSpecialCase4(t *testing.T) { } func TestVersionedCheckpointsSpecialCase5(t *testing.T) { + t.Parallel() + tree := NewMutableTree(db.NewMemDB(), 0) tree.Set([]byte("R"), []byte("ygZlIzeW")) @@ -877,6 +917,8 @@ func TestVersionedCheckpointsSpecialCase5(t *testing.T) { } func TestVersionedCheckpointsSpecialCase6(t *testing.T) { + t.Parallel() + tree := NewMutableTree(db.NewMemDB(), 0) tree.Set([]byte("Y"), []byte("MW79JQeV")) @@ -909,6 +951,8 @@ func TestVersionedCheckpointsSpecialCase6(t *testing.T) { } func TestVersionedCheckpointsSpecialCase7(t *testing.T) { + t.Parallel() + tree := NewMutableTree(db.NewMemDB(), 100) tree.Set([]byte("n"), []byte("OtqD3nyn")) @@ -942,6 +986,8 @@ func TestVersionedCheckpointsSpecialCase7(t *testing.T) { } func TestVersionedTreeEfficiency(t *testing.T) { + t.Parallel() + require := require.New(t) tree := NewMutableTree(db.NewMemDB(), 0) versions := 20 @@ -977,6 +1023,8 @@ func TestVersionedTreeEfficiency(t *testing.T) { } func TestVersionedTreeProofs(t *testing.T) { + t.Parallel() + require := require.New(t) tree := NewMutableTree(db.NewMemDB(), 0) @@ -1047,6 +1095,8 @@ func TestVersionedTreeProofs(t *testing.T) { } func TestOrphans(t *testing.T) { + t.Parallel() + // If you create a sequence of saved versions // Then randomly delete versions other than the first and last until only those two remain // Any remaining orphan nodes should be constrained to just the first version @@ -1079,6 +1129,8 @@ func TestOrphans(t *testing.T) { } func TestVersionedTreeHash(t *testing.T) { + t.Parallel() + require := require.New(t) tree := NewMutableTree(db.NewMemDB(), 0) @@ -1101,6 +1153,8 @@ func TestVersionedTreeHash(t *testing.T) { } func TestNilValueSemantics(t *testing.T) { + t.Parallel() + require := require.New(t) tree := NewMutableTree(db.NewMemDB(), 0) @@ -1110,6 +1164,8 @@ func TestNilValueSemantics(t *testing.T) { } func TestCopyValueSemantics(t *testing.T) { + t.Parallel() + require := require.New(t) tree := NewMutableTree(db.NewMemDB(), 0) @@ -1127,6 +1183,8 @@ func TestCopyValueSemantics(t *testing.T) { } func TestRollback(t *testing.T) { + t.Parallel() + require := require.New(t) tree := NewMutableTree(db.NewMemDB(), 0) @@ -1156,6 +1214,8 @@ func TestRollback(t *testing.T) { } func TestLazyLoadVersion(t *testing.T) { + t.Parallel() + mdb := db.NewMemDB() tree := NewMutableTree(mdb, 0) maxVersions := 10 @@ -1194,6 +1254,8 @@ func TestLazyLoadVersion(t *testing.T) { } func TestOverwrite(t *testing.T) { + t.Parallel() + require := require.New(t) mdb := db.NewMemDB() @@ -1226,6 +1288,8 @@ func TestOverwrite(t *testing.T) { } func TestLoadVersionForOverwriting(t *testing.T) { + t.Parallel() + require := require.New(t) mdb := db.NewMemDB() diff --git a/tm2/pkg/log/tm_logger_test.go b/tm2/pkg/log/tm_logger_test.go index 81614c5ea21..43ca98eb0f9 100644 --- a/tm2/pkg/log/tm_logger_test.go +++ b/tm2/pkg/log/tm_logger_test.go @@ -10,6 +10,8 @@ import ( ) func TestLoggerLogsItsErrors(t *testing.T) { + t.Parallel() + var buf bytes.Buffer logger := log.NewTMLogger(&buf) diff --git a/tm2/pkg/os/net_test.go b/tm2/pkg/os/net_test.go index 258ee28bb28..8cbba60aef2 100644 --- a/tm2/pkg/os/net_test.go +++ b/tm2/pkg/os/net_test.go @@ -7,6 +7,8 @@ import ( ) func TestProtocolAndAddress(t *testing.T) { + t.Parallel() + cases := []struct { fullAddr string proto string diff --git a/tm2/pkg/p2p/conn/connection_test.go b/tm2/pkg/p2p/conn/connection_test.go index 6974dd97e56..68f7fbc0841 100644 --- a/tm2/pkg/p2p/conn/connection_test.go +++ b/tm2/pkg/p2p/conn/connection_test.go @@ -37,6 +37,8 @@ func createMConnectionWithCallbacks(conn net.Conn, onReceive func(chID byte, msg } func TestMConnectionSendFlushStop(t *testing.T) { + t.Parallel() + server, client := NetPipe() defer server.Close() //nolint: errcheck defer client.Close() //nolint: errcheck @@ -82,6 +84,8 @@ func TestMConnectionSendFlushStop(t *testing.T) { } func TestMConnectionSend(t *testing.T) { + t.Parallel() + server, client := NetPipe() defer server.Close() //nolint: errcheck defer client.Close() //nolint: errcheck @@ -113,6 +117,8 @@ func TestMConnectionSend(t *testing.T) { } func TestMConnectionReceive(t *testing.T) { + t.Parallel() + server, client := NetPipe() defer server.Close() //nolint: errcheck defer client.Close() //nolint: errcheck @@ -149,6 +155,8 @@ func TestMConnectionReceive(t *testing.T) { } func TestMConnectionStatus(t *testing.T) { + t.Parallel() + server, client := NetPipe() defer server.Close() //nolint: errcheck defer client.Close() //nolint: errcheck @@ -164,6 +172,8 @@ func TestMConnectionStatus(t *testing.T) { } func TestMConnectionPongTimeoutResultsInError(t *testing.T) { + t.Parallel() + server, client := net.Pipe() defer server.Close() defer client.Close() @@ -203,6 +213,8 @@ func TestMConnectionPongTimeoutResultsInError(t *testing.T) { } func TestMConnectionMultiplePongsInTheBeginning(t *testing.T) { + t.Parallel() + server, client := net.Pipe() defer server.Close() defer client.Close() @@ -256,6 +268,8 @@ func TestMConnectionMultiplePongsInTheBeginning(t *testing.T) { } func TestMConnectionMultiplePings(t *testing.T) { + t.Parallel() + server, client := net.Pipe() defer server.Close() defer client.Close() @@ -293,6 +307,8 @@ func TestMConnectionMultiplePings(t *testing.T) { } func TestMConnectionPingPongs(t *testing.T) { + t.Parallel() + // check that we are not leaking any go-routines defer leaktest.CheckTimeout(t, 10*time.Second)() @@ -348,6 +364,8 @@ func TestMConnectionPingPongs(t *testing.T) { } func TestMConnectionStopsAndReturnsError(t *testing.T) { + t.Parallel() + server, client := NetPipe() defer server.Close() //nolint: errcheck defer client.Close() //nolint: errcheck @@ -422,6 +440,8 @@ func expectSend(ch chan struct{}) bool { } func TestMConnectionReadErrorBadEncoding(t *testing.T) { + t.Parallel() + chOnErr := make(chan struct{}) mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr) defer mconnClient.Stop() @@ -440,6 +460,8 @@ func TestMConnectionReadErrorBadEncoding(t *testing.T) { } func TestMConnectionReadErrorUnknownChannel(t *testing.T) { + t.Parallel() + chOnErr := make(chan struct{}) mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr) defer mconnClient.Stop() @@ -457,6 +479,8 @@ func TestMConnectionReadErrorUnknownChannel(t *testing.T) { } func TestMConnectionReadErrorLongMessage(t *testing.T) { + t.Parallel() + chOnErr := make(chan struct{}) chOnRcv := make(chan struct{}) @@ -499,6 +523,8 @@ func TestMConnectionReadErrorLongMessage(t *testing.T) { } func TestMConnectionReadErrorUnknownMsgType(t *testing.T) { + t.Parallel() + chOnErr := make(chan struct{}) mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr) defer mconnClient.Stop() @@ -513,6 +539,8 @@ func TestMConnectionReadErrorUnknownMsgType(t *testing.T) { } func TestMConnectionTrySend(t *testing.T) { + t.Parallel() + server, client := NetPipe() defer server.Close() defer client.Close() diff --git a/tm2/pkg/p2p/conn/secret_connection_test.go b/tm2/pkg/p2p/conn/secret_connection_test.go index a2560af34eb..b238297ae5e 100644 --- a/tm2/pkg/p2p/conn/secret_connection_test.go +++ b/tm2/pkg/p2p/conn/secret_connection_test.go @@ -98,6 +98,8 @@ func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection } func TestSecretConnectionHandshake(t *testing.T) { + t.Parallel() + fooSecConn, barSecConn := makeSecretConnPair(t) if err := fooSecConn.Close(); err != nil { t.Error(err) @@ -110,6 +112,8 @@ func TestSecretConnectionHandshake(t *testing.T) { // Test that shareEphPubKey rejects lower order public keys based on an // (incomplete) blacklist. func TestShareLowOrderPubkey(t *testing.T) { + t.Parallel() + fooConn, barConn := makeKVStoreConnPair() defer fooConn.Close() defer barConn.Close() @@ -141,6 +145,8 @@ func TestShareLowOrderPubkey(t *testing.T) { // Test that additionally that the Diffie-Hellman shared secret is non-zero. // The shared secret would be zero for lower order pub-keys (but tested against the blacklist only). func TestComputeDHFailsOnLowOrder(t *testing.T) { + t.Parallel() + _, locPrivKey := genEphKeys() for _, remLowOrderPubKey := range blacklist { remLowOrderPubKey := remLowOrderPubKey @@ -153,6 +159,8 @@ func TestComputeDHFailsOnLowOrder(t *testing.T) { } func TestConcurrentWrite(t *testing.T) { + t.Parallel() + fooSecConn, barSecConn := makeSecretConnPair(t) fooWriteText := random.RandStr(dataMaxSize) @@ -175,6 +183,8 @@ func TestConcurrentWrite(t *testing.T) { } func TestConcurrentRead(t *testing.T) { + t.Parallel() + fooSecConn, barSecConn := makeSecretConnPair(t) fooWriteText := random.RandStr(dataMaxSize) n := 100 @@ -221,6 +231,8 @@ func readLots(t *testing.T, wg *sync.WaitGroup, conn net.Conn, n int) { } func TestSecretConnectionReadWrite(t *testing.T) { + t.Parallel() + fooConn, barConn := makeKVStoreConnPair() fooWrites, barWrites := []string{}, []string{} fooReads, barReads := []string{}, []string{} @@ -341,6 +353,8 @@ func TestSecretConnectionReadWrite(t *testing.T) { var update = flag.Bool("update", false, "update .golden files") func TestDeriveSecretsAndChallengeGolden(t *testing.T) { + t.Parallel() + goldenFilepath := filepath.Join("testdata", t.Name()+".golden") if *update { t.Logf("Updating golden test vector file %s", goldenFilepath) @@ -386,6 +400,8 @@ func (pk privKeyWithNilPubKey) PubKey() crypto.PubKey { return nil } func (pk privKeyWithNilPubKey) Equals(pk2 crypto.PrivKey) bool { return pk.orig.Equals(pk2) } func TestNilPubkey(t *testing.T) { + t.Parallel() + fooConn, barConn := makeKVStoreConnPair() fooPrvKey := ed25519.GenPrivKey() barPrvKey := privKeyWithNilPubKey{ed25519.GenPrivKey()} @@ -404,6 +420,8 @@ func TestNilPubkey(t *testing.T) { } func TestNonEd25519Pubkey(t *testing.T) { + t.Parallel() + fooConn, barConn := makeKVStoreConnPair() fooPrvKey := ed25519.GenPrivKey() barPrvKey := secp256k1.GenPrivKey() diff --git a/tm2/pkg/p2p/key_test.go b/tm2/pkg/p2p/key_test.go index 8046f58eb25..4f67cc0a5da 100644 --- a/tm2/pkg/p2p/key_test.go +++ b/tm2/pkg/p2p/key_test.go @@ -11,6 +11,8 @@ import ( ) func TestLoadOrGenNodeKey(t *testing.T) { + t.Parallel() + filePath := filepath.Join(os.TempDir(), random.RandStr(12)+"_peer_id.json") nodeKey, err := LoadOrGenNodeKey(filePath) @@ -22,13 +24,15 @@ func TestLoadOrGenNodeKey(t *testing.T) { assert.Equal(t, nodeKey, nodeKey2) } -//---------------------------------------------------------- +// ---------------------------------------------------------- func padBytes(bz []byte, targetBytes int) []byte { return append(bz, bytes.Repeat([]byte{0xFF}, targetBytes-len(bz))...) } func TestPoWTarget(t *testing.T) { + t.Parallel() + targetBytes := 20 cases := []struct { difficulty uint diff --git a/tm2/pkg/p2p/netaddress_test.go b/tm2/pkg/p2p/netaddress_test.go index a5dc3fca375..413d020c153 100644 --- a/tm2/pkg/p2p/netaddress_test.go +++ b/tm2/pkg/p2p/netaddress_test.go @@ -11,6 +11,8 @@ import ( ) func TestAddress2ID(t *testing.T) { + t.Parallel() + idbz, _ := hex.DecodeString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") id := crypto.AddressFromBytes(idbz).ID() assert.Equal(t, crypto.ID("g1m6kmam774klwlh4dhmhaatd7al02m0h0jwnyc6"), id) @@ -21,6 +23,8 @@ func TestAddress2ID(t *testing.T) { } func TestNewNetAddress(t *testing.T) { + t.Parallel() + tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:8080") require.Nil(t, err) @@ -41,6 +45,8 @@ func TestNewNetAddress(t *testing.T) { } func TestNewNetAddressFromString(t *testing.T) { + t.Parallel() + testCases := []struct { name string addr string @@ -85,6 +91,8 @@ func TestNewNetAddressFromString(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { + t.Parallel() + addr, err := NewNetAddressFromString(tc.addr) if tc.correct { if assert.Nil(t, err, tc.addr) { @@ -98,6 +106,8 @@ func TestNewNetAddressFromString(t *testing.T) { } func TestNewNetAddressFromStrings(t *testing.T) { + t.Parallel() + addrs, errs := NewNetAddressFromStrings([]string{ "127.0.0.1:8080", "g1m6kmam774klwlh4dhmhaatd7al02m0h0jwnyc6@127.0.0.1:8080", @@ -108,11 +118,15 @@ func TestNewNetAddressFromStrings(t *testing.T) { } func TestNewNetAddressFromIPPort(t *testing.T) { + t.Parallel() + addr := NewNetAddressFromIPPort("", net.ParseIP("127.0.0.1"), 8080) assert.Equal(t, "127.0.0.1:8080", addr.String()) } func TestNetAddressProperties(t *testing.T) { + t.Parallel() + // TODO add more test cases testCases := []struct { addr string @@ -140,6 +154,8 @@ func TestNetAddressProperties(t *testing.T) { } func TestNetAddressReachabilityTo(t *testing.T) { + t.Parallel() + // TODO add more test cases testCases := []struct { addr string diff --git a/tm2/pkg/p2p/node_info_test.go b/tm2/pkg/p2p/node_info_test.go index ea97239643f..58f1dab8854 100644 --- a/tm2/pkg/p2p/node_info_test.go +++ b/tm2/pkg/p2p/node_info_test.go @@ -11,6 +11,8 @@ import ( ) func TestNodeInfoValidate(t *testing.T) { + t.Parallel() + // empty fails ni := NodeInfo{} assert.Error(t, ni.Validate()) @@ -86,6 +88,8 @@ func TestNodeInfoValidate(t *testing.T) { } func TestNodeInfoCompatible(t *testing.T) { + t.Parallel() + nodeKey1 := NodeKey{PrivKey: ed25519.GenPrivKey()} nodeKey2 := NodeKey{PrivKey: ed25519.GenPrivKey()} name := "testing" diff --git a/tm2/pkg/p2p/peer_test.go b/tm2/pkg/p2p/peer_test.go index 070d783d2af..8841e34cc83 100644 --- a/tm2/pkg/p2p/peer_test.go +++ b/tm2/pkg/p2p/peer_test.go @@ -19,6 +19,8 @@ import ( ) func TestPeerBasic(t *testing.T) { + t.Parallel() + assert, require := assert.New(t), require.New(t) // simulate remote peer @@ -43,6 +45,8 @@ func TestPeerBasic(t *testing.T) { } func TestPeerSend(t *testing.T) { + t.Parallel() + assert, require := assert.New(t), require.New(t) config := cfg diff --git a/tm2/pkg/p2p/switch_test.go b/tm2/pkg/p2p/switch_test.go index a0d4853493b..9e82e20bca1 100644 --- a/tm2/pkg/p2p/switch_test.go +++ b/tm2/pkg/p2p/switch_test.go @@ -105,6 +105,8 @@ func initSwitchFunc(i int, sw *Switch) *Switch { } func TestSwitches(t *testing.T) { + t.Parallel() + s1, s2 := MakeSwitchPair(t, initSwitchFunc) defer s1.Stop() defer s2.Stop() @@ -152,6 +154,8 @@ func assertMsgReceivedWithTimeout(t *testing.T, msgBytes []byte, channel byte, r } func TestSwitchFiltersOutItself(t *testing.T) { + t.Parallel() + s1 := MakeSwitch(cfg, 1, "127.0.0.1", "123.123.123", initSwitchFunc) // simulate s1 having a public IP by creating a remote peer with the same ID @@ -176,6 +180,8 @@ func TestSwitchFiltersOutItself(t *testing.T) { } func TestSwitchPeerFilter(t *testing.T) { + t.Parallel() + var ( filters = []PeerFilterFunc{ func(_ IPeerSet, _ Peer) error { return nil }, @@ -219,6 +225,8 @@ func TestSwitchPeerFilter(t *testing.T) { } func TestSwitchPeerFilterTimeout(t *testing.T) { + t.Parallel() + var ( filters = []PeerFilterFunc{ func(_ IPeerSet, _ Peer) error { @@ -260,6 +268,8 @@ func TestSwitchPeerFilterTimeout(t *testing.T) { } func TestSwitchPeerFilterDuplicate(t *testing.T) { + t.Parallel() + sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc) sw.Start() defer sw.Stop() @@ -303,6 +313,8 @@ func assertNoPeersAfterTimeout(t *testing.T, sw *Switch, timeout time.Duration) } func TestSwitchStopsNonPersistentPeerOnError(t *testing.T) { + t.Parallel() + assert, require := assert.New(t), require.New(t) sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc) @@ -338,6 +350,8 @@ func TestSwitchStopsNonPersistentPeerOnError(t *testing.T) { } func TestSwitchStopPeerForError(t *testing.T) { + t.Parallel() + // make two connected switches sw1, sw2 := MakeSwitchPair(t, func(i int, sw *Switch) *Switch { return initSwitchFunc(i, sw) @@ -360,6 +374,8 @@ func TestSwitchStopPeerForError(t *testing.T) { } func TestSwitchReconnectsToOutboundPersistentPeer(t *testing.T) { + t.Parallel() + sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc) err := sw.Start() require.NoError(t, err) @@ -405,6 +421,8 @@ func TestSwitchReconnectsToOutboundPersistentPeer(t *testing.T) { } func TestSwitchReconnectsToInboundPersistentPeer(t *testing.T) { + t.Parallel() + sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc) err := sw.Start() require.NoError(t, err) @@ -430,6 +448,8 @@ func TestSwitchReconnectsToInboundPersistentPeer(t *testing.T) { } func TestSwitchDialPeersAsync(t *testing.T) { + t.Parallel() + if testing.Short() { return } @@ -460,6 +480,8 @@ func waitUntilSwitchHasAtLeastNPeers(sw *Switch, n int) { } func TestSwitchFullConnectivity(t *testing.T) { + t.Parallel() + switches := MakeConnectedSwitches(cfg, 3, initSwitchFunc, Connect2Switches) defer func() { for _, sw := range switches { @@ -475,6 +497,8 @@ func TestSwitchFullConnectivity(t *testing.T) { } func TestSwitchAcceptRoutine(t *testing.T) { + t.Parallel() + cfg.MaxNumInboundPeers = 5 // make switch @@ -547,6 +571,8 @@ func (errorTransport) Cleanup(Peer) { } func TestSwitchAcceptRoutineErrorCases(t *testing.T) { + t.Parallel() + sw := NewSwitch(cfg, errorTransport{FilterTimeoutError{}}) assert.NotPanics(t, func() { err := sw.Start() @@ -599,6 +625,8 @@ func (r *mockReactor) InitCalledBeforeRemoveFinished() bool { // see stopAndRemovePeer func TestFlappySwitchInitPeerIsNotCalledBeforeRemovePeer(t *testing.T) { + t.Parallel() + testutils.FilterStability(t, testutils.Flappy) // make reactor diff --git a/tm2/pkg/p2p/transport_test.go b/tm2/pkg/p2p/transport_test.go index 49ab9ac52e3..63b1c26e666 100644 --- a/tm2/pkg/p2p/transport_test.go +++ b/tm2/pkg/p2p/transport_test.go @@ -33,6 +33,8 @@ func newMultiplexTransport( } func TestTransportMultiplexConnFilter(t *testing.T) { + t.Parallel() + mt := newMultiplexTransport( emptyNodeInfo(), NodeKey{ @@ -87,6 +89,8 @@ func TestTransportMultiplexConnFilter(t *testing.T) { } func TestTransportMultiplexConnFilterTimeout(t *testing.T) { + t.Parallel() + mt := newMultiplexTransport( emptyNodeInfo(), NodeKey{ @@ -137,6 +141,8 @@ func TestTransportMultiplexConnFilterTimeout(t *testing.T) { } func TestTransportMultiplexAcceptMultiple(t *testing.T) { + t.Parallel() + mt := testSetupMultiplexTransport(t) laddr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) @@ -212,6 +218,8 @@ func testDialer(dialAddr NetAddress, errc chan error) { } func TestFlappyTransportMultiplexAcceptNonBlocking(t *testing.T) { + t.Parallel() + testutils.FilterStability(t, testutils.Flappy) mt := testSetupMultiplexTransport(t) @@ -298,6 +306,8 @@ func TestFlappyTransportMultiplexAcceptNonBlocking(t *testing.T) { } func TestTransportMultiplexValidateNodeInfo(t *testing.T) { + t.Parallel() + mt := testSetupMultiplexTransport(t) errc := make(chan error) @@ -339,6 +349,8 @@ func TestTransportMultiplexValidateNodeInfo(t *testing.T) { } func TestTransportMultiplexRejectMismatchID(t *testing.T) { + t.Parallel() + mt := testSetupMultiplexTransport(t) errc := make(chan error) @@ -378,6 +390,8 @@ func TestTransportMultiplexRejectMismatchID(t *testing.T) { } func TestTransportMultiplexDialRejectWrongID(t *testing.T) { + t.Parallel() + mt := testSetupMultiplexTransport(t) var ( @@ -407,6 +421,8 @@ func TestTransportMultiplexDialRejectWrongID(t *testing.T) { } func TestTransportMultiplexRejectIncompatible(t *testing.T) { + t.Parallel() + mt := testSetupMultiplexTransport(t) errc := make(chan error) @@ -443,6 +459,8 @@ func TestTransportMultiplexRejectIncompatible(t *testing.T) { } func TestTransportMultiplexRejectSelf(t *testing.T) { + t.Parallel() + mt := testSetupMultiplexTransport(t) errc := make(chan error) @@ -482,6 +500,8 @@ func TestTransportMultiplexRejectSelf(t *testing.T) { } func TestTransportConnDuplicateIPFilter(t *testing.T) { + t.Parallel() + filter := ConnDuplicateIPFilter() if err := filter(nil, &testTransportConn{}, nil); err != nil { @@ -507,6 +527,8 @@ func TestTransportConnDuplicateIPFilter(t *testing.T) { } func TestTransportHandshake(t *testing.T) { + t.Parallel() + ln, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) diff --git a/tm2/pkg/random/random_test.go b/tm2/pkg/random/random_test.go index e2d45533626..71e05e95e16 100644 --- a/tm2/pkg/random/random_test.go +++ b/tm2/pkg/random/random_test.go @@ -15,18 +15,24 @@ import ( ) func TestRandStr(t *testing.T) { + t.Parallel() + l := 243 s := RandStr(l) assert.Equal(t, l, len(s)) } func TestRandBytes(t *testing.T) { + t.Parallel() + l := 243 b := RandBytes(l) assert.Equal(t, l, len(b)) } func TestRandIntn(t *testing.T) { + t.Parallel() + n := 243 for i := 0; i < 100; i++ { x := RandIntn(n) @@ -76,6 +82,8 @@ func testThemAll() string { } func TestRngConcurrencySafety(t *testing.T) { + t.Parallel() + var wg sync.WaitGroup for i := 0; i < 100; i++ { wg.Add(1) diff --git a/tm2/pkg/sdk/auth/ante_test.go b/tm2/pkg/sdk/auth/ante_test.go index 2dc3ec08176..9c15cca18a2 100644 --- a/tm2/pkg/sdk/auth/ante_test.go +++ b/tm2/pkg/sdk/auth/ante_test.go @@ -59,6 +59,8 @@ func defaultAnteOptions() AnteOptions { // Test various error cases in the AnteHandler control flow. func TestAnteHandlerSigErrors(t *testing.T) { + t.Parallel() + // setup env := setupTestEnv() ctx := env.ctx @@ -107,6 +109,8 @@ func TestAnteHandlerSigErrors(t *testing.T) { // Test logic around account number checking with one signer and many signers. func TestAnteHandlerAccountNumbers(t *testing.T) { + t.Parallel() + // setup env := setupTestEnv() anteHandler := NewAnteHandler(env.acck, env.bank, DefaultSigVerificationGasConsumer, defaultAnteOptions()) @@ -164,6 +168,8 @@ func TestAnteHandlerAccountNumbers(t *testing.T) { // Test logic around account number checking with many signers when BlockHeight is 0. func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) { + t.Parallel() + // setup env := setupTestEnv() anteHandler := NewAnteHandler(env.acck, env.bank, DefaultSigVerificationGasConsumer, defaultAnteOptions()) @@ -223,6 +229,8 @@ func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) { // Test logic around sequence checking with one signer and many signers. func TestAnteHandlerSequences(t *testing.T) { + t.Parallel() + // setup env := setupTestEnv() anteHandler := NewAnteHandler(env.acck, env.bank, DefaultSigVerificationGasConsumer, defaultAnteOptions()) @@ -300,6 +308,8 @@ func TestAnteHandlerSequences(t *testing.T) { // Test logic around fee deduction. func TestAnteHandlerFees(t *testing.T) { + t.Parallel() + // setup env := setupTestEnv() ctx := env.ctx @@ -341,6 +351,8 @@ func TestAnteHandlerFees(t *testing.T) { // Test logic around memo gas consumption. func TestAnteHandlerMemoGas(t *testing.T) { + t.Parallel() + // setup env := setupTestEnv() anteHandler := NewAnteHandler(env.acck, env.bank, DefaultSigVerificationGasConsumer, defaultAnteOptions()) @@ -381,6 +393,8 @@ func TestAnteHandlerMemoGas(t *testing.T) { } func TestAnteHandlerMultiSigner(t *testing.T) { + t.Parallel() + // setup env := setupTestEnv() anteHandler := NewAnteHandler(env.acck, env.bank, DefaultSigVerificationGasConsumer, defaultAnteOptions()) @@ -431,6 +445,8 @@ func TestAnteHandlerMultiSigner(t *testing.T) { } func TestAnteHandlerBadSignBytes(t *testing.T) { + t.Parallel() + // setup env := setupTestEnv() anteHandler := NewAnteHandler(env.acck, env.bank, DefaultSigVerificationGasConsumer, defaultAnteOptions()) @@ -508,6 +524,8 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { } func TestAnteHandlerSetPubKey(t *testing.T) { + t.Parallel() + // setup env := setupTestEnv() anteHandler := NewAnteHandler(env.acck, env.bank, DefaultSigVerificationGasConsumer, defaultAnteOptions()) @@ -560,6 +578,8 @@ func TestAnteHandlerSetPubKey(t *testing.T) { } func TestProcessPubKey(t *testing.T) { + t.Parallel() + env := setupTestEnv() ctx := env.ctx @@ -588,7 +608,10 @@ func TestProcessPubKey(t *testing.T) { {"pubkey doesn't match addr, simulate on", args{acc1, std.Signature{PubKey: priv2.PubKey()}, true}, false}, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + _, err := ProcessPubKey(tt.args.acc, tt.args.sig, tt.args.simulate) require.Equal(t, tt.wantErr, !err.IsOK()) }) @@ -596,6 +619,8 @@ func TestProcessPubKey(t *testing.T) { } func TestConsumeSignatureVerificationGas(t *testing.T) { + t.Parallel() + params := DefaultParams() msg := []byte{1, 2, 3, 4} @@ -625,7 +650,10 @@ func TestConsumeSignatureVerificationGas(t *testing.T) { {"unknown key", args{store.NewInfiniteGasMeter(), nil, nil, params}, 0, true}, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + res := DefaultSigVerificationGasConsumer(tt.args.meter, tt.args.sig, tt.args.pubkey, tt.args.params) if tt.shouldErr { @@ -671,6 +699,8 @@ func expectedGasCostByKeys(pubkeys []crypto.PubKey) int64 { } func TestCountSubkeys(t *testing.T) { + t.Parallel() + genPubKeys := func(n int) []crypto.PubKey { var ret []crypto.PubKey for i := 0; i < n; i++ { @@ -698,13 +728,18 @@ func TestCountSubkeys(t *testing.T) { {"multi level multikey", args{multiLevelMultiKey}, 11}, } for _, tt := range tests { - t.Run(tt.name, func(T *testing.T) { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + require.Equal(t, tt.want, std.CountSubKeys(tt.args.pub)) }) } } func TestAnteHandlerSigLimitExceeded(t *testing.T) { + t.Parallel() + // setup env := setupTestEnv() anteHandler := NewAnteHandler(env.acck, env.bank, DefaultSigVerificationGasConsumer, defaultAnteOptions()) @@ -742,6 +777,8 @@ func TestAnteHandlerSigLimitExceeded(t *testing.T) { } func TestEnsureSufficientMempoolFees(t *testing.T) { + t.Parallel() + // setup env := setupTestEnv() ctx := env.ctx.WithMinGasPrices( @@ -775,6 +812,8 @@ func TestEnsureSufficientMempoolFees(t *testing.T) { // Test custom SignatureVerificationGasConsumer func TestCustomSignatureVerificationGasConsumer(t *testing.T) { + t.Parallel() + // setup env := setupTestEnv() // setup an ante handler that only accepts PubKeyEd25519 diff --git a/tm2/pkg/sdk/auth/keeper_test.go b/tm2/pkg/sdk/auth/keeper_test.go index 3af74cf4a4c..d40d96cdb4b 100644 --- a/tm2/pkg/sdk/auth/keeper_test.go +++ b/tm2/pkg/sdk/auth/keeper_test.go @@ -9,6 +9,8 @@ import ( ) func TestAccountMapperGetSet(t *testing.T) { + t.Parallel() + env := setupTestEnv() addr := crypto.AddressFromPreimage([]byte("some-address")) @@ -38,6 +40,8 @@ func TestAccountMapperGetSet(t *testing.T) { } func TestAccountMapperRemoveAccount(t *testing.T) { + t.Parallel() + env := setupTestEnv() addr1 := crypto.AddressFromPreimage([]byte("addr1")) addr2 := crypto.AddressFromPreimage([]byte("addr2")) diff --git a/tm2/pkg/sdk/bank/handler_test.go b/tm2/pkg/sdk/bank/handler_test.go index fef4810c027..85fc68fc304 100644 --- a/tm2/pkg/sdk/bank/handler_test.go +++ b/tm2/pkg/sdk/bank/handler_test.go @@ -16,6 +16,8 @@ import ( ) func TestInvalidMsg(t *testing.T) { + t.Parallel() + h := NewHandler(BankKeeper{}) res := h.Process(sdk.NewContext(sdk.RunTxModeDeliver, nil, &bft.Header{ChainID: "test-chain"}, nil), tu.NewTestMsg()) require.False(t, res.IsOK()) @@ -23,6 +25,8 @@ func TestInvalidMsg(t *testing.T) { } func TestBalances(t *testing.T) { + t.Parallel() + env := setupTestEnv() h := NewHandler(env.bank) _, _, addr := tu.KeyTestPubAddr() @@ -51,6 +55,8 @@ func TestBalances(t *testing.T) { } func TestQuerierRouteNotFound(t *testing.T) { + t.Parallel() + env := setupTestEnv() h := NewHandler(env.bank) req := abci.RequestQuery{ diff --git a/tm2/pkg/sdk/bank/keeper_test.go b/tm2/pkg/sdk/bank/keeper_test.go index d4e230330d5..59b4c12689c 100644 --- a/tm2/pkg/sdk/bank/keeper_test.go +++ b/tm2/pkg/sdk/bank/keeper_test.go @@ -11,6 +11,8 @@ import ( ) func TestKeeper(t *testing.T) { + t.Parallel() + env := setupTestEnv() ctx := env.ctx @@ -88,6 +90,8 @@ func TestKeeper(t *testing.T) { } func TestBankKeeper(t *testing.T) { + t.Parallel() + env := setupTestEnv() ctx := env.ctx @@ -134,6 +138,8 @@ func TestBankKeeper(t *testing.T) { } func TestViewKeeper(t *testing.T) { + t.Parallel() + env := setupTestEnv() ctx := env.ctx view := NewViewKeeper(env.acck) diff --git a/tm2/pkg/sdk/baseapp_test.go b/tm2/pkg/sdk/baseapp_test.go index 3fb44e5f744..f6c2038569a 100644 --- a/tm2/pkg/sdk/baseapp_test.go +++ b/tm2/pkg/sdk/baseapp_test.go @@ -80,6 +80,8 @@ func setupBaseApp(t *testing.T, options ...func(*BaseApp)) *BaseApp { } func TestMountStores(t *testing.T) { + t.Parallel() + app := setupBaseApp(t) // check both stores @@ -92,6 +94,8 @@ func TestMountStores(t *testing.T) { // Test that we can make commits and then reload old versions. // Test that LoadLatestVersion actually does. func TestLoadVersion(t *testing.T) { + t.Parallel() + pruningOpt := SetPruningOptions(store.PruneSyncable) name := t.Name() db := dbm.NewMemDB() @@ -139,6 +143,8 @@ func TestLoadVersion(t *testing.T) { } func TestAppVersionSetterGetter(t *testing.T) { + t.Parallel() + pruningOpt := SetPruningOptions(store.PruneSyncable) name := t.Name() db := dbm.NewMemDB() @@ -158,6 +164,8 @@ func TestAppVersionSetterGetter(t *testing.T) { } func TestLoadVersionInvalid(t *testing.T) { + t.Parallel() + pruningOpt := SetPruningOptions(store.PruneSyncable) name := t.Name() db := dbm.NewMemDB() @@ -198,6 +206,8 @@ func testLoadVersionHelper(t *testing.T, app *BaseApp, expectedHeight int64, exp } func TestOptionFunction(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() bap := newBaseApp("starting name", db, testChangeNameHelper("new name")) require.Equal(t, bap.name, "new name", "BaseApp should have had name changed via option function") @@ -211,6 +221,8 @@ func testChangeNameHelper(name string) func(*BaseApp) { // Test that Info returns the latest committed state. func TestInfo(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() app := newBaseApp(t.Name(), db) @@ -229,6 +241,8 @@ func TestInfo(t *testing.T) { } func TestBaseAppOptionSeal(t *testing.T) { + t.Parallel() + app := setupBaseApp(t) require.Panics(t, func() { @@ -258,6 +272,8 @@ func TestBaseAppOptionSeal(t *testing.T) { } func TestSetMinGasPrices(t *testing.T) { + t.Parallel() + minGasPrices, err := ParseGasPrices("5000stake/10gas") require.Nil(t, err) db := dbm.NewMemDB() @@ -266,6 +282,8 @@ func TestSetMinGasPrices(t *testing.T) { } func TestInitChainer(t *testing.T) { + t.Parallel() + name := t.Name() // keep the db and logger ourselves so // we can reload the same app later @@ -483,6 +501,8 @@ func incrementingCounter(t *testing.T, store store.Store, counterKey []byte, cou // on the store within a block, and that the CheckTx state // gets reset to the latest committed state during Commit func TestCheckTx(t *testing.T) { + t.Parallel() + // This ante handler reads the key and checks that the value matches the current counter. // This ensures changes to the kvstore persist across successive CheckTx. counterKey := []byte("counter-key") @@ -526,6 +546,8 @@ func TestCheckTx(t *testing.T) { // Test that successive DeliverTx can see each others' effects // on the store, both within and across blocks. func TestDeliverTx(t *testing.T) { + t.Parallel() + // test increments in the ante anteKey := []byte("ante-key") anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, mainKey, anteKey)) } @@ -562,14 +584,10 @@ func TestDeliverTx(t *testing.T) { } } -// Number of messages doesn't matter to CheckTx. -func TestMultiMsgCheckTx(t *testing.T) { - // TODO: ensure we get the same results - // with one message or many -} - // One call to DeliverTx should process all the messages, in order. func TestMultiMsgDeliverTx(t *testing.T) { + t.Parallel() + // increment the tx counter anteKey := []byte("ante-key") anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, mainKey, anteKey)) } @@ -629,17 +647,12 @@ func TestMultiMsgDeliverTx(t *testing.T) { require.Equal(t, int64(2), msgCounter2) } -// Interleave calls to Check and Deliver and ensure -// that there is no cross-talk. Check sees results of the previous Check calls -// and Deliver sees that of the previous Deliver calls, but they don't see eachother. -func TestConcurrentCheckDeliver(t *testing.T) { - // TODO -} - // Simulate a transaction that uses gas to compute the gas. // Simulate() and Query(".app/simulate", txBytes) should give // the same results. func TestSimulateTx(t *testing.T) { + t.Parallel() + gasConsumed := int64(5) anteOpt := func(bapp *BaseApp) { @@ -700,6 +713,8 @@ func TestSimulateTx(t *testing.T) { } func TestRunInvalidTransaction(t *testing.T) { + t.Parallel() + anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(func(ctx Context, tx Tx, simulate bool) (newCtx Context, res Result, abort bool) { newCtx = ctx @@ -775,6 +790,8 @@ func TestRunInvalidTransaction(t *testing.T) { // Test that transactions exceeding gas limits fail func TestTxGasLimits(t *testing.T) { + t.Parallel() + gasGranted := int64(10) anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(func(ctx Context, tx Tx, simulate bool) (newCtx Context, res Result, abort bool) { @@ -849,6 +866,8 @@ func TestTxGasLimits(t *testing.T) { // Test that transactions exceeding gas limits fail func TestMaxBlockGasLimits(t *testing.T) { + t.Parallel() + gasGranted := int64(10) anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(func(ctx Context, tx Tx, simulate bool) (newCtx Context, res Result, abort bool) { @@ -938,6 +957,8 @@ func TestMaxBlockGasLimits(t *testing.T) { } func TestBaseAppAnteHandler(t *testing.T) { + t.Parallel() + anteKey := []byte("ante-key") anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, mainKey, anteKey)) @@ -1007,6 +1028,8 @@ func TestBaseAppAnteHandler(t *testing.T) { } func TestGasConsumptionBadTx(t *testing.T) { + t.Parallel() + gasWanted := int64(5) anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(func(ctx Context, tx Tx, simulate bool) (newCtx Context, res Result, abort bool) { @@ -1070,6 +1093,8 @@ func TestGasConsumptionBadTx(t *testing.T) { // Test that we can only query from the latest committed state. func TestQuery(t *testing.T) { + t.Parallel() + key, value := []byte("hello"), []byte("goodbye") anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(func(ctx Context, tx Tx, simulate bool) (newCtx Context, res Result, abort bool) { diff --git a/tm2/pkg/service/service_test.go b/tm2/pkg/service/service_test.go index b3817d6f60a..adf14e0c539 100644 --- a/tm2/pkg/service/service_test.go +++ b/tm2/pkg/service/service_test.go @@ -16,6 +16,8 @@ func (testService) OnReset() error { } func TestBaseServiceWait(t *testing.T) { + t.Parallel() + ts := &testService{} ts.BaseService = *NewBaseService(nil, "TestService", ts) ts.Start() @@ -37,6 +39,8 @@ func TestBaseServiceWait(t *testing.T) { } func TestBaseServiceReset(t *testing.T) { + t.Parallel() + ts := &testService{} ts.BaseService = *NewBaseService(nil, "TestService", ts) ts.Start() diff --git a/tm2/pkg/std/coin_test.go b/tm2/pkg/std/coin_test.go index 923781ed412..8d9a9359b61 100644 --- a/tm2/pkg/std/coin_test.go +++ b/tm2/pkg/std/coin_test.go @@ -18,12 +18,16 @@ var ( // Coin tests func TestCoin(t *testing.T) { + t.Parallel() + require.Panics(t, func() { NewCoin(testDenom1, -1) }) require.Panics(t, func() { NewCoin(strings.ToUpper(testDenom1), 10) }) require.Equal(t, int64(5), NewCoin(testDenom1, 5).Amount) } func TestIsEqualCoin(t *testing.T) { + t.Parallel() + cases := []struct { inputOne Coin inputTwo Coin @@ -46,6 +50,8 @@ func TestIsEqualCoin(t *testing.T) { } func TestCoinIsValid(t *testing.T) { + t.Parallel() + cases := []struct { coin Coin expectPass bool @@ -66,6 +72,8 @@ func TestCoinIsValid(t *testing.T) { } func TestAddCoin(t *testing.T) { + t.Parallel() + cases := []struct { inputOne Coin inputTwo Coin @@ -88,6 +96,8 @@ func TestAddCoin(t *testing.T) { } func TestSubCoin(t *testing.T) { + t.Parallel() + cases := []struct { inputOne Coin inputTwo Coin @@ -120,6 +130,8 @@ func TestSubCoin(t *testing.T) { } func TestIsGTECoin(t *testing.T) { + t.Parallel() + cases := []struct { inputOne Coin inputTwo Coin @@ -142,6 +154,8 @@ func TestIsGTECoin(t *testing.T) { } func TestIsLTCoin(t *testing.T) { + t.Parallel() + cases := []struct { inputOne Coin inputTwo Coin @@ -167,6 +181,8 @@ func TestIsLTCoin(t *testing.T) { } func TestCoinIsZero(t *testing.T) { + t.Parallel() + coin := NewCoin(testDenom1, 0) res := coin.IsZero() require.True(t, res) @@ -180,6 +196,8 @@ func TestCoinIsZero(t *testing.T) { // Coins tests func TestIsZeroCoins(t *testing.T) { + t.Parallel() + cases := []struct { inputOne Coins expected bool @@ -198,6 +216,8 @@ func TestIsZeroCoins(t *testing.T) { } func TestEqualCoins(t *testing.T) { + t.Parallel() + cases := []struct { inputOne Coins inputTwo Coins @@ -224,6 +244,8 @@ func TestEqualCoins(t *testing.T) { } func TestAddCoins(t *testing.T) { + t.Parallel() + zero := int64(0) one := int64(1) two := int64(2) @@ -248,6 +270,8 @@ func TestAddCoins(t *testing.T) { } func TestSubCoins(t *testing.T) { + t.Parallel() + zero := int64(0) one := int64(1) two := int64(2) @@ -277,6 +301,8 @@ func TestSubCoins(t *testing.T) { } func TestCoins(t *testing.T) { + t.Parallel() + good := Coins{ {"gas", int64(1)}, {"mineral", int64(1)}, @@ -339,6 +365,8 @@ func TestCoins(t *testing.T) { } func TestCoinsGT(t *testing.T) { + t.Parallel() + one := int64(1) two := int64(2) @@ -351,6 +379,8 @@ func TestCoinsGT(t *testing.T) { } func TestCoinsLT(t *testing.T) { + t.Parallel() + one := int64(1) two := int64(2) @@ -366,6 +396,8 @@ func TestCoinsLT(t *testing.T) { } func TestCoinsLTE(t *testing.T) { + t.Parallel() + one := int64(1) two := int64(2) @@ -381,6 +413,8 @@ func TestCoinsLTE(t *testing.T) { } func TestParse(t *testing.T) { + t.Parallel() + one := int64(1) cases := []struct { @@ -413,6 +447,8 @@ func TestParse(t *testing.T) { } func TestSortCoins(t *testing.T) { + t.Parallel() + good := Coins{ NewCoin("gas", 1), NewCoin("mineral", 1), @@ -462,6 +498,8 @@ func TestSortCoins(t *testing.T) { } func TestAmountOf(t *testing.T) { + t.Parallel() + case0 := Coins{} case1 := Coins{ NewCoin("gold", 0), @@ -504,6 +542,8 @@ func TestAmountOf(t *testing.T) { } func TestCoinsIsAnyGTE(t *testing.T) { + t.Parallel() + one := int64(1) two := int64(2) @@ -524,6 +564,8 @@ func TestCoinsIsAnyGTE(t *testing.T) { } func TestCoinsIsAllGT(t *testing.T) { + t.Parallel() + one := int64(1) two := int64(2) @@ -544,6 +586,8 @@ func TestCoinsIsAllGT(t *testing.T) { } func TestCoinsIsAllGTE(t *testing.T) { + t.Parallel() + one := int64(1) two := int64(2) @@ -566,6 +610,8 @@ func TestCoinsIsAllGTE(t *testing.T) { } func TestNewCoins(t *testing.T) { + t.Parallel() + tenatom := NewCoin("atom", 10) tenbtc := NewCoin("btc", 10) zeroeth := NewCoin("eth", 0) @@ -582,7 +628,10 @@ func TestNewCoins(t *testing.T) { {"panic on dups", []Coin{tenatom, tenatom}, Coins{}, true}, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + if tt.wantPanic { require.Panics(t, func() { NewCoins(tt.coins...) }) return @@ -594,6 +643,8 @@ func TestNewCoins(t *testing.T) { } func TestCoinsIsAnyGT(t *testing.T) { + t.Parallel() + twoAtom := NewCoin("atom", 2) fiveAtom := NewCoin("atom", 5) threeEth := NewCoin("eth", 3) @@ -613,6 +664,8 @@ func TestCoinsIsAnyGT(t *testing.T) { } func TestFindDup(t *testing.T) { + t.Parallel() + abc := NewCoin("abc", 10) def := NewCoin("def", 10) ghi := NewCoin("ghi", 10) @@ -632,7 +685,10 @@ func TestFindDup(t *testing.T) { {"dup after first position", args{Coins{abc, def, def}}, 2}, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + if got := findDup(tt.args.coins); got != tt.want { t.Errorf("findDup() = %v, want %v", got, tt.want) } @@ -641,6 +697,8 @@ func TestFindDup(t *testing.T) { } func TestMarshalJSONCoins(t *testing.T) { + t.Parallel() + testCases := []struct { name string input Coins @@ -652,7 +710,11 @@ func TestMarshalJSONCoins(t *testing.T) { } for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + bz, err := amino.MarshalJSON(tc.input) require.NoError(t, err) require.Equal(t, tc.strOutput, string(bz)) diff --git a/tm2/pkg/std/kvpair_test.go b/tm2/pkg/std/kvpair_test.go index d030da48053..5edf750e6dd 100644 --- a/tm2/pkg/std/kvpair_test.go +++ b/tm2/pkg/std/kvpair_test.go @@ -7,6 +7,8 @@ import ( ) func TestKVPairs(t *testing.T) { + t.Parallel() + kvs := KVPairs{ {Key: []byte("k2"), Value: []byte("")}, {Key: []byte("k1"), Value: []byte("2")}, @@ -32,6 +34,8 @@ func TestKVPairs(t *testing.T) { } func TestKI64Pairs(t *testing.T) { + t.Parallel() + kvs := KI64Pairs{ {Key: []byte("k2"), Value: 0}, {Key: []byte("k1"), Value: 2}, diff --git a/tm2/pkg/store/cache/store_test.go b/tm2/pkg/store/cache/store_test.go index 5daf83fcb61..adf122fc637 100644 --- a/tm2/pkg/store/cache/store_test.go +++ b/tm2/pkg/store/cache/store_test.go @@ -22,6 +22,8 @@ func keyFmt(i int) []byte { return bz(fmt.Sprintf("key%0.8d", i)) } func valFmt(i int) []byte { return bz(fmt.Sprintf("value%0.8d", i)) } func TestCacheStore(t *testing.T) { + t.Parallel() + mem := dbadapter.Store{dbm.NewMemDB()} st := cache.New(mem) @@ -65,12 +67,16 @@ func TestCacheStore(t *testing.T) { } func TestCacheStoreNoNilSet(t *testing.T) { + t.Parallel() + mem := dbadapter.Store{dbm.NewMemDB()} st := cache.New(mem) require.Panics(t, func() { st.Set([]byte("key"), nil) }, "setting a nil value should panic") } func TestCacheStoreNested(t *testing.T) { + t.Parallel() + mem := dbadapter.Store{dbm.NewMemDB()} st := cache.New(mem) @@ -100,6 +106,8 @@ func TestCacheStoreNested(t *testing.T) { } func TestCacheKVIteratorBounds(t *testing.T) { + t.Parallel() + st := newCacheStore() // set some items @@ -151,6 +159,8 @@ func TestCacheKVIteratorBounds(t *testing.T) { } func TestCacheKVReverseIteratorBounds(t *testing.T) { + t.Parallel() + st := newCacheStore() // set some items @@ -195,6 +205,8 @@ func TestCacheKVReverseIteratorBounds(t *testing.T) { } func TestCacheKVMergeIteratorBasics(t *testing.T) { + t.Parallel() + st := newCacheStore() // set and delete an item in the cache, iterator should be empty @@ -243,6 +255,8 @@ func TestCacheKVMergeIteratorBasics(t *testing.T) { } func TestCacheKVMergeIteratorDeleteLast(t *testing.T) { + t.Parallel() + st := newCacheStore() // set some items and write them @@ -269,6 +283,8 @@ func TestCacheKVMergeIteratorDeleteLast(t *testing.T) { } func TestCacheKVMergeIteratorDeletes(t *testing.T) { + t.Parallel() + st := newCacheStore() truth := dbm.NewMemDB() @@ -303,6 +319,8 @@ func TestCacheKVMergeIteratorDeletes(t *testing.T) { } func TestCacheKVMergeIteratorChunks(t *testing.T) { + t.Parallel() + st := newCacheStore() // Use the truth to check values on the merge iterator @@ -334,6 +352,8 @@ func TestCacheKVMergeIteratorChunks(t *testing.T) { } func TestCacheKVMergeIteratorRandom(t *testing.T) { + t.Parallel() + st := newCacheStore() truth := dbm.NewMemDB() diff --git a/tm2/pkg/store/gas/store_test.go b/tm2/pkg/store/gas/store_test.go index ad335d73c24..54729abf2ed 100644 --- a/tm2/pkg/store/gas/store_test.go +++ b/tm2/pkg/store/gas/store_test.go @@ -19,6 +19,8 @@ func keyFmt(i int) []byte { return bz(fmt.Sprintf("key%0.8d", i)) } func valFmt(i int) []byte { return bz(fmt.Sprintf("value%0.8d", i)) } func TestGasKVStoreBasic(t *testing.T) { + t.Parallel() + mem := dbadapter.Store{dbm.NewMemDB()} meter := types.NewGasMeter(10000) st := gas.New(mem, meter, types.DefaultGasConfig()) @@ -31,6 +33,8 @@ func TestGasKVStoreBasic(t *testing.T) { } func TestGasKVStoreIterator(t *testing.T) { + t.Parallel() + mem := dbadapter.Store{dbm.NewMemDB()} meter := types.NewGasMeter(10000) st := gas.New(mem, meter, types.DefaultGasConfig()) @@ -55,6 +59,8 @@ func TestGasKVStoreIterator(t *testing.T) { } func TestGasKVStoreOutOfGasSet(t *testing.T) { + t.Parallel() + mem := dbadapter.Store{dbm.NewMemDB()} meter := types.NewGasMeter(0) st := gas.New(mem, meter, types.DefaultGasConfig()) @@ -62,6 +68,8 @@ func TestGasKVStoreOutOfGasSet(t *testing.T) { } func TestGasKVStoreOutOfGasIterator(t *testing.T) { + t.Parallel() + mem := dbadapter.Store{dbm.NewMemDB()} meter := types.NewGasMeter(20000) st := gas.New(mem, meter, types.DefaultGasConfig()) diff --git a/tm2/pkg/store/iavl/store_test.go b/tm2/pkg/store/iavl/store_test.go index 83afae91860..a29dbab096a 100644 --- a/tm2/pkg/store/iavl/store_test.go +++ b/tm2/pkg/store/iavl/store_test.go @@ -49,6 +49,8 @@ func newAlohaTree(t *testing.T, db dbm.DB) (*iavl.MutableTree, types.CommitID) { } func TestGetImmutable(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() tree, cID := newAlohaTree(t, db) store := UnsafeNewStore(tree, storeOptions(10, 10)) @@ -79,6 +81,8 @@ func TestGetImmutable(t *testing.T) { } func TestTestGetImmutableIterator(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() tree, cID := newAlohaTree(t, db) store := UnsafeNewStore(tree, storeOptions(10, 10)) @@ -102,6 +106,8 @@ func TestTestGetImmutableIterator(t *testing.T) { } func TestIAVLStoreGetSetHasDelete(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() tree, _ := newAlohaTree(t, db) iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) @@ -127,6 +133,8 @@ func TestIAVLStoreGetSetHasDelete(t *testing.T) { } func TestIAVLStoreNoNilSet(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() tree, _ := newAlohaTree(t, db) iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) @@ -134,6 +142,8 @@ func TestIAVLStoreNoNilSet(t *testing.T) { } func TestIAVLIterator(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() tree, _ := newAlohaTree(t, db) iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) @@ -207,6 +217,8 @@ func TestIAVLIterator(t *testing.T) { } func TestIAVLReverseIterator(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() tree := iavl.NewMutableTree(db, cacheSize) iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) @@ -240,6 +252,8 @@ func TestIAVLReverseIterator(t *testing.T) { } func TestIAVLPrefixIterator(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() tree := iavl.NewMutableTree(db, cacheSize) iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) @@ -302,6 +316,8 @@ func TestIAVLPrefixIterator(t *testing.T) { } func TestIAVLReversePrefixIterator(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() tree := iavl.NewMutableTree(db, cacheSize) iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) @@ -368,6 +384,8 @@ func nextVersion(iavl *Store) { } func TestIAVLDefaultPruning(t *testing.T) { + t.Parallel() + // Expected stored / deleted version numbers for: // numRecent = 5, storeEvery = 3 states := []pruneState{ @@ -392,6 +410,8 @@ func TestIAVLDefaultPruning(t *testing.T) { } func TestIAVLAlternativePruning(t *testing.T) { + t.Parallel() + // Expected stored / deleted version numbers for: // numRecent = 3, storeEvery = 5 states := []pruneState{ @@ -442,6 +462,8 @@ func testPruning(t *testing.T, numRecent int64, storeEvery int64, states []prune } func TestIAVLNoPrune(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() tree := iavl.NewMutableTree(db, cacheSize) iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, int64(1))) @@ -457,6 +479,8 @@ func TestIAVLNoPrune(t *testing.T) { } func TestIAVLPruneEverything(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() tree := iavl.NewMutableTree(db, cacheSize) iavlStore := UnsafeNewStore(tree, storeOptions(int64(0), int64(0))) @@ -475,6 +499,8 @@ func TestIAVLPruneEverything(t *testing.T) { } func TestIAVLStoreQuery(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() tree := iavl.NewMutableTree(db, cacheSize) iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) diff --git a/tm2/pkg/store/prefix/store_test.go b/tm2/pkg/store/prefix/store_test.go index 70f0eae05c8..6f70c5bd16f 100644 --- a/tm2/pkg/store/prefix/store_test.go +++ b/tm2/pkg/store/prefix/store_test.go @@ -88,6 +88,8 @@ func testPrefixStore(t *testing.T, baseStore types.Store, prefix []byte) { } func TestIAVLStorePrefix(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() tree := tiavl.NewMutableTree(db, cacheSize) iavlStore := iavl.UnsafeNewStore(tree, types.StoreOptions{ @@ -101,6 +103,8 @@ func TestIAVLStorePrefix(t *testing.T) { } func TestPrefixStoreNoNilSet(t *testing.T) { + t.Parallel() + meter := types.NewGasMeter(100000000) mem := dbadapter.Store{dbm.NewMemDB()} gasStore := gas.New(mem, meter, types.DefaultGasConfig()) @@ -108,6 +112,8 @@ func TestPrefixStoreNoNilSet(t *testing.T) { } func TestPrefixStoreIterate(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() baseStore := dbadapter.Store{db} prefix := []byte("test") @@ -135,6 +141,8 @@ func incFirstByte(bz []byte) { } func TestCloneAppend(t *testing.T) { + t.Parallel() + kvps := genRandomKVPairs() for _, kvp := range kvps { bz := cloneAppend(kvp.key, kvp.value) @@ -154,6 +162,8 @@ func TestCloneAppend(t *testing.T) { } func TestPrefixStoreIteratorEdgeCase(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() baseStore := dbadapter.Store{db} @@ -184,6 +194,8 @@ func TestPrefixStoreIteratorEdgeCase(t *testing.T) { } func TestPrefixStoreReverseIteratorEdgeCase(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() baseStore := dbadapter.Store{db} @@ -323,6 +335,8 @@ func checkNextPanics(t *testing.T, itr types.Iterator) { } func TestPrefixDBSimple(t *testing.T) { + t.Parallel() + store := mockStoreWithStuff() pstore := New(store, bz("key")) @@ -341,6 +355,8 @@ func TestPrefixDBSimple(t *testing.T) { } func TestPrefixDBIterator1(t *testing.T) { + t.Parallel() + store := mockStoreWithStuff() pstore := New(store, bz("key")) @@ -359,6 +375,8 @@ func TestPrefixDBIterator1(t *testing.T) { } func TestPrefixDBIterator2(t *testing.T) { + t.Parallel() + store := mockStoreWithStuff() pstore := New(store, bz("key")) @@ -369,6 +387,8 @@ func TestPrefixDBIterator2(t *testing.T) { } func TestPrefixDBIterator3(t *testing.T) { + t.Parallel() + store := mockStoreWithStuff() pstore := New(store, bz("key")) @@ -387,6 +407,8 @@ func TestPrefixDBIterator3(t *testing.T) { } func TestPrefixDBIterator4(t *testing.T) { + t.Parallel() + store := mockStoreWithStuff() pstore := New(store, bz("key")) @@ -397,6 +419,8 @@ func TestPrefixDBIterator4(t *testing.T) { } func TestPrefixDBReverseIterator1(t *testing.T) { + t.Parallel() + store := mockStoreWithStuff() pstore := New(store, bz("key")) @@ -415,6 +439,8 @@ func TestPrefixDBReverseIterator1(t *testing.T) { } func TestPrefixDBReverseIterator2(t *testing.T) { + t.Parallel() + store := mockStoreWithStuff() pstore := New(store, bz("key")) @@ -433,6 +459,8 @@ func TestPrefixDBReverseIterator2(t *testing.T) { } func TestPrefixDBReverseIterator3(t *testing.T) { + t.Parallel() + store := mockStoreWithStuff() pstore := New(store, bz("key")) @@ -443,6 +471,8 @@ func TestPrefixDBReverseIterator3(t *testing.T) { } func TestPrefixDBReverseIterator4(t *testing.T) { + t.Parallel() + store := mockStoreWithStuff() pstore := New(store, bz("key")) diff --git a/tm2/pkg/store/rootmulti/proof_test.go b/tm2/pkg/store/rootmulti/proof_test.go index 565ea59face..c79cbb07bd5 100644 --- a/tm2/pkg/store/rootmulti/proof_test.go +++ b/tm2/pkg/store/rootmulti/proof_test.go @@ -13,6 +13,8 @@ import ( ) func TestVerifyIAVLStoreQueryProof(t *testing.T) { + t.Parallel() + // Create main tree for testing. db := dbm.NewMemDB() opts := types.StoreOptions{ @@ -58,6 +60,8 @@ func TestVerifyIAVLStoreQueryProof(t *testing.T) { } func TestVerifyMultiStoreQueryProof(t *testing.T) { + t.Parallel() + // Create main tree for testing. db := dbm.NewMemDB() store := NewMultiStore(db) @@ -113,6 +117,8 @@ func TestVerifyMultiStoreQueryProof(t *testing.T) { } func TestVerifyMultiStoreQueryProofEmptyStore(t *testing.T) { + t.Parallel() + // Create main tree for testing. db := dbm.NewMemDB() store := NewMultiStore(db) @@ -142,6 +148,8 @@ func TestVerifyMultiStoreQueryProofEmptyStore(t *testing.T) { } func TestVerifyMultiStoreQueryProofAbsence(t *testing.T) { + t.Parallel() + // Create main tree for testing. db := dbm.NewMemDB() store := NewMultiStore(db) diff --git a/tm2/pkg/store/rootmulti/store_test.go b/tm2/pkg/store/rootmulti/store_test.go index e660f80c6bb..e6a04ee5ded 100644 --- a/tm2/pkg/store/rootmulti/store_test.go +++ b/tm2/pkg/store/rootmulti/store_test.go @@ -15,6 +15,8 @@ import ( ) func TestStoreType(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() store := NewMultiStore(db) store.MountStoreWithDB( @@ -22,6 +24,8 @@ func TestStoreType(t *testing.T) { } func TestStoreMount(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() store := NewMultiStore(db) @@ -37,6 +41,8 @@ func TestStoreMount(t *testing.T) { } func TestCacheMultiStoreWithVersion(t *testing.T) { + t.Parallel() + var db dbm.DB = dbm.NewMemDB() ms := newMultiStoreWithMounts(db) err := ms.LoadLatestVersion() @@ -74,6 +80,8 @@ func TestCacheMultiStoreWithVersion(t *testing.T) { } func TestHashStableWithEmptyCommit(t *testing.T) { + t.Parallel() + var db dbm.DB = dbm.NewMemDB() ms := newMultiStoreWithMounts(db) err := ms.LoadLatestVersion() @@ -98,6 +106,8 @@ func TestHashStableWithEmptyCommit(t *testing.T) { } func TestMultistoreCommitLoad(t *testing.T) { + t.Parallel() + var db dbm.DB = dbm.NewMemDB() store := newMultiStoreWithMounts(db) err := store.LoadLatestVersion() @@ -158,6 +168,8 @@ func TestMultistoreCommitLoad(t *testing.T) { } func TestParsePath(t *testing.T) { + t.Parallel() + _, _, err := parsePath("foo") require.Error(t, err) @@ -178,6 +190,8 @@ func TestParsePath(t *testing.T) { } func TestMultiStoreQuery(t *testing.T) { + t.Parallel() + db := dbm.NewMemDB() multi := newMultiStoreWithMounts(db) err := multi.LoadLatestVersion() diff --git a/tm2/pkg/store/types/gas_test.go b/tm2/pkg/store/types/gas_test.go index 7fef09227c5..410ba0b7e92 100644 --- a/tm2/pkg/store/types/gas_test.go +++ b/tm2/pkg/store/types/gas_test.go @@ -9,6 +9,8 @@ import ( ) func TestGasMeter(t *testing.T) { + t.Parallel() + cases := []struct { limit Gas usage []Gas @@ -46,6 +48,8 @@ func TestGasMeter(t *testing.T) { } func TestAddUint64Overflow(t *testing.T) { + t.Parallel() + testCases := []struct { a, b int64 result int64 diff --git a/tm2/pkg/strings/string_test.go b/tm2/pkg/strings/string_test.go index 1ec7b0d56be..55deac00b1f 100644 --- a/tm2/pkg/strings/string_test.go +++ b/tm2/pkg/strings/string_test.go @@ -9,6 +9,8 @@ import ( ) func TestStringInSlice(t *testing.T) { + t.Parallel() + assert.True(t, StringInSlice("a", []string{"a", "b", "c"})) assert.False(t, StringInSlice("d", []string{"a", "b", "c"})) assert.True(t, StringInSlice("", []string{""})) @@ -16,6 +18,8 @@ func TestStringInSlice(t *testing.T) { } func TestIsASCIIText(t *testing.T) { + t.Parallel() + notASCIIText := []string{ "", "\xC2", "\xC2\xA2", "\xFF", "\x80", "\xF0", "\n", "\t", } @@ -31,6 +35,8 @@ func TestIsASCIIText(t *testing.T) { } func TestASCIITrim(t *testing.T) { + t.Parallel() + assert.Equal(t, ASCIITrim(" "), "") assert.Equal(t, ASCIITrim(" a"), "a") assert.Equal(t, ASCIITrim("a "), "a") @@ -39,6 +45,8 @@ func TestASCIITrim(t *testing.T) { } func TestStringSliceEqual(t *testing.T) { + t.Parallel() + tests := []struct { a []string b []string diff --git a/tm2/pkg/timer/throttle_timer_test.go b/tm2/pkg/timer/throttle_timer_test.go index 2bee1dc0125..fb82fe39ff6 100644 --- a/tm2/pkg/timer/throttle_timer_test.go +++ b/tm2/pkg/timer/throttle_timer_test.go @@ -36,6 +36,8 @@ func (c *thCounter) Read() { } func TestThrottle(test *testing.T) { + test.Parallel() + assert := asrt.New(test) ms := 100 From da05213ffef88ad013b6a0ebcff965c1f2156826 Mon Sep 17 00:00:00 2001 From: Jeff Thompson Date: Thu, 9 Nov 2023 17:18:53 +0100 Subject: [PATCH 21/25] fix: In Keybase GetByAddress, change generic error to NewErrKeyNotFound (#1316) The Keybase method `GetByName` [returns the specific error](https://github.com/gnolang/gno/blob/199cd29584d44812a0aec3606bbff37a320c609a/tm2/pkg/crypto/keys/keybase.go#L184) `ErrKeyNotFound` if the key is not found. This is very nice because the GnoMobile API wraps this with a gRPC function and we use `keyerror.IsErrKeyNotFound` to check the error type and convert it to the gRPC equivalent. But the Keybase method `GetByAddress` just [returns a generic error](https://github.com/gnolang/gno/blob/199cd29584d44812a0aec3606bbff37a320c609a/tm2/pkg/crypto/keys/keybase.go#L192) if the key isn't found. (I assume that it is not intentional to restrict this to a generic error.) This means that the gRPC interface must search the error string for "not found", which is unreliable. We would prefer to use `keyerror.IsErrKeyNotFound`. Furthermore, `GetByNameOrAddress` [can return an error from either](https://github.com/gnolang/gno/blob/199cd29584d44812a0aec3606bbff37a320c609a/tm2/pkg/crypto/keys/keybase.go#L175-L177) `GetByName` or `GetByAddress`. It is preferable to return just one error type for key not found. This pull request updates `GetByAddress` to use `keyerror.NewErrKeyNotFound` with the same error message.
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [ ] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
Signed-off-by: Jeff Thompson --- tm2/pkg/crypto/keys/keybase.go | 2 +- tm2/pkg/crypto/keys/keybase_test.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tm2/pkg/crypto/keys/keybase.go b/tm2/pkg/crypto/keys/keybase.go index 13f6e00979d..06eaf54f503 100644 --- a/tm2/pkg/crypto/keys/keybase.go +++ b/tm2/pkg/crypto/keys/keybase.go @@ -181,7 +181,7 @@ func (kb dbKeybase) GetByName(name string) (Info, error) { func (kb dbKeybase) GetByAddress(address crypto.Address) (Info, error) { ik := kb.db.Get(addrKey(address)) if len(ik) == 0 { - return nil, fmt.Errorf("key with address %s not found", address) + return nil, keyerror.NewErrKeyNotFound(fmt.Sprintf("key with address %s not found", address)) } bs := kb.db.Get(ik) return readInfo(bs) diff --git a/tm2/pkg/crypto/keys/keybase_test.go b/tm2/pkg/crypto/keys/keybase_test.go index cae5f2af947..e80c6c3cd03 100644 --- a/tm2/pkg/crypto/keys/keybase_test.go +++ b/tm2/pkg/crypto/keys/keybase_test.go @@ -9,6 +9,7 @@ import ( "github.com/gnolang/gno/tm2/pkg/crypto" "github.com/gnolang/gno/tm2/pkg/crypto/ed25519" + "github.com/gnolang/gno/tm2/pkg/crypto/keys/keyerror" ) func TestCreateAccountInvalidMnemonic(t *testing.T) { @@ -107,6 +108,7 @@ func TestKeyManagement(t *testing.T) { require.NoError(t, err) _, err = cstore.GetByAddress(addr) require.NotNil(t, err) + require.True(t, keyerror.IsErrKeyNotFound(err)) // list shows them in order keyS, err := cstore.List() From 39ea6620d327a506340182fc7043d623ba7c9507 Mon Sep 17 00:00:00 2001 From: Manfred Touron <94029+moul@users.noreply.github.com> Date: Thu, 9 Nov 2023 18:38:56 +0100 Subject: [PATCH 22/25] feat: add contribs/gnokeykc (#1270) ## Done - add a `contribs/gnokeykc` wrapper (adding keychain support). - make `tm2/commands.IO` an interface instead of a struct. ## Usage ```console $ gnokeykc kc set Enter password. Successfully added password for key. $ gnokeykc maketx send --send 1ugnot --to g1fsu3z335h5qngf7t3lmakvpmpwg9ae76tqwh7c --chainid test3 --remote test3.gno.land:36657 --gas-fee "1000000ugnot" --gas-wanted "2000000" --broadcast moul OK! GAS WANTED: 2000000 GAS USED: 47072 ``` ## Links - [x] Depends on #1256 (for contribs/' Makefile & CI) --------- Signed-off-by: moul <94029+moul@users.noreply.github.com> --- contribs/gnokeykc/README.md | 16 ++ contribs/gnokeykc/go.mod | 54 ++++++ contribs/gnokeykc/go.sum | 237 +++++++++++++++++++++++ contribs/gnokeykc/kc.go | 94 +++++++++ contribs/gnokeykc/main.go | 32 +++ gno.land/cmd/genesis/balances.go | 2 +- gno.land/cmd/genesis/balances_add.go | 6 +- gno.land/cmd/genesis/balances_export.go | 4 +- gno.land/cmd/genesis/balances_remove.go | 4 +- gno.land/cmd/genesis/generate.go | 4 +- gno.land/cmd/genesis/main.go | 2 +- gno.land/cmd/genesis/txs.go | 2 +- gno.land/cmd/genesis/txs_add.go | 4 +- gno.land/cmd/genesis/txs_export.go | 4 +- gno.land/cmd/genesis/txs_remove.go | 4 +- gno.land/cmd/genesis/validator.go | 2 +- gno.land/cmd/genesis/validator_add.go | 4 +- gno.land/cmd/genesis/validator_remove.go | 4 +- gno.land/cmd/genesis/verify.go | 4 +- gno.land/cmd/gnofaucet/serve.go | 4 +- gno.land/cmd/gnoland/root.go | 2 +- gno.land/cmd/gnoland/start.go | 8 +- gnovm/cmd/gno/build.go | 4 +- gnovm/cmd/gno/clean.go | 6 +- gnovm/cmd/gno/doc.go | 6 +- gnovm/cmd/gno/lint.go | 8 +- gnovm/cmd/gno/main.go | 2 +- gnovm/cmd/gno/mod.go | 10 +- gnovm/cmd/gno/precompile.go | 4 +- gnovm/cmd/gno/run.go | 10 +- gnovm/cmd/gno/test.go | 14 +- tm2/pkg/commands/io.go | 69 ++++--- tm2/pkg/commands/utils.go | 10 +- tm2/pkg/crypto/keys/client/add.go | 8 +- tm2/pkg/crypto/keys/client/addpkg.go | 6 +- tm2/pkg/crypto/keys/client/broadcast.go | 4 +- tm2/pkg/crypto/keys/client/call.go | 4 +- tm2/pkg/crypto/keys/client/delete.go | 6 +- tm2/pkg/crypto/keys/client/export.go | 4 +- tm2/pkg/crypto/keys/client/generate.go | 4 +- tm2/pkg/crypto/keys/client/import.go | 4 +- tm2/pkg/crypto/keys/client/list.go | 6 +- tm2/pkg/crypto/keys/client/maketx.go | 2 +- tm2/pkg/crypto/keys/client/query.go | 4 +- tm2/pkg/crypto/keys/client/root.go | 2 +- tm2/pkg/crypto/keys/client/send.go | 4 +- tm2/pkg/crypto/keys/client/sign.go | 4 +- tm2/pkg/crypto/keys/client/verify.go | 4 +- 48 files changed, 582 insertions(+), 124 deletions(-) create mode 100644 contribs/gnokeykc/README.md create mode 100644 contribs/gnokeykc/go.mod create mode 100644 contribs/gnokeykc/go.sum create mode 100644 contribs/gnokeykc/kc.go create mode 100644 contribs/gnokeykc/main.go diff --git a/contribs/gnokeykc/README.md b/contribs/gnokeykc/README.md new file mode 100644 index 00000000000..5d508b4b221 --- /dev/null +++ b/contribs/gnokeykc/README.md @@ -0,0 +1,16 @@ +# `gnokeykc` + +`gnokeykc` is a Go-based CLI tool that enhances [`gnokey`](../../gno.land/cmd/gnokey) by integrating with your system's keychain. It adds `gnokey kc ...` subcommands to set and unset passwords in the keychain, allowing Gnokey to fetch passwords directly from the keychain instead of prompting for terminal input. + +## Usage + + gnokey kc -h + +## Terminal Alias + +For ease of use, set up a terminal alias to replace `gnokey` with `gnokeykc`: + + echo "alias gnokey='gnokeykc'" >> ~/.bashrc && source ~/.bashrc + +Now, `gnokey` commands will use `gnokeykc`, fetching passwords from the keychain. + diff --git a/contribs/gnokeykc/go.mod b/contribs/gnokeykc/go.mod new file mode 100644 index 00000000000..fca27e7455a --- /dev/null +++ b/contribs/gnokeykc/go.mod @@ -0,0 +1,54 @@ +module github.com/gnolang/gno/contribs/gnokeykc + +go 1.20 + +replace github.com/gnolang/gno => ../.. + +require ( + github.com/gnolang/gno v0.0.0-00010101000000-000000000000 + github.com/zalando/go-keyring v0.2.3 +) + +require ( + github.com/alessio/shellescape v1.4.1 // indirect + github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c // indirect + github.com/btcsuite/btcd/btcutil v1.0.0 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/cockroachdb/apd v1.1.0 // indirect + github.com/danieljoos/wincred v1.2.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgraph-io/badger/v3 v3.2103.4 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/gnolang/goleveldb v0.0.9 // indirect + github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect + github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/flatbuffers v1.12.1 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/jmhodges/levigo v1.0.0 // indirect + github.com/klauspost/compress v1.12.3 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/linxGnu/grocksdb v1.8.4 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/peterbourgon/ff/v3 v3.4.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rs/cors v1.10.1 // indirect + github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect + go.etcd.io/bbolt v1.3.7 // indirect + go.opencensus.io v0.22.5 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/tools v0.13.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect +) diff --git a/contribs/gnokeykc/go.sum b/contribs/gnokeykc/go.sum new file mode 100644 index 00000000000..9ab29663ae6 --- /dev/null +++ b/contribs/gnokeykc/go.sum @@ -0,0 +1,237 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= +github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c h1:lnAMg3ra/Gw4AkRMxrxYs8nrprWsHowg8H9zaYsJOo4= +github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= +github.com/btcsuite/btcd/btcutil v1.0.0 h1:dB36qRTOucIh6NUe40UCieOS+axPhP6VNyRtYkTUKKk= +github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= +github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger/v3 v3.2103.4 h1:WE1B07YNTTJTtG9xjBcSW2wn0RJLyiV99h959RKZqM4= +github.com/dgraph-io/badger/v3 v3.2103.4/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gnolang/goleveldb v0.0.9 h1:Q7rGko9oXMKtQA+Apeeed5a3sjba/mcDhzJGoTVLCKE= +github.com/gnolang/goleveldb v0.0.9/go.mod h1:Dz6p9bmpy/FBESTgduiThZt5mToVDipcHGzj/zUOo8E= +github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 h1:GKvsK3oLWG9B1GL7WP/VqwM6C92j5tIvB844oggL9Lk= +github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216/go.mod h1:xJhtEL7ahjM1WJipt89gel8tHzfIl/LyMY+lCYh38d8= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jaekwon/testify v1.6.1 h1:4AtAJcR9GzXN5W4DdY7ie74iCPiJV1JJUJL90t2ZUyw= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= +github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/linxGnu/grocksdb v1.8.4 h1:ZMsBpPpJNtRLHiKKp0mI7gW+NT4s7UgfD5xHxx1jVRo= +github.com/linxGnu/grocksdb v1.8.4/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/peterbourgon/ff/v3 v3.4.0 h1:QBvM/rizZM1cB0p0lGMdmR7HxZeI/ZrBWB4DqLkMUBc= +github.com/peterbourgon/ff/v3 v3.4.0/go.mod h1:zjJVUhx+twciwfDl0zBcFzl4dW8axCRyXE/eKY9RztQ= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= +github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zalando/go-keyring v0.2.3 h1:v9CUu9phlABObO4LPWycf+zwMG7nlbb3t/B5wa97yms= +github.com/zalando/go-keyring v0.2.3/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +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-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/contribs/gnokeykc/kc.go b/contribs/gnokeykc/kc.go new file mode 100644 index 00000000000..f91dc8ba4dd --- /dev/null +++ b/contribs/gnokeykc/kc.go @@ -0,0 +1,94 @@ +package main + +import ( + "context" + "flag" + "fmt" + + "github.com/gnolang/gno/tm2/pkg/commands" + "github.com/zalando/go-keyring" +) + +const ( + kcService = "gnokey" + kcName = "encryption" +) + +func newKcCmd(io commands.IO) *commands.Command { + cmd := commands.NewCommand( + commands.Metadata{ + Name: "kc", + ShortUsage: "kc ", + ShortHelp: "Manage OS keychain", + }, + commands.NewEmptyConfig(), + commands.HelpExec, + ) + cmd.AddSubCommands( + newKcSetCmd(io), + newKcUnsetCmd(io), + ) + return cmd +} + +func newKcSetCmd(io commands.IO) *commands.Command { + return commands.NewCommand( + commands.Metadata{ + Name: "set", + ShortUsage: "set", + ShortHelp: "set encryption password in OS keychain", + }, + commands.NewEmptyConfig(), + func(_ context.Context, args []string) error { + return execKcSet(args, io) + }, + ) +} + +func execKcSet(args []string, io commands.IO) error { + if len(args) != 0 { + return flag.ErrHelp + } + + insecurePasswordStdin := false // XXX: cfg.rootCfg.InsecurePasswordStdin + password, err := io.GetPassword("Enter password.", insecurePasswordStdin) + if err != nil { + return fmt.Errorf("cannot read password: %w", err) + } + + err = keyring.Set(kcService, kcName, password) + if err != nil { + return fmt.Errorf("cannot set password is OS keychain") + } + + io.Printfln("Successfully added password for key.") + return nil +} + +func newKcUnsetCmd(io commands.IO) *commands.Command { + return commands.NewCommand( + commands.Metadata{ + Name: "unset", + ShortUsage: "unset", + ShortHelp: "unset password in OS keychain", + }, + commands.NewEmptyConfig(), + func(_ context.Context, args []string) error { + return execKcUnset(args, io) + }, + ) +} + +func execKcUnset(args []string, io commands.IO) error { + if len(args) != 0 { + return flag.ErrHelp + } + + err := keyring.Delete(kcService, kcName) + if err != nil { + return fmt.Errorf("cannot unset password from OS keychain") + } + + io.Printfln("Successfully unset password") + return nil +} diff --git a/contribs/gnokeykc/main.go b/contribs/gnokeykc/main.go new file mode 100644 index 00000000000..8060f8cb1e3 --- /dev/null +++ b/contribs/gnokeykc/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "context" + "fmt" + "os" + + "github.com/gnolang/gno/tm2/pkg/commands" + "github.com/gnolang/gno/tm2/pkg/crypto/keys/client" + "github.com/zalando/go-keyring" +) + +func main() { + stdio := commands.NewDefaultIO() + wrappedio := &wrappedIO{IO: stdio} + cmd := client.NewRootCmd(wrappedio) + cmd.AddSubCommands(newKcCmd(stdio)) + + if err := cmd.ParseAndRun(context.Background(), os.Args[1:]); err != nil { + _, _ = fmt.Fprintf(os.Stderr, "%+v\n", err) + + os.Exit(1) + } +} + +type wrappedIO struct { + commands.IO +} + +func (io *wrappedIO) GetPassword(prompt string, insecure bool) (string, error) { + return keyring.Get(kcService, kcName) +} diff --git a/gno.land/cmd/genesis/balances.go b/gno.land/cmd/genesis/balances.go index bb6cd8b532c..0e81f280f33 100644 --- a/gno.land/cmd/genesis/balances.go +++ b/gno.land/cmd/genesis/balances.go @@ -11,7 +11,7 @@ type balancesCfg struct { } // newBalancesCmd creates the genesis balances subcommand -func newBalancesCmd(io *commands.IO) *commands.Command { +func newBalancesCmd(io commands.IO) *commands.Command { cfg := &balancesCfg{} cmd := commands.NewCommand( diff --git a/gno.land/cmd/genesis/balances_add.go b/gno.land/cmd/genesis/balances_add.go index 8df193c770c..d1e88efcc6b 100644 --- a/gno.land/cmd/genesis/balances_add.go +++ b/gno.land/cmd/genesis/balances_add.go @@ -35,7 +35,7 @@ type balancesAddCfg struct { } // newBalancesAddCmd creates the genesis balances add subcommand -func newBalancesAddCmd(rootCfg *balancesCfg, io *commands.IO) *commands.Command { +func newBalancesAddCmd(rootCfg *balancesCfg, io commands.IO) *commands.Command { cfg := &balancesAddCfg{ rootCfg: rootCfg, } @@ -75,7 +75,7 @@ func (c *balancesAddCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execBalancesAdd(ctx context.Context, cfg *balancesAddCfg, io *commands.IO) error { +func execBalancesAdd(ctx context.Context, cfg *balancesAddCfg, io commands.IO) error { // Load the genesis genesis, loadErr := types.GenesisDocFromFile(cfg.rootCfg.genesisPath) if loadErr != nil { @@ -232,7 +232,7 @@ func getBalancesFromSheet(sheet io.Reader) (accountBalances, error) { // and construct a balance sheet based off of this information func getBalancesFromTransactions( ctx context.Context, - io *commands.IO, + io commands.IO, reader io.Reader, ) (accountBalances, error) { balances := make(accountBalances) diff --git a/gno.land/cmd/genesis/balances_export.go b/gno.land/cmd/genesis/balances_export.go index fd5ade26663..c07f250afeb 100644 --- a/gno.land/cmd/genesis/balances_export.go +++ b/gno.land/cmd/genesis/balances_export.go @@ -11,7 +11,7 @@ import ( ) // newBalancesExportCmd creates the genesis balances export subcommand -func newBalancesExportCmd(balancesCfg *balancesCfg, io *commands.IO) *commands.Command { +func newBalancesExportCmd(balancesCfg *balancesCfg, io commands.IO) *commands.Command { return commands.NewCommand( commands.Metadata{ Name: "export", @@ -26,7 +26,7 @@ func newBalancesExportCmd(balancesCfg *balancesCfg, io *commands.IO) *commands.C ) } -func execBalancesExport(cfg *balancesCfg, io *commands.IO, args []string) error { +func execBalancesExport(cfg *balancesCfg, io commands.IO, args []string) error { // Load the genesis genesis, loadErr := types.GenesisDocFromFile(cfg.genesisPath) if loadErr != nil { diff --git a/gno.land/cmd/genesis/balances_remove.go b/gno.land/cmd/genesis/balances_remove.go index f4286d95ad2..a752bbda4fd 100644 --- a/gno.land/cmd/genesis/balances_remove.go +++ b/gno.land/cmd/genesis/balances_remove.go @@ -24,7 +24,7 @@ type balancesRemoveCfg struct { } // newBalancesRemoveCmd creates the genesis balances remove subcommand -func newBalancesRemoveCmd(rootCfg *balancesCfg, io *commands.IO) *commands.Command { +func newBalancesRemoveCmd(rootCfg *balancesCfg, io commands.IO) *commands.Command { cfg := &balancesRemoveCfg{ rootCfg: rootCfg, } @@ -51,7 +51,7 @@ func (c *balancesRemoveCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execBalancesRemove(cfg *balancesRemoveCfg, io *commands.IO) error { +func execBalancesRemove(cfg *balancesRemoveCfg, io commands.IO) error { // Load the genesis genesis, loadErr := types.GenesisDocFromFile(cfg.rootCfg.genesisPath) if loadErr != nil { diff --git a/gno.land/cmd/genesis/generate.go b/gno.land/cmd/genesis/generate.go index 93f8553f9e7..684f8441874 100644 --- a/gno.land/cmd/genesis/generate.go +++ b/gno.land/cmd/genesis/generate.go @@ -23,7 +23,7 @@ type generateCfg struct { } // newGenerateCmd creates the genesis generate subcommand -func newGenerateCmd(io *commands.IO) *commands.Command { +func newGenerateCmd(io commands.IO) *commands.Command { cfg := &generateCfg{} return commands.NewCommand( @@ -91,7 +91,7 @@ func (c *generateCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execGenerate(cfg *generateCfg, io *commands.IO) error { +func execGenerate(cfg *generateCfg, io commands.IO) error { // Start with the default configuration genesis := getDefaultGenesis() diff --git a/gno.land/cmd/genesis/main.go b/gno.land/cmd/genesis/main.go index c0b043b456a..507d004e8ed 100644 --- a/gno.land/cmd/genesis/main.go +++ b/gno.land/cmd/genesis/main.go @@ -20,7 +20,7 @@ func main() { } } -func newRootCmd(io *commands.IO) *commands.Command { +func newRootCmd(io commands.IO) *commands.Command { cmd := commands.NewCommand( commands.Metadata{ ShortUsage: " [flags] [...]", diff --git a/gno.land/cmd/genesis/txs.go b/gno.land/cmd/genesis/txs.go index a7be307c4be..a292a9c01de 100644 --- a/gno.land/cmd/genesis/txs.go +++ b/gno.land/cmd/genesis/txs.go @@ -11,7 +11,7 @@ type txsCfg struct { } // newTxsCmd creates the genesis txs subcommand -func newTxsCmd(io *commands.IO) *commands.Command { +func newTxsCmd(io commands.IO) *commands.Command { cfg := &txsCfg{} cmd := commands.NewCommand( diff --git a/gno.land/cmd/genesis/txs_add.go b/gno.land/cmd/genesis/txs_add.go index 027cedae0bd..e356badc4aa 100644 --- a/gno.land/cmd/genesis/txs_add.go +++ b/gno.land/cmd/genesis/txs_add.go @@ -22,7 +22,7 @@ var ( ) // newTxsAddCmd creates the genesis txs add subcommand -func newTxsAddCmd(txsCfg *txsCfg, io *commands.IO) *commands.Command { +func newTxsAddCmd(txsCfg *txsCfg, io commands.IO) *commands.Command { return commands.NewCommand( commands.Metadata{ Name: "add", @@ -40,7 +40,7 @@ func newTxsAddCmd(txsCfg *txsCfg, io *commands.IO) *commands.Command { func execTxsAdd( ctx context.Context, cfg *txsCfg, - io *commands.IO, + io commands.IO, args []string, ) error { // Load the genesis diff --git a/gno.land/cmd/genesis/txs_export.go b/gno.land/cmd/genesis/txs_export.go index 170166e8a37..b06660d87d4 100644 --- a/gno.land/cmd/genesis/txs_export.go +++ b/gno.land/cmd/genesis/txs_export.go @@ -15,7 +15,7 @@ import ( var errNoOutputFile = errors.New("no output file path specified") // newTxsExportCmd creates the genesis txs export subcommand -func newTxsExportCmd(txsCfg *txsCfg, io *commands.IO) *commands.Command { +func newTxsExportCmd(txsCfg *txsCfg, io commands.IO) *commands.Command { return commands.NewCommand( commands.Metadata{ Name: "export", @@ -30,7 +30,7 @@ func newTxsExportCmd(txsCfg *txsCfg, io *commands.IO) *commands.Command { ) } -func execTxsExport(cfg *txsCfg, io *commands.IO, args []string) error { +func execTxsExport(cfg *txsCfg, io commands.IO, args []string) error { // Load the genesis genesis, loadErr := types.GenesisDocFromFile(cfg.genesisPath) if loadErr != nil { diff --git a/gno.land/cmd/genesis/txs_remove.go b/gno.land/cmd/genesis/txs_remove.go index 2aef44fe1e5..7893ad50cac 100644 --- a/gno.land/cmd/genesis/txs_remove.go +++ b/gno.land/cmd/genesis/txs_remove.go @@ -20,7 +20,7 @@ var ( ) // newTxsRemoveCmd creates the genesis txs remove subcommand -func newTxsRemoveCmd(txsCfg *txsCfg, io *commands.IO) *commands.Command { +func newTxsRemoveCmd(txsCfg *txsCfg, io commands.IO) *commands.Command { return commands.NewCommand( commands.Metadata{ Name: "remove", @@ -35,7 +35,7 @@ func newTxsRemoveCmd(txsCfg *txsCfg, io *commands.IO) *commands.Command { ) } -func execTxsRemove(cfg *txsCfg, io *commands.IO, args []string) error { +func execTxsRemove(cfg *txsCfg, io commands.IO, args []string) error { // Load the genesis genesis, loadErr := types.GenesisDocFromFile(cfg.genesisPath) if loadErr != nil { diff --git a/gno.land/cmd/genesis/validator.go b/gno.land/cmd/genesis/validator.go index a1fee07d070..bf858a7732e 100644 --- a/gno.land/cmd/genesis/validator.go +++ b/gno.land/cmd/genesis/validator.go @@ -13,7 +13,7 @@ type validatorCfg struct { } // newValidatorCmd creates the genesis validator subcommand -func newValidatorCmd(io *commands.IO) *commands.Command { +func newValidatorCmd(io commands.IO) *commands.Command { cfg := &validatorCfg{ commonCfg: commonCfg{}, } diff --git a/gno.land/cmd/genesis/validator_add.go b/gno.land/cmd/genesis/validator_add.go index 603bfa90caa..502b572effb 100644 --- a/gno.land/cmd/genesis/validator_add.go +++ b/gno.land/cmd/genesis/validator_add.go @@ -28,7 +28,7 @@ type validatorAddCfg struct { } // newValidatorAddCmd creates the genesis validator add subcommand -func newValidatorAddCmd(validatorCfg *validatorCfg, io *commands.IO) *commands.Command { +func newValidatorAddCmd(validatorCfg *validatorCfg, io commands.IO) *commands.Command { cfg := &validatorAddCfg{ rootCfg: validatorCfg, } @@ -69,7 +69,7 @@ func (c *validatorAddCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execValidatorAdd(cfg *validatorAddCfg, io *commands.IO) error { +func execValidatorAdd(cfg *validatorAddCfg, io commands.IO) error { // Load the genesis genesis, loadErr := types.GenesisDocFromFile(cfg.rootCfg.genesisPath) if loadErr != nil { diff --git a/gno.land/cmd/genesis/validator_remove.go b/gno.land/cmd/genesis/validator_remove.go index f769b53b0e1..960d891239b 100644 --- a/gno.land/cmd/genesis/validator_remove.go +++ b/gno.land/cmd/genesis/validator_remove.go @@ -13,7 +13,7 @@ import ( var errValidatorNotPresent = errors.New("validator not present in genesis.json") // newValidatorRemoveCmd creates the genesis validator remove subcommand -func newValidatorRemoveCmd(rootCfg *validatorCfg, io *commands.IO) *commands.Command { +func newValidatorRemoveCmd(rootCfg *validatorCfg, io commands.IO) *commands.Command { return commands.NewCommand( commands.Metadata{ Name: "remove", @@ -27,7 +27,7 @@ func newValidatorRemoveCmd(rootCfg *validatorCfg, io *commands.IO) *commands.Com ) } -func execValidatorRemove(cfg *validatorCfg, io *commands.IO) error { +func execValidatorRemove(cfg *validatorCfg, io commands.IO) error { // Load the genesis genesis, loadErr := types.GenesisDocFromFile(cfg.genesisPath) if loadErr != nil { diff --git a/gno.land/cmd/genesis/verify.go b/gno.land/cmd/genesis/verify.go index 6c877ca51ec..260a9eb734d 100644 --- a/gno.land/cmd/genesis/verify.go +++ b/gno.land/cmd/genesis/verify.go @@ -18,7 +18,7 @@ type verifyCfg struct { } // newVerifyCmd creates the genesis verify subcommand -func newVerifyCmd(io *commands.IO) *commands.Command { +func newVerifyCmd(io commands.IO) *commands.Command { cfg := &verifyCfg{} return commands.NewCommand( @@ -39,7 +39,7 @@ func (c *verifyCfg) RegisterFlags(fs *flag.FlagSet) { c.commonCfg.RegisterFlags(fs) } -func execVerify(cfg *verifyCfg, io *commands.IO) error { +func execVerify(cfg *verifyCfg, io commands.IO) error { // Load the genesis genesis, loadErr := types.GenesisDocFromFile(cfg.genesisPath) if loadErr != nil { diff --git a/gno.land/cmd/gnofaucet/serve.go b/gno.land/cmd/gnofaucet/serve.go index 3fe0966592c..e00406a6e80 100644 --- a/gno.land/cmd/gnofaucet/serve.go +++ b/gno.land/cmd/gnofaucet/serve.go @@ -152,7 +152,7 @@ func (c *config) RegisterFlags(fs *flag.FlagSet) { ) } -func execServe(cfg *config, args []string, io *commands.IO) error { +func execServe(cfg *config, args []string, io commands.IO) error { if len(args) != 1 { return flag.ErrHelp } @@ -345,7 +345,7 @@ func execServe(cfg *config, args []string, io *commands.IO) error { func sendAmountTo( cfg *config, cli rpcclient.Client, - io *commands.IO, + io commands.IO, name, pass string, toAddr crypto.Address, diff --git a/gno.land/cmd/gnoland/root.go b/gno.land/cmd/gnoland/root.go index 5b2cbe0e4fe..dfb595347c0 100644 --- a/gno.land/cmd/gnoland/root.go +++ b/gno.land/cmd/gnoland/root.go @@ -19,7 +19,7 @@ func main() { } } -func newRootCmd(io *commands.IO) *commands.Command { +func newRootCmd(io commands.IO) *commands.Command { cmd := commands.NewCommand( commands.Metadata{ ShortUsage: " [flags] [...]", diff --git a/gno.land/cmd/gnoland/start.go b/gno.land/cmd/gnoland/start.go index 618f4f87a09..77d6eb4ed51 100644 --- a/gno.land/cmd/gnoland/start.go +++ b/gno.land/cmd/gnoland/start.go @@ -42,7 +42,7 @@ type startCfg struct { nodeConfigPath string } -func newStartCmd(io *commands.IO) *commands.Command { +func newStartCmd(io commands.IO) *commands.Command { cfg := &startCfg{} return commands.NewCommand( @@ -173,8 +173,8 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execStart(c *startCfg, io *commands.IO) error { - logger := log.NewTMLogger(log.NewSyncWriter(io.Out)) +func execStart(c *startCfg, io commands.IO) error { + logger := log.NewTMLogger(log.NewSyncWriter(io.Out())) dataDir := c.dataDir var ( @@ -232,7 +232,7 @@ func execStart(c *startCfg, io *commands.IO) error { return fmt.Errorf("error in creating node: %w", err) } - fmt.Fprintln(io.Err, "Node created.") + fmt.Fprintln(io.Err(), "Node created.") if c.skipStart { io.ErrPrintln("'--skip-start' is set. Exiting.") diff --git a/gnovm/cmd/gno/build.go b/gnovm/cmd/gno/build.go index b80711586e4..7396d17fd8f 100644 --- a/gnovm/cmd/gno/build.go +++ b/gnovm/cmd/gno/build.go @@ -20,7 +20,7 @@ var defaultBuildOptions = &buildCfg{ goBinary: "go", } -func newBuildCmd(io *commands.IO) *commands.Command { +func newBuildCmd(io commands.IO) *commands.Command { cfg := &buildCfg{} return commands.NewCommand( @@ -52,7 +52,7 @@ func (c *buildCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execBuild(cfg *buildCfg, args []string, io *commands.IO) error { +func execBuild(cfg *buildCfg, args []string, io commands.IO) error { if len(args) < 1 { return flag.ErrHelp } diff --git a/gnovm/cmd/gno/clean.go b/gnovm/cmd/gno/clean.go index 999cc5f1f53..dad5332c4fa 100644 --- a/gnovm/cmd/gno/clean.go +++ b/gnovm/cmd/gno/clean.go @@ -20,7 +20,7 @@ type cleanCfg struct { modCache bool // clean -modcache flag } -func newCleanCmd(io *commands.IO) *commands.Command { +func newCleanCmd(io commands.IO) *commands.Command { cfg := &cleanCfg{} return commands.NewCommand( @@ -59,7 +59,7 @@ func (c *cleanCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execClean(cfg *cleanCfg, args []string, io *commands.IO) error { +func execClean(cfg *cleanCfg, args []string, io commands.IO) error { if len(args) > 0 { return flag.ErrHelp } @@ -96,7 +96,7 @@ func execClean(cfg *cleanCfg, args []string, io *commands.IO) error { } // clean removes generated files from a directory. -func clean(dir string, cfg *cleanCfg, io *commands.IO) error { +func clean(dir string, cfg *cleanCfg, io commands.IO) error { return filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error { if err != nil { return err diff --git a/gnovm/cmd/gno/doc.go b/gnovm/cmd/gno/doc.go index 0de49470c2a..4617c31741e 100644 --- a/gnovm/cmd/gno/doc.go +++ b/gnovm/cmd/gno/doc.go @@ -22,7 +22,7 @@ type docCfg struct { rootDir string } -func newDocCmd(io *commands.IO) *commands.Command { +func newDocCmd(io commands.IO) *commands.Command { c := &docCfg{} return commands.NewCommand( commands.Metadata{ @@ -74,7 +74,7 @@ func (c *docCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execDoc(cfg *docCfg, args []string, io *commands.IO) error { +func execDoc(cfg *docCfg, args []string, io commands.IO) error { // guess opts.RootDir if cfg.rootDir == "" { cfg.rootDir = guessRootDir() @@ -112,7 +112,7 @@ func execDoc(cfg *docCfg, args []string, io *commands.IO) error { io.Printfln("warning: error parsing some candidate packages:\n%v", err) } return res.WriteDocumentation( - io.Out, + io.Out(), &doc.WriteDocumentationOptions{ ShowAll: cfg.all, Source: cfg.src, diff --git a/gnovm/cmd/gno/lint.go b/gnovm/cmd/gno/lint.go index 7acd9877770..ad223afa3b0 100644 --- a/gnovm/cmd/gno/lint.go +++ b/gnovm/cmd/gno/lint.go @@ -19,7 +19,7 @@ type lintCfg struct { // auto-fix: apply suggested fixes automatically. } -func newLintCmd(io *commands.IO) *commands.Command { +func newLintCmd(io commands.IO) *commands.Command { cfg := &lintCfg{} return commands.NewCommand( @@ -41,7 +41,7 @@ func (c *lintCfg) RegisterFlags(fs *flag.FlagSet) { fs.IntVar(&c.setExitStatus, "set-exit-status", 1, "set exit status to 1 if any issues are found") } -func execLint(cfg *lintCfg, args []string, io *commands.IO) error { +func execLint(cfg *lintCfg, args []string, io commands.IO) error { if len(args) < 1 { return flag.ErrHelp } @@ -62,12 +62,12 @@ func execLint(cfg *lintCfg, args []string, io *commands.IO) error { hasError := false addIssue := func(issue lintIssue) { hasError = true - fmt.Fprint(io.Err, issue.String()+"\n") + fmt.Fprint(io.Err(), issue.String()+"\n") } for _, pkgPath := range pkgPaths { if verbose { - fmt.Fprintf(io.Err, "Linting %q...\n", pkgPath) + fmt.Fprintf(io.Err(), "Linting %q...\n", pkgPath) } // 'gno.mod' exists? diff --git a/gnovm/cmd/gno/main.go b/gnovm/cmd/gno/main.go index 433db703b90..c84aa52fc86 100644 --- a/gnovm/cmd/gno/main.go +++ b/gnovm/cmd/gno/main.go @@ -18,7 +18,7 @@ func main() { } } -func newGnocliCmd(io *commands.IO) *commands.Command { +func newGnocliCmd(io commands.IO) *commands.Command { cmd := commands.NewCommand( commands.Metadata{ ShortUsage: " [flags] [...]", diff --git a/gnovm/cmd/gno/mod.go b/gnovm/cmd/gno/mod.go index 9fb5dd704ce..da8db3ed68a 100644 --- a/gnovm/cmd/gno/mod.go +++ b/gnovm/cmd/gno/mod.go @@ -21,7 +21,7 @@ type modDownloadCfg struct { verbose bool } -func newModCmd(io *commands.IO) *commands.Command { +func newModCmd(io commands.IO) *commands.Command { cmd := commands.NewCommand( commands.Metadata{ Name: "mod", @@ -41,7 +41,7 @@ func newModCmd(io *commands.IO) *commands.Command { return cmd } -func newModDownloadCmd(io *commands.IO) *commands.Command { +func newModDownloadCmd(io commands.IO) *commands.Command { cfg := &modDownloadCfg{} return commands.NewCommand( @@ -71,7 +71,7 @@ func newModInitCmd() *commands.Command { ) } -func newModTidy(io *commands.IO) *commands.Command { +func newModTidy(io commands.IO) *commands.Command { return commands.NewCommand( commands.Metadata{ Name: "tidy", @@ -101,7 +101,7 @@ func (c *modDownloadCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execModDownload(cfg *modDownloadCfg, args []string, io *commands.IO) error { +func execModDownload(cfg *modDownloadCfg, args []string, io commands.IO) error { if len(args) > 0 { return flag.ErrHelp } @@ -172,7 +172,7 @@ func execModInit(args []string) error { return nil } -func execModTidy(args []string, io *commands.IO) error { +func execModTidy(args []string, io commands.IO) error { if len(args) > 0 { return flag.ErrHelp } diff --git a/gnovm/cmd/gno/precompile.go b/gnovm/cmd/gno/precompile.go index 7e895109706..4a4528001a2 100644 --- a/gnovm/cmd/gno/precompile.go +++ b/gnovm/cmd/gno/precompile.go @@ -47,7 +47,7 @@ func (p *precompileOptions) markAsPrecompiled(pkg importPath) { p.precompiled[pkg] = struct{}{} } -func newPrecompileCmd(io *commands.IO) *commands.Command { +func newPrecompileCmd(io commands.IO) *commands.Command { cfg := &precompileCfg{} return commands.NewCommand( @@ -107,7 +107,7 @@ func (c *precompileCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execPrecompile(cfg *precompileCfg, args []string, io *commands.IO) error { +func execPrecompile(cfg *precompileCfg, args []string, io commands.IO) error { if len(args) < 1 { return flag.ErrHelp } diff --git a/gnovm/cmd/gno/run.go b/gnovm/cmd/gno/run.go index 2c8d8c77350..d37c86df502 100644 --- a/gnovm/cmd/gno/run.go +++ b/gnovm/cmd/gno/run.go @@ -20,7 +20,7 @@ type runCfg struct { expr string } -func newRunCmd(io *commands.IO) *commands.Command { +func newRunCmd(io commands.IO) *commands.Command { cfg := &runCfg{} return commands.NewCommand( @@ -59,7 +59,7 @@ func (c *runCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execRun(cfg *runCfg, args []string, io *commands.IO) error { +func execRun(cfg *runCfg, args []string, io commands.IO) error { if len(args) == 0 { return flag.ErrHelp } @@ -68,9 +68,9 @@ func execRun(cfg *runCfg, args []string, io *commands.IO) error { cfg.rootDir = guessRootDir() } - stdin := io.In - stdout := io.Out - stderr := io.Err + stdin := io.In() + stdout := io.Out() + stderr := io.Err() // init store and machine testStore := tests.TestStore(cfg.rootDir, diff --git a/gnovm/cmd/gno/test.go b/gnovm/cmd/gno/test.go index 85fe3f7ee7d..718235c1390 100644 --- a/gnovm/cmd/gno/test.go +++ b/gnovm/cmd/gno/test.go @@ -37,7 +37,7 @@ type testCfg struct { withNativeFallback bool } -func newTestCmd(io *commands.IO) *commands.Command { +func newTestCmd(io commands.IO) *commands.Command { cfg := &testCfg{} return commands.NewCommand( @@ -157,7 +157,7 @@ func (c *testCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execTest(cfg *testCfg, args []string, io *commands.IO) error { +func execTest(cfg *testCfg, args []string, io commands.IO) error { if len(args) < 1 { return flag.ErrHelp } @@ -279,7 +279,7 @@ func gnoTestPkg( unittestFiles, filetestFiles []string, cfg *testCfg, - io *commands.IO, + io commands.IO, ) error { var ( verbose = cfg.verbose @@ -287,9 +287,9 @@ func gnoTestPkg( runFlag = cfg.run printRuntimeMetrics = cfg.printRuntimeMetrics - stdin = io.In - stdout = io.Out - stderr = io.Err + stdin = io.In() + stdout = io.Out() + stderr = io.Err() errs error ) @@ -415,7 +415,7 @@ func runTestFiles( verbose bool, printRuntimeMetrics bool, runFlag string, - io *commands.IO, + io commands.IO, ) error { var errs error diff --git a/tm2/pkg/commands/io.go b/tm2/pkg/commands/io.go index b23455e4602..fc0d3378a88 100644 --- a/tm2/pkg/commands/io.go +++ b/tm2/pkg/commands/io.go @@ -9,21 +9,42 @@ import ( // IO holds settable command // input, output and error buffers -type IO struct { - In io.Reader +type IO interface { + // getters + In() io.Reader + Out() io.WriteCloser + Err() io.WriteCloser + + // setters and helpers + SetIn(in io.Reader) + SetOut(out io.WriteCloser) + SetErr(err io.WriteCloser) + Println(args ...interface{}) + Printf(format string, args ...interface{}) + Printfln(format string, args ...interface{}) + ErrPrintln(args ...interface{}) + ErrPrintfln(format string, args ...interface{}) + GetCheckPassword(prompts [2]string, insecure bool) (string, error) + GetConfirmation(prompt string) (bool, error) + GetPassword(prompt string, insecure bool) (string, error) + GetString(prompt string) (string, error) +} + +type IOImpl struct { + in io.Reader inBuf *bufio.Reader - Out io.WriteCloser + out io.WriteCloser outBuf *bufio.Writer - Err io.WriteCloser + err io.WriteCloser errBuf *bufio.Writer } // NewDefaultIO returns a default command io // that utilizes standard input / output / error -func NewDefaultIO() *IO { - c := &IO{} +func NewDefaultIO() IO { + c := &IOImpl{} c.SetIn(os.Stdin) c.SetOut(os.Stdout) @@ -34,17 +55,21 @@ func NewDefaultIO() *IO { // NewTestIO returns a test command io // that only sets standard input (to avoid panics) -func NewTestIO() *IO { - c := &IO{} +func NewTestIO() IO { + c := &IOImpl{} c.SetIn(os.Stdin) return c } +func (io *IOImpl) In() io.Reader { return io.in } +func (io *IOImpl) Out() io.WriteCloser { return io.out } +func (io *IOImpl) Err() io.WriteCloser { return io.err } + // SetIn sets the input reader for the command io -func (io *IO) SetIn(in io.Reader) { - io.In = in - if inbuf, ok := io.In.(*bufio.Reader); ok { +func (io *IOImpl) SetIn(in io.Reader) { + io.in = in + if inbuf, ok := io.in.(*bufio.Reader); ok { io.inBuf = inbuf return @@ -54,19 +79,19 @@ func (io *IO) SetIn(in io.Reader) { } // SetOut sets the output writer for the command io -func (io *IO) SetOut(out io.WriteCloser) { - io.Out = out - io.outBuf = bufio.NewWriter(io.Out) +func (io *IOImpl) SetOut(out io.WriteCloser) { + io.out = out + io.outBuf = bufio.NewWriter(io.out) } // SetErr sets the error writer for the command io -func (io *IO) SetErr(err io.WriteCloser) { - io.Err = err - io.errBuf = bufio.NewWriter(io.Err) +func (io *IOImpl) SetErr(err io.WriteCloser) { + io.err = err + io.errBuf = bufio.NewWriter(io.err) } // Println prints a line terminated by a newline -func (io *IO) Println(args ...interface{}) { +func (io *IOImpl) Println(args ...interface{}) { if io.outBuf == nil { return } @@ -76,7 +101,7 @@ func (io *IO) Println(args ...interface{}) { } // Printf prints a formatted string without trailing newline -func (io *IO) Printf(format string, args ...interface{}) { +func (io *IOImpl) Printf(format string, args ...interface{}) { if io.outBuf == nil { return } @@ -86,7 +111,7 @@ func (io *IO) Printf(format string, args ...interface{}) { } // Printfln prints a formatted string terminated by a newline -func (io *IO) Printfln(format string, args ...interface{}) { +func (io *IOImpl) Printfln(format string, args ...interface{}) { if io.outBuf == nil { return } @@ -97,7 +122,7 @@ func (io *IO) Printfln(format string, args ...interface{}) { // ErrPrintln prints a line terminated by a newline to // cmd.Err(Buf) -func (io *IO) ErrPrintln(args ...interface{}) { +func (io *IOImpl) ErrPrintln(args ...interface{}) { if io.errBuf == nil { return } @@ -107,7 +132,7 @@ func (io *IO) ErrPrintln(args ...interface{}) { } // ErrPrintfln prints a formatted string terminated by a newline to cmd.Err(Buf) -func (io *IO) ErrPrintfln(format string, args ...interface{}) { +func (io *IOImpl) ErrPrintfln(format string, args ...interface{}) { if io.errBuf == nil { return } diff --git a/tm2/pkg/commands/utils.go b/tm2/pkg/commands/utils.go index c7ce19e8138..90b6fa12b64 100644 --- a/tm2/pkg/commands/utils.go +++ b/tm2/pkg/commands/utils.go @@ -9,7 +9,7 @@ import ( ) // GetPassword fetches the password using the provided prompt, if any -func (io *IO) GetPassword( +func (io *IOImpl) GetPassword( prompt string, insecure bool, ) (string, error) { @@ -27,7 +27,7 @@ func (io *IO) GetPassword( } // readLine reads a new line from standard input -func (io *IO) readLine() (string, error) { +func (io *IOImpl) readLine() (string, error) { input, err := io.inBuf.ReadString('\n') if err != nil { return "", err @@ -52,7 +52,7 @@ func readPassword() (string, error) { // GetConfirmation will request user give the confirmation from stdin. // "y", "Y", "yes", "YES", and "Yes" all count as confirmations. // If the input is not recognized, it returns false and a nil error. -func (io *IO) GetConfirmation(prompt string) (bool, error) { +func (io *IOImpl) GetConfirmation(prompt string) (bool, error) { // On stderr so it isn't part of bash output. io.ErrPrintfln("%s [y/n]:", prompt) @@ -78,7 +78,7 @@ func (io *IO) GetConfirmation(prompt string) (bool, error) { // match (for creating a new password). // It enforces the password length. Only parses password once if // input is piped in. -func (io *IO) GetCheckPassword( +func (io *IOImpl) GetCheckPassword( prompts [2]string, insecure bool, ) (string, error) { @@ -100,7 +100,7 @@ func (io *IO) GetCheckPassword( } // GetString simply returns the trimmed string output of a given reader. -func (io *IO) GetString(prompt string) (string, error) { +func (io *IOImpl) GetString(prompt string) (string, error) { if prompt != "" { // On stderr so it isn't part of bash output. io.ErrPrintln(prompt) diff --git a/tm2/pkg/crypto/keys/client/add.go b/tm2/pkg/crypto/keys/client/add.go index c90dfc9f803..a4089316e92 100644 --- a/tm2/pkg/crypto/keys/client/add.go +++ b/tm2/pkg/crypto/keys/client/add.go @@ -29,7 +29,7 @@ type addCfg struct { index uint64 } -func newAddCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { +func newAddCmd(rootCfg *baseCfg, io commands.IO) *commands.Command { cfg := &addCfg{ rootCfg: rootCfg, } @@ -131,7 +131,7 @@ input output - armor encrypted private key (saved to file) */ -func execAdd(cfg *addCfg, args []string, io *commands.IO) error { +func execAdd(cfg *addCfg, args []string, io commands.IO) error { var ( kb keys.Keybase err error @@ -280,7 +280,7 @@ func execAdd(cfg *addCfg, args []string, io *commands.IO) error { return printCreate(info, showMnemonic, mnemonic, io) } -func printCreate(info keys.Info, showMnemonic bool, mnemonic string, io *commands.IO) error { +func printCreate(info keys.Info, showMnemonic bool, mnemonic string, io commands.IO) error { io.Println("") printNewInfo(info, io) @@ -296,7 +296,7 @@ It is the only way to recover your account if you ever forget your password. return nil } -func printNewInfo(info keys.Info, io *commands.IO) { +func printNewInfo(info keys.Info, io commands.IO) { keyname := info.GetName() keytype := info.GetType() keypub := info.GetPubKey() diff --git a/tm2/pkg/crypto/keys/client/addpkg.go b/tm2/pkg/crypto/keys/client/addpkg.go index 3de9a6de546..5bbd3f08ad0 100644 --- a/tm2/pkg/crypto/keys/client/addpkg.go +++ b/tm2/pkg/crypto/keys/client/addpkg.go @@ -24,7 +24,7 @@ type addPkgCfg struct { deposit string } -func newAddPkgCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { +func newAddPkgCmd(rootCfg *makeTxCfg, io commands.IO) *commands.Command { cfg := &addPkgCfg{ rootCfg: rootCfg, } @@ -65,7 +65,7 @@ func (c *addPkgCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execAddPkg(cfg *addPkgCfg, args []string, io *commands.IO) error { +func execAddPkg(cfg *addPkgCfg, args []string, io commands.IO) error { if cfg.pkgPath == "" { return errors.New("pkgpath not specified") } @@ -142,7 +142,7 @@ func signAndBroadcast( cfg *makeTxCfg, args []string, tx std.Tx, - io *commands.IO, + io commands.IO, ) error { baseopts := cfg.rootCfg txopts := cfg diff --git a/tm2/pkg/crypto/keys/client/broadcast.go b/tm2/pkg/crypto/keys/client/broadcast.go index f1d448495a6..9c05f2c43b3 100644 --- a/tm2/pkg/crypto/keys/client/broadcast.go +++ b/tm2/pkg/crypto/keys/client/broadcast.go @@ -23,7 +23,7 @@ type broadcastCfg struct { tx *std.Tx } -func newBroadcastCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { +func newBroadcastCmd(rootCfg *baseCfg, io commands.IO) *commands.Command { cfg := &broadcastCfg{ rootCfg: rootCfg, } @@ -50,7 +50,7 @@ func (c *broadcastCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execBroadcast(cfg *broadcastCfg, args []string, io *commands.IO) error { +func execBroadcast(cfg *broadcastCfg, args []string, io commands.IO) error { if len(args) != 1 { return flag.ErrHelp } diff --git a/tm2/pkg/crypto/keys/client/call.go b/tm2/pkg/crypto/keys/client/call.go index 29fe9739a36..6f9c9d52f5f 100644 --- a/tm2/pkg/crypto/keys/client/call.go +++ b/tm2/pkg/crypto/keys/client/call.go @@ -22,7 +22,7 @@ type callCfg struct { args commands.StringArr } -func newCallCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { +func newCallCmd(rootCfg *makeTxCfg, io commands.IO) *commands.Command { cfg := &callCfg{ rootCfg: rootCfg, } @@ -69,7 +69,7 @@ func (c *callCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execCall(cfg *callCfg, args []string, io *commands.IO) error { +func execCall(cfg *callCfg, args []string, io commands.IO) error { if cfg.pkgPath == "" { return errors.New("pkgpath not specified") } diff --git a/tm2/pkg/crypto/keys/client/delete.go b/tm2/pkg/crypto/keys/client/delete.go index e22ac30988c..cf65b8fc60a 100644 --- a/tm2/pkg/crypto/keys/client/delete.go +++ b/tm2/pkg/crypto/keys/client/delete.go @@ -16,7 +16,7 @@ type deleteCfg struct { force bool } -func newDeleteCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { +func newDeleteCmd(rootCfg *baseCfg, io commands.IO) *commands.Command { cfg := &deleteCfg{ rootCfg: rootCfg, } @@ -50,7 +50,7 @@ func (c *deleteCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execDelete(cfg *deleteCfg, args []string, io *commands.IO) error { +func execDelete(cfg *deleteCfg, args []string, io commands.IO) error { if len(args) != 1 { return flag.ErrHelp } @@ -101,7 +101,7 @@ func execDelete(cfg *deleteCfg, args []string, io *commands.IO) error { return nil } -func confirmDeletion(io *commands.IO) error { +func confirmDeletion(io commands.IO) error { answer, err := io.GetConfirmation("Key reference will be deleted. Continue?") if err != nil { return err diff --git a/tm2/pkg/crypto/keys/client/export.go b/tm2/pkg/crypto/keys/client/export.go index 6eff8aa97b3..c3921c31fd7 100644 --- a/tm2/pkg/crypto/keys/client/export.go +++ b/tm2/pkg/crypto/keys/client/export.go @@ -18,7 +18,7 @@ type exportCfg struct { unsafe bool } -func newExportCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { +func newExportCmd(rootCfg *baseCfg, io commands.IO) *commands.Command { cfg := &exportCfg{ rootCfg: rootCfg, } @@ -59,7 +59,7 @@ func (c *exportCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execExport(cfg *exportCfg, io *commands.IO) error { +func execExport(cfg *exportCfg, io commands.IO) error { // Create a new instance of the key-base kb, err := keys.NewKeyBaseFromDir(cfg.rootCfg.Home) if err != nil { diff --git a/tm2/pkg/crypto/keys/client/generate.go b/tm2/pkg/crypto/keys/client/generate.go index d209bd70bd3..04a0ea8947f 100644 --- a/tm2/pkg/crypto/keys/client/generate.go +++ b/tm2/pkg/crypto/keys/client/generate.go @@ -16,7 +16,7 @@ type generateCfg struct { customEntropy bool } -func newGenerateCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { +func newGenerateCmd(rootCfg *baseCfg, io commands.IO) *commands.Command { cfg := &generateCfg{ rootCfg: rootCfg, } @@ -43,7 +43,7 @@ func (c *generateCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execGenerate(cfg *generateCfg, args []string, io *commands.IO) error { +func execGenerate(cfg *generateCfg, args []string, io commands.IO) error { customEntropy := cfg.customEntropy if len(args) != 0 { diff --git a/tm2/pkg/crypto/keys/client/import.go b/tm2/pkg/crypto/keys/client/import.go index e1d8af55861..e4f20ff6402 100644 --- a/tm2/pkg/crypto/keys/client/import.go +++ b/tm2/pkg/crypto/keys/client/import.go @@ -18,7 +18,7 @@ type importCfg struct { unsafe bool } -func newImportCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { +func newImportCmd(rootCfg *baseCfg, io commands.IO) *commands.Command { cfg := &importCfg{ rootCfg: rootCfg, } @@ -59,7 +59,7 @@ func (c *importCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execImport(cfg *importCfg, io *commands.IO) error { +func execImport(cfg *importCfg, io commands.IO) error { // Create a new instance of the key-base kb, err := keys.NewKeyBaseFromDir(cfg.rootCfg.Home) if err != nil { diff --git a/tm2/pkg/crypto/keys/client/list.go b/tm2/pkg/crypto/keys/client/list.go index cb86feb2395..bdee6b3bbe9 100644 --- a/tm2/pkg/crypto/keys/client/list.go +++ b/tm2/pkg/crypto/keys/client/list.go @@ -8,7 +8,7 @@ import ( "github.com/gnolang/gno/tm2/pkg/crypto/keys" ) -func newListCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { +func newListCmd(rootCfg *baseCfg, io commands.IO) *commands.Command { return commands.NewCommand( commands.Metadata{ Name: "list", @@ -22,7 +22,7 @@ func newListCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { ) } -func execList(cfg *baseCfg, args []string, io *commands.IO) error { +func execList(cfg *baseCfg, args []string, io commands.IO) error { if len(args) != 0 { return flag.ErrHelp } @@ -40,7 +40,7 @@ func execList(cfg *baseCfg, args []string, io *commands.IO) error { return err } -func printInfos(infos []keys.Info, io *commands.IO) { +func printInfos(infos []keys.Info, io commands.IO) { for i, info := range infos { keyname := info.GetName() keytype := info.GetType() diff --git a/tm2/pkg/crypto/keys/client/maketx.go b/tm2/pkg/crypto/keys/client/maketx.go index 36214a5a983..e3fe89b930d 100644 --- a/tm2/pkg/crypto/keys/client/maketx.go +++ b/tm2/pkg/crypto/keys/client/maketx.go @@ -17,7 +17,7 @@ type makeTxCfg struct { chainID string } -func newMakeTxCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { +func newMakeTxCmd(rootCfg *baseCfg, io commands.IO) *commands.Command { cfg := &makeTxCfg{ rootCfg: rootCfg, } diff --git a/tm2/pkg/crypto/keys/client/query.go b/tm2/pkg/crypto/keys/client/query.go index 8cc5757aba7..746048e772c 100644 --- a/tm2/pkg/crypto/keys/client/query.go +++ b/tm2/pkg/crypto/keys/client/query.go @@ -21,7 +21,7 @@ type queryCfg struct { path string } -func newQueryCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { +func newQueryCmd(rootCfg *baseCfg, io commands.IO) *commands.Command { cfg := &queryCfg{ rootCfg: rootCfg, } @@ -62,7 +62,7 @@ func (c *queryCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execQuery(cfg *queryCfg, args []string, io *commands.IO) error { +func execQuery(cfg *queryCfg, args []string, io commands.IO) error { if len(args) != 1 { return flag.ErrHelp } diff --git a/tm2/pkg/crypto/keys/client/root.go b/tm2/pkg/crypto/keys/client/root.go index 550dd408b77..61fd7d077b5 100644 --- a/tm2/pkg/crypto/keys/client/root.go +++ b/tm2/pkg/crypto/keys/client/root.go @@ -18,7 +18,7 @@ type baseCfg struct { BaseOptions } -func NewRootCmd(io *commands.IO) *commands.Command { +func NewRootCmd(io commands.IO) *commands.Command { cfg := &baseCfg{} cmd := commands.NewCommand( diff --git a/tm2/pkg/crypto/keys/client/send.go b/tm2/pkg/crypto/keys/client/send.go index 6d19ffcb393..a5098aea08c 100644 --- a/tm2/pkg/crypto/keys/client/send.go +++ b/tm2/pkg/crypto/keys/client/send.go @@ -21,7 +21,7 @@ type sendCfg struct { to string } -func newSendCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { +func newSendCmd(rootCfg *makeTxCfg, io commands.IO) *commands.Command { cfg := &sendCfg{ rootCfg: rootCfg, } @@ -55,7 +55,7 @@ func (c *sendCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execSend(cfg *sendCfg, args []string, io *commands.IO) error { +func execSend(cfg *sendCfg, args []string, io commands.IO) error { if len(args) != 1 { return flag.ErrHelp } diff --git a/tm2/pkg/crypto/keys/client/sign.go b/tm2/pkg/crypto/keys/client/sign.go index 761e0d7a563..f8fcc02fdde 100644 --- a/tm2/pkg/crypto/keys/client/sign.go +++ b/tm2/pkg/crypto/keys/client/sign.go @@ -28,7 +28,7 @@ type signCfg struct { pass string } -func newSignCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { +func newSignCmd(rootCfg *baseCfg, io commands.IO) *commands.Command { cfg := &signCfg{ rootCfg: rootCfg, } @@ -83,7 +83,7 @@ func (c *signCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execSign(cfg *signCfg, args []string, io *commands.IO) error { +func execSign(cfg *signCfg, args []string, io commands.IO) error { var err error if len(args) != 1 { diff --git a/tm2/pkg/crypto/keys/client/verify.go b/tm2/pkg/crypto/keys/client/verify.go index bb486c1a8fa..fff2fcd852f 100644 --- a/tm2/pkg/crypto/keys/client/verify.go +++ b/tm2/pkg/crypto/keys/client/verify.go @@ -16,7 +16,7 @@ type verifyCfg struct { docPath string } -func newVerifyCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { +func newVerifyCmd(rootCfg *baseCfg, io commands.IO) *commands.Command { cfg := &verifyCfg{ rootCfg: rootCfg, } @@ -43,7 +43,7 @@ func (c *verifyCfg) RegisterFlags(fs *flag.FlagSet) { ) } -func execVerify(cfg *verifyCfg, args []string, io *commands.IO) error { +func execVerify(cfg *verifyCfg, args []string, io commands.IO) error { var ( kb keys.Keybase err error From 09d7c5291ca847990d7cac641562562b85f0338e Mon Sep 17 00:00:00 2001 From: Jeff Thompson Date: Thu, 9 Nov 2023 18:43:34 +0100 Subject: [PATCH 23/25] chore: Add Keybase HasByNameOrAddress, HasByName and HasByAddress (#1313) The Keybase [interface has](https://github.com/gnolang/gno/blob/7105d00e10209003ea41fbae7a4d7c463c4167c3/tm2/pkg/crypto/keys/types.go#L16C2-L18) `GetByNameOrAddress`, `GetByName` and `GetByAddress`. If an application simply wants to check if the key is in the key base, it must use one of these and check for an error, as is done [in the gnokey command line](https://github.com/gnolang/gno/blob/7105d00e10209003ea41fbae7a4d7c463c4167c3/tm2/pkg/crypto/keys/client/add.go#L159-L160). ``` _, err = kb.GetByName(name) if err == nil { // account exists, ask for user confirmation ... } ``` A GnoMobile app also needs to check for the key. But it's expensive to return the entire key info. The byte buffer must be copies multiple times, in the Keybase and in the gRPC interface, and the key info structure must be reformatted to Protobuf and then to the application's language. And not preferable to generate errors to pass information in normal program flow. In the underlying `DB` interface, there is already a [Has function](https://github.com/gnolang/gno/blob/7105d00e10209003ea41fbae7a4d7c463c4167c3/tm2/pkg/db/types.go#L13). This PR updates the `Keybase` with the related functions `HasByNameOrAddress`, `HasByName` and `HasByAddress` which use `Has` to inexpensively return a simple bool. It also updates the gnokey command line to use `HasByName` to be more clear: ``` if has, err := kb.HasByName(name); err == nil && has { // account exists, ask for user confirmation ... } ``` --------- Signed-off-by: Jeff Thompson Co-authored-by: Morgan Bazalgette --- tm2/pkg/crypto/keys/client/add.go | 3 +-- tm2/pkg/crypto/keys/keybase.go | 22 +++++++++++++++++++-- tm2/pkg/crypto/keys/keybase_test.go | 27 +++++++++++++++++--------- tm2/pkg/crypto/keys/lazy_keybase.go | 30 +++++++++++++++++++++++++++++ tm2/pkg/crypto/keys/types.go | 3 +++ 5 files changed, 72 insertions(+), 13 deletions(-) diff --git a/tm2/pkg/crypto/keys/client/add.go b/tm2/pkg/crypto/keys/client/add.go index a4089316e92..71dc6f03090 100644 --- a/tm2/pkg/crypto/keys/client/add.go +++ b/tm2/pkg/crypto/keys/client/add.go @@ -156,8 +156,7 @@ func execAdd(cfg *addCfg, args []string, io commands.IO) error { return err } - _, err = kb.GetByName(name) - if err == nil { + if has, err := kb.HasByName(name); err == nil && has { // account exists, ask for user confirmation response, err2 := io.GetConfirmation(fmt.Sprintf("Override the existing name %s", name)) if err2 != nil { diff --git a/tm2/pkg/crypto/keys/keybase.go b/tm2/pkg/crypto/keys/keybase.go index 06eaf54f503..31b0012c433 100644 --- a/tm2/pkg/crypto/keys/keybase.go +++ b/tm2/pkg/crypto/keys/keybase.go @@ -160,14 +160,32 @@ func (kb dbKeybase) List() ([]Info, error) { return res, nil } +// HasByNameOrAddress checks if a key with the name or bech32 string address is in the keybase. +func (kb dbKeybase) HasByNameOrAddress(nameOrBech32 string) (bool, error) { + address, err := crypto.AddressFromBech32(nameOrBech32) + if err != nil { + return kb.HasByName(nameOrBech32) + } + return kb.HasByAddress(address) +} + +// HasByName checks if a key with the name is in the keybase. +func (kb dbKeybase) HasByName(name string) (bool, error) { + return kb.db.Has(infoKey(name)), nil +} + +// HasByAddress checks if a key with the address is in the keybase. +func (kb dbKeybase) HasByAddress(address crypto.Address) (bool, error) { + return kb.db.Has(addrKey(address)), nil +} + // Get returns the public information about one key. func (kb dbKeybase) GetByNameOrAddress(nameOrBech32 string) (Info, error) { addr, err := crypto.AddressFromBech32(nameOrBech32) if err != nil { return kb.GetByName(nameOrBech32) - } else { - return kb.GetByAddress(addr) } + return kb.GetByAddress(addr) } func (kb dbKeybase) GetByName(name string) (Info, error) { diff --git a/tm2/pkg/crypto/keys/keybase_test.go b/tm2/pkg/crypto/keys/keybase_test.go index e80c6c3cd03..d7660ac38f1 100644 --- a/tm2/pkg/crypto/keys/keybase_test.go +++ b/tm2/pkg/crypto/keys/keybase_test.go @@ -89,8 +89,9 @@ func TestKeyManagement(t *testing.T) { assert.Empty(t, l) // create some keys - _, err = cstore.GetByName(n1) - require.Error(t, err) + has, err := cstore.HasByName(n1) + require.NoError(t, err) + require.False(t, has) i, err := cstore.CreateAccount(n1, mn1, bip39Passphrase, p1, 0, 0) require.NoError(t, err) require.Equal(t, n1, i.GetName()) @@ -100,10 +101,16 @@ func TestKeyManagement(t *testing.T) { // we can get these keys i2, err := cstore.GetByName(n2) require.NoError(t, err) - _, err = cstore.GetByName(n3) - require.NotNil(t, err) - _, err = cstore.GetByAddress(toAddr(i2)) + has, err = cstore.HasByName(n3) + require.NoError(t, err) + require.False(t, has) + has, err = cstore.HasByAddress(toAddr(i2)) + require.NoError(t, err) + require.True(t, has) + // Also check with HasByNameOrAddress + has, err = cstore.HasByNameOrAddress(crypto.AddressToBech32(toAddr(i2))) require.NoError(t, err) + require.True(t, has) addr, err := crypto.AddressFromBech32("g1frtkxv37nq7arvyz5p0mtjqq7hwuvd4dnt892p") require.NoError(t, err) _, err = cstore.GetByAddress(addr) @@ -127,8 +134,9 @@ func TestKeyManagement(t *testing.T) { keyS, err = cstore.List() require.NoError(t, err) require.Equal(t, 1, len(keyS)) - _, err = cstore.GetByName(n1) - require.Error(t, err) + has, err = cstore.HasByName(n1) + require.NoError(t, err) + require.False(t, has) // create an offline key o1 := "offline" @@ -388,8 +396,9 @@ func TestSeedPhrase(t *testing.T) { // now, let us delete this key err = cstore.Delete(n1, p1, false) require.Nil(t, err, "%+v", err) - _, err = cstore.GetByName(n1) - require.NotNil(t, err) + has, err := cstore.HasByName(n1) + require.NoError(t, err) + require.False(t, has) } func ExampleNew() { diff --git a/tm2/pkg/crypto/keys/lazy_keybase.go b/tm2/pkg/crypto/keys/lazy_keybase.go index f7f9e229980..62e88d9a8e2 100644 --- a/tm2/pkg/crypto/keys/lazy_keybase.go +++ b/tm2/pkg/crypto/keys/lazy_keybase.go @@ -37,6 +37,36 @@ func (lkb lazyKeybase) List() ([]Info, error) { return NewDBKeybase(db).List() } +func (lkb lazyKeybase) HasByNameOrAddress(nameOrBech32 string) (bool, error) { + db, err := db.NewDB(lkb.name, dbBackend, lkb.dir) + if err != nil { + return false, err + } + defer db.Close() + + return NewDBKeybase(db).HasByNameOrAddress(nameOrBech32) +} + +func (lkb lazyKeybase) HasByName(name string) (bool, error) { + db, err := db.NewDB(lkb.name, dbBackend, lkb.dir) + if err != nil { + return false, err + } + defer db.Close() + + return NewDBKeybase(db).HasByName(name) +} + +func (lkb lazyKeybase) HasByAddress(address crypto.Address) (bool, error) { + db, err := db.NewDB(lkb.name, dbBackend, lkb.dir) + if err != nil { + return false, err + } + defer db.Close() + + return NewDBKeybase(db).HasByAddress(address) +} + func (lkb lazyKeybase) GetByNameOrAddress(nameOrBech32 string) (Info, error) { db, err := db.NewDB(lkb.name, dbBackend, lkb.dir) if err != nil { diff --git a/tm2/pkg/crypto/keys/types.go b/tm2/pkg/crypto/keys/types.go index bba3a917b69..c5d33023a0a 100644 --- a/tm2/pkg/crypto/keys/types.go +++ b/tm2/pkg/crypto/keys/types.go @@ -13,6 +13,9 @@ import ( type Keybase interface { // CRUD on the keystore List() ([]Info, error) + HasByNameOrAddress(nameOrBech32 string) (bool, error) + HasByName(name string) (bool, error) + HasByAddress(address crypto.Address) (bool, error) GetByNameOrAddress(nameOrBech32 string) (Info, error) GetByName(name string) (Info, error) GetByAddress(address crypto.Address) (Info, error) From 117bcd1fac5c3db5e828046de25306baa4bf6eac Mon Sep 17 00:00:00 2001 From: Leon Hudak <33522493+leohhhn@users.noreply.github.com> Date: Thu, 9 Nov 2023 18:48:07 +0100 Subject: [PATCH 24/25] feat: add p/demo/pausable (#1328) ## Description This PR adds the `Pausable` package to p/demo, allowing realms to have pausability. It relies on the already existing `Ownable` package for access control, #1314. Inspired by OpenZeppelin's [Pausable](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.9.3/contracts/security/Pausable.sol).
Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [x] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--------- Co-authored-by: Morgan Bazalgette --- examples/gno.land/p/demo/pausable/gno.mod | 3 + .../gno.land/p/demo/pausable/pausable.gno | 49 ++++++++++++ .../p/demo/pausable/pausable_test.gno | 77 +++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 examples/gno.land/p/demo/pausable/gno.mod create mode 100644 examples/gno.land/p/demo/pausable/pausable.gno create mode 100644 examples/gno.land/p/demo/pausable/pausable_test.gno diff --git a/examples/gno.land/p/demo/pausable/gno.mod b/examples/gno.land/p/demo/pausable/gno.mod new file mode 100644 index 00000000000..08c7a4f7e5f --- /dev/null +++ b/examples/gno.land/p/demo/pausable/gno.mod @@ -0,0 +1,3 @@ +module gno.land/p/demo/pausable + +require gno.land/p/demo/ownable v0.0.0-latest diff --git a/examples/gno.land/p/demo/pausable/pausable.gno b/examples/gno.land/p/demo/pausable/pausable.gno new file mode 100644 index 00000000000..eae3456ba61 --- /dev/null +++ b/examples/gno.land/p/demo/pausable/pausable.gno @@ -0,0 +1,49 @@ +package pausable + +import "gno.land/p/demo/ownable" + +type Pausable struct { + *ownable.Ownable + paused bool +} + +// New returns a new Pausable struct with non-paused state as default +func New() *Pausable { + return &Pausable{ + Ownable: ownable.New(), + paused: false, + } +} + +// NewFromOwnable is the same as New, but with a pre-existing top-level ownable +func NewFromOwnable(ownable *ownable.Ownable) *Pausable { + return &Pausable{ + Ownable: ownable, + paused: false, + } +} + +// IsPaused checks if Pausable is paused +func (p Pausable) IsPaused() bool { + return p.paused +} + +// Pause sets the state of Pausable to true, meaning all pausable functions are paused +func (p *Pausable) Pause() error { + if err := p.CallerIsOwner(); err != nil { + return err + } + + p.paused = true + return nil +} + +// Unpause sets the state of Pausable to false, meaning all pausable functions are resumed +func (p *Pausable) Unpause() error { + if err := p.CallerIsOwner(); err != nil { + return err + } + + p.paused = false + return nil +} diff --git a/examples/gno.land/p/demo/pausable/pausable_test.gno b/examples/gno.land/p/demo/pausable/pausable_test.gno new file mode 100644 index 00000000000..cc95c457573 --- /dev/null +++ b/examples/gno.land/p/demo/pausable/pausable_test.gno @@ -0,0 +1,77 @@ +package pausable + +import ( + "std" + "testing" + + "gno.land/p/demo/ownable" +) + +var ( + firstCaller = std.Address("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + secondCaller = std.Address("g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa") +) + +func TestNew(t *testing.T) { + std.TestSetOrigCaller(firstCaller) + + result := New() + + if result.paused != false { + t.Fatalf("Expected result to be unpaused, got %t\n", result.paused) + } + + if result.Owner() != firstCaller { + t.Fatalf("Expected %s, got %s\n", firstCaller, result.Owner()) + } +} + +func TestNewFromOwnable(t *testing.T) { + std.TestSetOrigCaller(firstCaller) + o := ownable.New() + + std.TestSetOrigCaller(secondCaller) + result := NewFromOwnable(o) + + if result.Owner() != firstCaller { + t.Fatalf("Expected %s, got %s\n", firstCaller, result.Owner()) + } +} + +func TestSetUnpaused(t *testing.T) { + std.TestSetOrigCaller(firstCaller) + + result := New() + result.Unpause() + + if result.IsPaused() { + t.Fatalf("Expected result to be unpaused, got %t\n", result.IsPaused()) + } +} + +func TestSetPaused(t *testing.T) { + std.TestSetOrigCaller(firstCaller) + + result := New() + result.Pause() + + if !result.IsPaused() { + t.Fatalf("Expected result to be paused, got %t\n", result.IsPaused()) + } +} + +func TestIsPaused(t *testing.T) { + std.TestSetOrigCaller(firstCaller) + + result := New() + + if result.IsPaused() { + t.Fatalf("Expected result to be unpaused, got %t\n", result.IsPaused()) + } + + result.Pause() + + if !result.IsPaused() { + t.Fatalf("Expected result to be paused, got %t\n", result.IsPaused()) + } +} From 9c8f2483a863bdb15f7668bcf6fdc08e4c41c06a Mon Sep 17 00:00:00 2001 From: Morgan Date: Thu, 9 Nov 2023 18:52:26 +0100 Subject: [PATCH 25/25] docs: update Go<>Gno compatibility document with up-to-date info (#1311) --- gnovm/docs/go-gno-compatibility.md | 515 +++++++++++++---------------- 1 file changed, 226 insertions(+), 289 deletions(-) diff --git a/gnovm/docs/go-gno-compatibility.md b/gnovm/docs/go-gno-compatibility.md index a39cec533f4..6ff433c056f 100644 --- a/gnovm/docs/go-gno-compatibility.md +++ b/gnovm/docs/go-gno-compatibility.md @@ -1,11 +1,7 @@ # Go<>Gno compatibility -**WIP: does not reflect the current state yet.** - ## Native keywords -Legend: full, partial, missing, TBD. - | keyword | support | |-------------|------------------------| | break | full | @@ -32,22 +28,27 @@ Legend: full, partial, missing, TBD. | type | full | | var | full | +Generics are currently not implemented. + ## Native types | type | usage | persistency | |-----------------------------------------------|------------------------|------------------------------------------------------------| | `bool` | full | full | | `byte` | full | full | -| `float32`, `float64` | full | full | | `int`, `int8`, `int16`, `int32`, `int64` | full | full | | `uint`, `uint8`, `uint16`, `uint32`, `uint64` | full | full | +| `float32`, `float64` | full | full | +| `complex64`, `complex128` | missing (TBD) | missing | +| `uintptr`, `unsafe.Pointer` | missing | missing | | `string` | full | full | | `rune` | full | full | | `interface{}` | full | full | -| `[]T` (slices) | full | full* | -| `map[T1]T2` | full | full* | +| `[]T` (slices) | full | full\* | +| `[N]T` (arrays) | full | full\* | +| `map[T1]T2` | full | full\* | | `func (T1...) T2...` | full | full (needs more tests) | -| `*T` (pointers) | full | full* | +| `*T` (pointers) | full | full\* | | `chan T` (channels) | missing (after launch) | missing (after launch) | **\*:** depends on `T`/`T1`/`T2` @@ -62,286 +63,221 @@ Additional native types: ## Stdlibs - +Legend: + +* `nondet`: the standard library in question would require non-deterministic + behaviour to implement as in Go, such as cryptographical randomness or + os/network access. The library may still be implemented at one point, with a + different API. +* `gospec`: the standard library is very Go-specific -- for instance, it is used + for debugging information or for parsing/build Go source code. A Gno version + may exist at one point, likely with a different package name or semantics. +* `gnics`: the standard library requires generics. +* `test`: the standard library is currently available for use exclusively in + test contexts, and may have limited functionality. +* `cmd`: the Go standard library is a command -- a direct equivalent in Gno + would not be useful. +* `tbd`: whether to include the standard library or not is still up for + discussion. +* `todo`: the standard libary is to be added, and + [contributions are welcome.](https://github.com/gnolang/gno/issues/1267) +* `part`: the standard library is partially implemented in Gno, and contributions are + welcome to add the missing functionality. +* `full`: the standard library is fully implemented in Gno. + + | package | status | |---------------------------------------------|----------| -| archive/tar | TBD | -| archive/zip | TBD | -| arena | TBD | -| bufio | TBD | -| builtin | TBD | -| bytes | TBD | -| cmd/addr2line | TBD | -| cmd/api | TBD | -| cmd/api/testdata/src/issue21181/dep | TBD | -| cmd/api/testdata/src/issue21181/indirect | TBD | -| cmd/api/testdata/src/issue21181/p | TBD | -| cmd/api/testdata/src/pkg/p1 | TBD | -| cmd/api/testdata/src/pkg/p2 | TBD | -| cmd/api/testdata/src/pkg/p3 | TBD | -| cmd/api/testdata/src/pkg/p4 | TBD | -| cmd/asm | TBD | -| cmd/buildid | TBD | -| cmd/cgo | TBD | -| cmd/compile | TBD | -| cmd/covdata | TBD | -| cmd/covdata/testdata | TBD | -| cmd/cover | TBD | -| cmd/cover/testdata | TBD | -| cmd/cover/testdata/html | TBD | -| cmd/cover/testdata/pkgcfg/a | TBD | -| cmd/cover/testdata/pkgcfg/b | TBD | -| cmd/cover/testdata/pkgcfg/main | TBD | -| cmd/dist | TBD | -| cmd/distpack | TBD | -| cmd/doc | TBD | -| cmd/doc/testdata | TBD | -| cmd/doc/testdata/merge | TBD | -| cmd/doc/testdata/nested | TBD | -| cmd/doc/testdata/nested/empty | TBD | -| cmd/doc/testdata/nested/nested | TBD | -| cmd/fix | TBD | -| cmd/go | TBD | -| cmd/gofmt | TBD | -| cmd/go/testdata | TBD | -| cmd/link | TBD | -| cmd/link/testdata/pe-binutils | TBD | -| cmd/link/testdata/pe-llvm | TBD | -| cmd/link/testdata/testBuildFortvOS | TBD | -| cmd/link/testdata/testHashedSyms | TBD | -| cmd/link/testdata/testIndexMismatch | TBD | -| cmd/link/testdata/testRO | TBD | -| cmd/nm | TBD | -| cmd/objdump | TBD | -| cmd/objdump/testdata | TBD | -| cmd/objdump/testdata/testfilenum | TBD | -| cmd/pack | TBD | -| cmd/pprof | TBD | -| cmd/pprof/testdata | TBD | -| cmd/test2json | TBD | -| cmd/trace | TBD | -| cmd/vet | TBD | -| cmd/vet/testdata/asm | TBD | -| cmd/vet/testdata/assign | TBD | -| cmd/vet/testdata/atomic | TBD | -| cmd/vet/testdata/bool | TBD | -| cmd/vet/testdata/buildtag | TBD | -| cmd/vet/testdata/cgo | TBD | -| cmd/vet/testdata/composite | TBD | -| cmd/vet/testdata/copylock | TBD | -| cmd/vet/testdata/deadcode | TBD | -| cmd/vet/testdata/directive | TBD | -| cmd/vet/testdata/httpresponse | TBD | -| cmd/vet/testdata/lostcancel | TBD | -| cmd/vet/testdata/method | TBD | -| cmd/vet/testdata/nilfunc | TBD | -| cmd/vet/testdata/print | TBD | -| cmd/vet/testdata/rangeloop | TBD | -| cmd/vet/testdata/shift | TBD | -| cmd/vet/testdata/structtag | TBD | -| cmd/vet/testdata/tagtest | TBD | -| cmd/vet/testdata/testingpkg | TBD | -| cmd/vet/testdata/unmarshal | TBD | -| cmd/vet/testdata/unsafeptr | TBD | -| cmd/vet/testdata/unused | TBD | -| compress/bzip2 | TBD | -| compress/flate | TBD | -| compress/gzip | TBD | -| compress/lzw | TBD | -| compress/zlib | TBD | -| container/heap | TBD | -| container/list | TBD | -| container/ring | TBD | -| context | TBD | -| crypto | TBD | -| crypto/aes | TBD | -| crypto/boring | TBD | -| crypto/cipher | TBD | -| crypto/des | TBD | -| crypto/dsa | TBD | -| crypto/ecdh | TBD | -| crypto/ecdsa | TBD | -| crypto/ed25519 | TBD | -| crypto/elliptic | TBD | -| crypto/hmac | TBD | -| crypto/md5 | TBD | -| crypto/rand | TBD | -| crypto/rc4 | TBD | -| crypto/rsa | TBD | -| crypto/sha1 | TBD | -| crypto/sha256 | TBD | -| crypto/sha512 | TBD | -| crypto/subtle | TBD | -| crypto/tls | TBD | -| crypto/tls/fipsonly | TBD | -| crypto/x509 | TBD | -| crypto/x509/pkix | TBD | -| database/sql | TBD | -| database/sql/driver | TBD | -| debug/buildinfo | TBD | -| debug/dwarf | TBD | -| debug/elf | TBD | -| debug/gosym | TBD | -| debug/gosym/testdata | TBD | -| debug/macho | TBD | -| debug/pe | TBD | -| debug/plan9obj | TBD | -| embed | TBD | -| encoding | TBD | -| encoding/ascii85 | TBD | -| encoding/asn1 | TBD | -| encoding/base32 | TBD | -| encoding/base64 | TBD | -| encoding/binary | partial | -| encoding/csv | TBD | -| encoding/gob | TBD | -| encoding/hex | TBD | -| encoding/json | TBD | -| encoding/pem | TBD | -| encoding/xml | TBD | -| errors | TBD | -| expvar | TBD | -| flag | TBD | -| fmt | TBD | -| go/ast | TBD | -| go/build | TBD | -| go/build/constraint | TBD | -| go/build/testdata/alltags | TBD | -| go/build/testdata/cgo_disabled | TBD | -| go/build/testdata/directives | TBD | -| go/build/testdata/doc | TBD | -| go/build/testdata/multi | TBD | -| go/build/testdata/non_source_tags | TBD | -| go/build/testdata/other | TBD | -| go/build/testdata/other/file | TBD | -| go/constant | TBD | -| go/doc | TBD | -| go/doc/comment | TBD | -| go/doc/testdata | TBD | -| go/doc/testdata/examples | TBD | -| go/doc/testdata/pkgdoc | TBD | -| go/format | TBD | -| go/importer | TBD | -| go/parser | TBD | -| go/parser/testdata/goversion | TBD | -| go/parser/testdata/issue42951 | TBD | -| go/parser/testdata/issue42951/not_a_file.go | TBD | -| go/printer | TBD | -| go/printer/testdata | TBD | -| go/scanner | TBD | -| go/token | TBD | -| go/types | TBD | -| go/types/testdata | TBD | -| go/types/testdata/local | TBD | -| hash | partial | -| hash/adler32 | full | -| hash/crc32 | TBD | -| hash/crc64 | TBD | -| hash/fnv | TBD | -| hash/maphash | TBD | -| html | TBD | -| html/template | TBD | -| image | TBD | -| image/color | TBD | -| image/color/palette | TBD | -| image/draw | TBD | -| image/gif | TBD | -| image/jpeg | TBD | -| image/png | TBD | -| index/suffixarray | TBD | -| io | TBD | -| io/fs | TBD | -| io/ioutil | TBD | -| log | TBD | -| log/internal | TBD | -| log/slog | TBD | -| log/slog/internal | TBD | -| log/syslog | TBD | -| maps | TBD | -| math | partial | -| math/big | TBD | -| math/bits | TBD | -| math/cmplx | TBD | -| math/rand | TBD | -| mime | TBD | -| mime/multipart | TBD | -| mime/quotedprintable | TBD | -| net | TBD | -| net/http | TBD | -| net/http/cgi | TBD | -| net/http/cookiejar | TBD | -| net/http/fcgi | TBD | -| net/http/httptest | TBD | -| net/http/httptrace | TBD | -| net/http/httputil | TBD | -| net/http/internal | TBD | -| net/http/pprof | TBD | -| net/mail | TBD | -| net/netip | TBD | -| net/rpc | TBD | -| net/rpc/jsonrpc | TBD | -| net/smtp | TBD | -| net/textproto | TBD | -| net/url | full | -| os | TBD | -| os/exec | TBD | -| os/signal | TBD | -| os/user | TBD | -| path | full | -| path/filepath | TBD | -| plugin | TBD | -| reflect | TBD | -| regexp | TBD | -| regexp/syntax | TBD | -| runtime | TBD | -| runtime/asan | TBD | -| runtime/cgo | TBD | -| runtime/coverage | TBD | -| runtime/coverage/testdata | TBD | -| runtime/coverage/testdata/issue56006 | TBD | -| runtime/debug | TBD | -| runtime/metrics | TBD | -| runtime/msan | TBD | -| runtime/pprof | TBD | -| runtime/pprof/testdata/mappingtest | TBD | -| runtime/race | TBD | -| runtime/race/testdata | TBD | -| runtime/testdata/testexithooks | TBD | -| runtime/testdata/testfaketime | TBD | -| runtime/testdata/testprog | TBD | -| runtime/testdata/testprogcgo | TBD | -| runtime/testdata/testprogcgo/windows | TBD | -| runtime/testdata/testprognet | TBD | -| runtime/testdata/testwinlib | TBD | -| runtime/testdata/testwinlibsignal | TBD | -| runtime/testdata/testwinlibthrow | TBD | -| runtime/testdata/testwinsignal | TBD | -| runtime/trace | TBD | -| slices | TBD | -| sort | TBD | -| strconv | TBD | -| strings | TBD | -| sync | TBD | -| sync/atomic | TBD | -| syscall | TBD | -| syscall/js | TBD | -| testing | TBD | -| testing/fstest | TBD | -| testing/iotest | TBD | -| testing/quick | TBD | -| text/scanner | TBD | -| text/tabwriter | TBD | -| text/template | TBD | -| text/template/parse | TBD | -| time | TBD | -| time/tzdata | TBD | -| unicode | TBD | -| unicode/utf16 | TBD | -| unicode/utf8 | TBD | -| unsafe | TBD | - +| archive/tar | `tbd` | +| archive/zip | `tbd` | +| arena | `improb` | +| bufio | `full` | +| builtin | `full`[^1] | +| bytes | `full` | +| cmd/\* | `cmd` | +| compress/bzip2 | `tbd` | +| compress/flate | `tbd` | +| compress/gzip | `tbd` | +| compress/lzw | `tbd` | +| compress/zlib | `tbd` | +| container/heap | `tbd` | +| container/list | `tbd` | +| container/ring | `tbd` | +| context | `tbd` | +| crypto | `todo` | +| crypto/aes | `todo` | +| crypto/boring | `tbd` | +| crypto/cipher | `part` | +| crypto/des | `tbd` | +| crypto/dsa | `tbd` | +| crypto/ecdh | `tbd` | +| crypto/ecdsa | `tbd` | +| crypto/ed25519 | `tbd` | +| crypto/elliptic | `tbd` | +| crypto/hmac | `todo` | +| crypto/md5 | `test`[^2] | +| crypto/rand | `nondet` | +| crypto/rc4 | `tbd` | +| crypto/rsa | `tbd` | +| crypto/sha1 | `test`[^2] | +| crypto/sha256 | `part`[^3] | +| crypto/sha512 | `tbd` | +| crypto/subtle | `tbd` | +| crypto/tls | `nondet` | +| crypto/tls/fipsonly | `nondet` | +| crypto/x509 | `tbd` | +| crypto/x509/pkix | `tbd` | +| database/sql | `nondet` | +| database/sql/driver | `nondet` | +| debug/buildinfo | `gospec` | +| debug/dwarf | `gospec` | +| debug/elf | `gospec` | +| debug/gosym | `gospec` | +| debug/macho | `gospec` | +| debug/pe | `gospec` | +| debug/plan9obj | `gospec` | +| embed | `tbd` | +| encoding | `full` | +| encoding/ascii85 | `todo` | +| encoding/asn1 | `todo` | +| encoding/base32 | `todo` | +| encoding/base64 | `full` | +| encoding/binary | `part` | +| encoding/csv | `todo` | +| encoding/gob | `tbd` | +| encoding/hex | `full` | +| encoding/json | `todo` | +| encoding/pem | `todo` | +| encoding/xml | `todo` | +| errors | `part` | +| expvar | `tbd` | +| flag | `nondet` | +| fmt | `test`[^4] | +| go/ast | `gospec` | +| go/build | `gospec` | +| go/build/constraint | `gospec` | +| go/constant | `gospec` | +| go/doc | `gospec` | +| go/doc/comment | `gospec` | +| go/format | `gospec` | +| go/importer | `gospec` | +| go/parser | `gospec` | +| go/printer | `gospec` | +| go/scanner | `gospec` | +| go/token | `gospec` | +| go/types | `gospec` | +| hash | `full` | +| hash/adler32 | `full` | +| hash/crc32 | `todo` | +| hash/crc64 | `todo` | +| hash/fnv | `todo` | +| hash/maphash | `todo` | +| html | `todo` | +| html/template | `todo` | +| image | `tbd` | +| image/color | `tbd` | +| image/color/palette | `tbd` | +| image/draw | `tbd` | +| image/gif | `tbd` | +| image/jpeg | `tbd` | +| image/png | `tbd` | +| index/suffixarray | `tbd` | +| io | `full` | +| io/fs | `tbd` | +| io/ioutil | removed[^5] | +| log | `tbd` | +| log/slog | `tbd` | +| log/syslog | `nondet` | +| maps | `gnics` | +| math | `part` | +| math/big | `tbd` | +| math/bits | `todo` | +| math/cmplx | `tbd` | +| math/rand | `todo` | +| mime | `tbd` | +| mime/multipart | `tbd` | +| mime/quotedprintable | `tbd` | +| net | `nondet` | +| net/http | `nondet` | +| net/http/cgi | `nondet` | +| net/http/cookiejar | `nondet` | +| net/http/fcgi | `nondet` | +| net/http/httptest | `nondet` | +| net/http/httptrace | `nondet` | +| net/http/httputil | `nondet` | +| net/http/internal | `nondet` | +| net/http/pprof | `nondet` | +| net/mail | `nondet` | +| net/netip | `nondet` | +| net/rpc | `nondet` | +| net/rpc/jsonrpc | `nondet` | +| net/smtp | `nondet` | +| net/textproto | `nondet` | +| net/url | `full` | +| os | `nondet` | +| os/exec | `nondet` | +| os/signal | `nondet` | +| os/user | `nondet` | +| path | `full` | +| path/filepath | `nondet` | +| plugin | `nondet` | +| reflect | `todo` | +| regexp | `full` | +| regexp/syntax | `full` | +| runtime | `gospec` | +| runtime/asan | `gospec` | +| runtime/cgo | `gospec` | +| runtime/coverage | `gospec` | +| runtime/debug | `gospec` | +| runtime/metrics | `gospec` | +| runtime/msan | `gospec` | +| runtime/pprof | `gospec` | +| runtime/race | `gospec` | +| runtime/trace | `gospec` | +| slices | `gnics` | +| sort | `part`[^6] | +| strconv | `part` | +| strings | `full` | +| sync | `tbd` | +| sync/atomic | `tbd` | +| syscall | `nondet` | +| syscall/js | `nondet` | +| testing | `part` | +| testing/fstest | `tbd` | +| testing/iotest | `tbd` | +| testing/quick | `tbd` | +| text/scanner | `todo` | +| text/tabwriter | `todo` | +| text/template | `todo` | +| text/template/parse | `todo` | +| time | `full`[^7] | +| time/tzdata | `tbd` | +| unicode | `full` | +| unicode/utf16 | `tbd` | +| unicode/utf8 | `full` | +| unsafe | `nondet` | +[^1]: `builtin` is a "fake" package that exists to document the behaviour of + some builtin functions. The "fake" package does not currently exist in Gno, + but [all functions up to Go 1.17 exist](https://pkg.go.dev/builtin@go1.17), + except for those relating to complex or channel types. +[^2]: `crypto/sha1` and `crypto/md5` implement "deprecated" hashing + algorithms, widely considered unsafe for cryptographic hashing. Decision on + whether to include these as part of the official standard libraries is still + pending. +[^3]: `crypto/sha256` is currently only implemented for `Sum256`, which should + still cover a majority of use cases. A full implementation is welcome. +[^4]: like many other encoding packages, `fmt` depends on `reflect` to be added. + For now, package `gno.land/p/demo/ufmt` may do what you need. In test + functions, `fmt` works. +[^5]: `io/ioutil` [is deprecated in Go.](https://pkg.go.dev/io/ioutil) + Its functionality has been moved to packages `os` and `io`. The functions + which have been moved in `io` are implemented in that package. +[^6]: `sort` has the notable omission of `sort.Slice`. You'll need to write a + bit of boilerplate, but you can use `sort.Interface` + `sort.Sort`! +[^7]: `time.Now` returns the block time rather than the system time, for + determinism. Concurrent functionality (such as `time.Ticker`) is not implemented. ## Tooling (`gno` binary) @@ -353,15 +289,16 @@ Additional native types: | go doc | gno doc | limited compatibility; see https://github.com/gnolang/gno/issues/522 | | go env | | | | go fix | | | -| go fmt | | | +| go fmt | | gofmt (& similar tools, like gofumpt) works on gno code. | | go generate | | | -| go get | | | -| go help | | | +| go get | | see `gno mod download`. | +| go help | gno $cmd --help | ie. `gno doc --help` | | go install | | | | go list | | | -| go mod | | | -| + go mod download | gno mod download | same behavior | +| go mod | gno mod | | | + go mod init | gno mod init | same behavior | +| + go mod download | gno mod download | same behavior | +| + go mod tidy | gno mod tidy | same behavior | | | gno precompile | | | go work | | | | | gno repl | |