diff --git a/.github/workflows/test_template.yml b/.github/workflows/test_template.yml index 18911415087..38fa10e096b 100644 --- a/.github/workflows/test_template.yml +++ b/.github/workflows/test_template.yml @@ -42,7 +42,7 @@ jobs: # confusing and meticulous. There will be some improvements in Go # 1.23 regarding coverage, so we can use this as a workaround until # then. - go test -covermode=atomic -timeout ${{ inputs.tests-timeout }} -v ./... -test.gocoverdir=$GOCOVERDIR + go test -covermode=atomic -timeout ${{ inputs.tests-timeout }} ./... -test.gocoverdir=$GOCOVERDIR # Print results (set +x; echo 'go coverage results:') diff --git a/Makefile b/Makefile index fe862d52893..5cf8c8c58f9 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ VERIFY_MOD_SUMS ?= false ######################################## # Dev tools .PHONY: install -install: install.gnokey install.gno install.gnodev +install: install.gnokey install.gno install.gnodev install.gnogenesis # shortcuts to frequently used commands from sub-components. .PHONY: install.gnokey @@ -45,6 +45,11 @@ install.gno: install.gnodev: $(MAKE) --no-print-directory -C ./contribs/gnodev install @printf "\033[0;32m[+] 'gnodev' has been installed. Read more in ./contribs/gnodev/\033[0m\n" +.PHONY: install.gnogenesis +install.gnogenesis: + $(MAKE) --no-print-directory -C ./contribs/gnogenesis install + @printf "\033[0;32m[+] 'gnogenesis' has been installed. Read more in ./contribs/gnogenesis/\033[0m\n" + # old aliases .PHONY: install_gnokey diff --git a/contribs/gnogenesis/Makefile b/contribs/gnogenesis/Makefile new file mode 100644 index 00000000000..20f234e7e36 --- /dev/null +++ b/contribs/gnogenesis/Makefile @@ -0,0 +1,18 @@ +rundep := go run -modfile ../../misc/devdeps/go.mod +golangci_lint := $(rundep) github.com/golangci/golangci-lint/cmd/golangci-lint + + +.PHONY: install +install: + go install . + +.PHONY: build +build: + go build -o build/gnogenesis . + +lint: + $(golangci_lint) --config ../../.github/golangci.yml run ./... + +test: + go test $(GOTEST_FLAGS) -v ./... + diff --git a/contribs/gnogenesis/README.md b/contribs/gnogenesis/README.md new file mode 100644 index 00000000000..ae8daa6b81c --- /dev/null +++ b/contribs/gnogenesis/README.md @@ -0,0 +1,181 @@ +## Overview + +`gnogenesis` is a CLI tool for managing the Gnoland blockchain's `genesis.json` file. It provides +subcommands for setting up and manipulating the genesis file, from generating a new genesis configuration to managing +initial validators, balances, and transactions. + +Refer to specific command help options (`--help`) for further customization options. + +## Installation + +To install gnogenesis, clone the repository and build the tool: + +```shell +git clone https://github.com/gnoland/gno.git +cd gno +make install.gnogenesis +``` + +This will compile and install `gnogenesis` to your system path, allowing you to run commands directly. + +## Features + +### Generate a `genesis.json` + +To create a new genesis.json, use the `generate` subcommand. You can specify parameters such as chain ID, block limits, +and more: + +```shell +gnogenesis generate --chain-id gno-dev --block-max-gas 100000000 --output-path ./genesis.json +``` + +This command generates a genesis.json file with custom parameters, defining the chain’s identity, block limits, and +more. By default, the genesis-time is set to the current timestamp, or you can specify a future time for scheduled chain +launches. + +Keep in mind the `genesis.json` is generated with an empty validator set, and you will need to manually add the initial +validators. + +### Manage initial validators + +The `validator` subcommands allow you to add or remove validators directly in the genesis file. + +#### Add a validator + +To add a validator, specify their `address`, `name`, and `pub-key`: + +```shell +gnogenesis validator add --address g1rzuwh5frve732k4futyw45y78rzuty4626zy6h --name validator1 --pub-key gpub1pggj7ard9eg82cjtv4u52epjx56nzwgjyg9zplmcmggxyxyrch0zcyg684yxmerullv3l6hmau58sk4eyxskmny9h7lsnz +``` + +This command will add the validator with the specified details in the genesis file. + +The `address` and `pub-key` values need to be in bech32 format. They can be fetched using `gnoland secrets get`. + +#### Remove a validator + +If you need to remove a validator, specify their address: + +```shell +gnogenesis validator remove --address g1rzuwh5frve732k4futyw45y78rzuty4626zy6h +``` + +This will remove the specified validator from the validator set in `genesis.json`, if it is present. + +### Verify the `genesis.json` + +The `verify` subcommand is helpful to confirm the integrity of a `genesis.json` file: + +```shell +gnogenesis verify --genesis-path ./genesis.json +``` + +This validation checks for proper structure, account balance totals, and ensures validators are correctly configured, +preventing common genesis setup issues. It is advised to always run this verification step when dealing with an external +`genesis.json`. + +### Manage account balances + +Balances can be added or removed through the balances subcommand, either individually or using a balance sheet file. + +The format for individual balance entries is `
=ugnot`. + +#### Add Account Balances + +Add a single balance directly: + +```shell +gnogenesis balances add --single g1rzuwh5frve732k4futyw45y78rzuty4626zy6h=100ugnot +``` + +Alternatively, load multiple accounts with a balance sheet file: + +```shell +gnogenesis balances add --balance-sheet ./balances.txt +``` + +The format of the balance sheet file is the same as with individual entries, for example: + +```text +# Test accounts. +g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5=10000000000000ugnot # test1 +g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj=10000000000000ugnot # test2 + +# Faucet accounts. +g1f4v282mwyhu29afke4vq5r2xzcm6z3ftnugcnv=1000000000000ugnot # faucet0 (jae) +g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa=1000000000000ugnot # faucet1 (moul) +g1q6jrp203fq0239pv38sdq3y3urvd6vt5azacpv=1000000000000ugnot # faucet2 (devx) +g13d7jc32adhc39erm5me38w5v7ej7lpvlnqjk73=1000000000000ugnot # faucet3 (devx) +g18l9us6trqaljw39j94wzf5ftxmd9qqkvrxghd2=1000000000000ugnot # faucet4 (adena) +``` + +This will update `genesis.json` with the provided accounts and balances. + +#### Remove account balances + +To remove an account’s balance from `genesis.json`, use: + +```shell +gnogenesis balances remove --address g1rzuwh5frve732k4futyw45y78rzuty4626zy6h +``` + +This deletes the balance entry for the specified address, if present. + +### Handle genesis transactions + +The `txs` subcommand allows you to manage initial transactions. + +It is a bit more robust than the `balances` command suite, in the sense that it supports: + +- adding transactions from transaction sheets +- generating and adding deploy transactions from a directory (ex. like `examples`) + +The format for transactions in the transaction sheet is the following: + +- Transaction (`std.Tx`) is encoded in Amino JSON +- Transactions are saved single-line, 1 line 1 tx +- File format of the transaction sheet file is `jsonl` + +#### Add genesis transactions + +To add genesis transactions from a file: + +```shell +gnogenesis txs add sheets ./txs.json +``` + +This outputs the initial transaction count. + +An example transaction sheet: + +```json lines +{"msg":[{"@type":"/vm.m_call","caller":"g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq","send":"","pkg_path":"gno.land/r/demo/users","func":"Invite","args":["g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj:10\ng1589c8cekvmjfmy0qrd4f3z52r7fn7rgk02667s:1\ng13sm84nuqed3fuank8huh7x9mupgw22uft3lcl8:1\ng1m6732pkrngu9vrt0g7056lvr9kcqc4mv83xl5q:1\ng1wg88rhzlwxjd2z4j5de5v5xq30dcf6rjq3dhsj:1\ng18pmaskasz7mxj6rmgrl3al58xu45a7w0l5nmc0:1\ng19wwhkmqlns70604ksp6rkuuu42qhtvyh05lffz:1\ng187982000zsc493znqt828s90cmp6hcp2erhu6m:1\ng1ndpsnrspdnauckytvkfv8s823t3gmpqmtky8pl:1\ng16ja66d65emkr0zxd2tu7xjvm7utthyhpej0037:1\ng1ds24jj9kqjcskd0gzu24r9e4n62ggye230zuv5:1\ng1trkzq75ntamsnw9xnrav2v7gy2lt5g6p29yhdr:1\ng1rrf8s5mrmu00sx04fzfsvc399fklpeg2x0a7mz:1\ng19p5ntfvpt4lwq4jqsmnxsnelhf3tff9scy3w8w:1\ng1tue8l73d6rq4vhqdsp2sr3zhuzpure3k2rnwpz:1\ng14hhsss4ngx5kq77je5g0tl4vftg8qp45ceadk3:1\ng1768hvkh7anhd40ch4h7jdh6j3mpcs7hrat4gl0:1\ng15fa8kyjhu88t9dr8zzua8fwdvkngv5n8yqsm0n:1\ng1xhccdjcscuhgmt3quww6qdy3j3czqt3urc2eac:1\ng1z629z04f85k4t5gnkk5egpxw9tqxeec435esap:1\ng1pfldkplz9puq0v82lu9vqcve9nwrxuq9qe5ttv:1\ng152pn0g5qfgxr7yx8zlwjq48hytkafd8x7egsfv:1\ng1cf2ye686ke38vjyqakreprljum4xu6rwf5jskq:1\ng1c5shztyaj4gjrc5zlwmh9xhex5w7l4asffs2w6:1\ng1lhpx2ktk0ha3qw42raxq4m24a4c4xqxyrgv54q:1\ng1026p54q0j902059sm2zsv37krf0ghcl7gmhyv7:1\ng1n4yvwnv77frq2ccuw27dmtjkd7u4p4jg0pgm7k:1\ng13m7f2e6r3lh3ykxupacdt9sem2tlvmaamwjhll:1\ng19uxluuecjlsqvwmwu8sp6pxaaqfhk972q975xd:1\ng1j80fpcsumfkxypvydvtwtz3j4sdwr8c2u0lr64:1\ng1tjdpptuk9eysq6z38nscqyycr998xjyx3w8jvw:1\ng19t3n89slfemgd3mwuat4lajwcp0yxrkadgeg7a:1\ng1yqndt8xx92l9h494jfruz2w79swzjes3n4wqjc:1\ng13278z0a5ufeg80ffqxpda9dlp599t7ekregcy6:1\ng1ht236wjd83x96uqwh9rh3fq6pylyn78mtwq9v6:1\ng1fj9jccm3zjnqspq7lp2g7lj4czyfq0s35600g9:1\ng1wwppuzdns5u6c6jqpkzua24zh6ppsus6399cea:1\ng1k8pjnguyu36pkc8hy0ufzgpzfmj2jl78la7ek3:1\ng1e8umkzumtxgs8399lw0us4rclea3xl5gxy9spp:1\ng14qekdkj2nmmwea4ufg9n002a3pud23y8k7ugs5:1\ng19w2488ntfgpduzqq3sk4j5x387zynwknqdvjqf:1\ng1495y3z7zrej4rendysnw5kaeu4g3d7x7w0734g:1\ng1hygx8ga9qakhkczyrzs9drm8j8tu4qds9y5e3r:1\ng1f977l6wxdh3qu60kzl75vx2wmzswu68l03r8su:1\ng1644qje5rx6jsdqfkzmgnfcegx4dxkjh6rwqd69:1\ng1mzjajymvmtksdwh3wkrndwj6zls2awl9q83dh6:1\ng14da4n9hcynyzz83q607uu8keuh9hwlv42ra6fa:10\ng14vhcdsyf83ngsrrqc92kmw8q9xakqjm0v8448t:5\n"]}],"fee":{"gas_wanted":"2000000","gas_fee":"1000000ugnot"},"signatures":[{"pub_key":{"@type":"/tm.PubKeySecp256k1","value":"AmG6kzznyo1uNqWPAYU6wDpsmzQKDaEOrVRaZ08vOyX0"},"signature":"S8iMMzlOMK8dmox78R9Z8+pSsS8YaTCXrIcaHDpiOgkOy7gqoQJ0oftM0zf8zAz4xpezK8Lzg8Q0fCdXJxV76w=="}],"memo":""} +{"msg":[{"@type":"/vm.m_call","caller":"g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq","send":"","pkg_path":"gno.land/r/demo/users","func":"Invite","args":["g1thlf3yct7n7ex70k0p62user0kn6mj6d3s0cg3\ng1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5\n"]}],"fee":{"gas_wanted":"2000000","gas_fee":"1000000ugnot"},"signatures":[{"pub_key":{"@type":"/tm.PubKeySecp256k1","value":"AmG6kzznyo1uNqWPAYU6wDpsmzQKDaEOrVRaZ08vOyX0"},"signature":"njczE6xYdp01+CaUU/8/v0YC/NuZD06+qLind+ZZEEMNaRe/4Ln+4z7dG6HYlaWUMsyI1KCoB6NIehoE0PZ44Q=="}],"memo":""} +{"msg":[{"@type":"/vm.m_call","caller":"g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq","send":"","pkg_path":"gno.land/r/demo/users","func":"Invite","args":["g1589c8cekvmjfmy0qrd4f3z52r7fn7rgk02667s\ng13sm84nuqed3fuank8huh7x9mupgw22uft3lcl8\ng1m6732pkrngu9vrt0g7056lvr9kcqc4mv83xl5q\ng1wg88rhzlwxjd2z4j5de5v5xq30dcf6rjq3dhsj\ng18pmaskasz7mxj6rmgrl3al58xu45a7w0l5nmc0\ng19wwhkmqlns70604ksp6rkuuu42qhtvyh05lffz\ng187982000zsc493znqt828s90cmp6hcp2erhu6m\ng1ndpsnrspdnauckytvkfv8s823t3gmpqmtky8pl\ng16ja66d65emkr0zxd2tu7xjvm7utthyhpej0037\ng1ds24jj9kqjcskd0gzu24r9e4n62ggye230zuv5\ng1trkzq75ntamsnw9xnrav2v7gy2lt5g6p29yhdr\ng1rrf8s5mrmu00sx04fzfsvc399fklpeg2x0a7mz\ng19p5ntfvpt4lwq4jqsmnxsnelhf3tff9scy3w8w\ng1tue8l73d6rq4vhqdsp2sr3zhuzpure3k2rnwpz\ng14hhsss4ngx5kq77je5g0tl4vftg8qp45ceadk3\ng1768hvkh7anhd40ch4h7jdh6j3mpcs7hrat4gl0\ng15fa8kyjhu88t9dr8zzua8fwdvkngv5n8yqsm0n\ng1xhccdjcscuhgmt3quww6qdy3j3czqt3urc2eac\ng1z629z04f85k4t5gnkk5egpxw9tqxeec435esap\ng1pfldkplz9puq0v82lu9vqcve9nwrxuq9qe5ttv\ng152pn0g5qfgxr7yx8zlwjq48hytkafd8x7egsfv\ng1cf2ye686ke38vjyqakreprljum4xu6rwf5jskq\ng1c5shztyaj4gjrc5zlwmh9xhex5w7l4asffs2w6\ng1lhpx2ktk0ha3qw42raxq4m24a4c4xqxyrgv54q\ng1026p54q0j902059sm2zsv37krf0ghcl7gmhyv7\ng1n4yvwnv77frq2ccuw27dmtjkd7u4p4jg0pgm7k\ng13m7f2e6r3lh3ykxupacdt9sem2tlvmaamwjhll\ng19uxluuecjlsqvwmwu8sp6pxaaqfhk972q975xd\ng1j80fpcsumfkxypvydvtwtz3j4sdwr8c2u0lr64\ng1tjdpptuk9eysq6z38nscqyycr998xjyx3w8jvw\ng19t3n89slfemgd3mwuat4lajwcp0yxrkadgeg7a\ng1yqndt8xx92l9h494jfruz2w79swzjes3n4wqjc\ng13278z0a5ufeg80ffqxpda9dlp599t7ekregcy6\ng1ht236wjd83x96uqwh9rh3fq6pylyn78mtwq9v6\ng1fj9jccm3zjnqspq7lp2g7lj4czyfq0s35600g9\ng1wwppuzdns5u6c6jqpkzua24zh6ppsus6399cea\ng1k8pjnguyu36pkc8hy0ufzgpzfmj2jl78la7ek3\ng1e8umkzumtxgs8399lw0us4rclea3xl5gxy9spp\ng14qekdkj2nmmwea4ufg9n002a3pud23y8k7ugs5\ng19w2488ntfgpduzqq3sk4j5x387zynwknqdvjqf\ng1495y3z7zrej4rendysnw5kaeu4g3d7x7w0734g\ng1hygx8ga9qakhkczyrzs9drm8j8tu4qds9y5e3r\ng1f977l6wxdh3qu60kzl75vx2wmzswu68l03r8su\ng1644qje5rx6jsdqfkzmgnfcegx4dxkjh6rwqd69\ng1mzjajymvmtksdwh3wkrndwj6zls2awl9q83dh6\ng1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq\ng14da4n9hcynyzz83q607uu8keuh9hwlv42ra6fa\ng14vhcdsyf83ngsrrqc92kmw8q9xakqjm0v8448t\n"]}],"fee":{"gas_wanted":"4000000","gas_fee":"1000000ugnot"},"signatures":[{"pub_key":{"@type":"/tm.PubKeySecp256k1","value":"AmG6kzznyo1uNqWPAYU6wDpsmzQKDaEOrVRaZ08vOyX0"},"signature":"7AmlhZhsVkxCUl0bbpvpPMnIKihwtG7A5IFR6Tg4xStWLgaUr05XmWRKlO2xjstTtwbVKQT5mFL4h5wyX4SQzw=="}],"memo":""} +``` + +To add genesis (deploy) transactions from a directory: + +```shell +gnogenesis txs add packages ./examples +``` + +This will generate `MsgAddPkg` transactions, and add them to the given `genesis.json`. + +#### Remove genesis transactions + +To clear specific transactions, use the transaction hash: + +```shell +gnogenesis txs remove "5HuU9LN8WUa2NsjiNxp8Xii9n0zlSGXc9UqzLHB+DPs=" +``` + +The transaction hash is the base64 encoding of the Amino-Binary encoded `std.Tx` transaction hash. + +The steps to get this sort of hash are: + +- get the `std.Tx` +- marshal it using `amino.Marshal` +- cast the result to `types.Tx` (`bft`) +- call `Hash` on the `types.Tx` +- encode the result into base64 diff --git a/contribs/gnogenesis/genesis.go b/contribs/gnogenesis/genesis.go new file mode 100644 index 00000000000..839e5fbe653 --- /dev/null +++ b/contribs/gnogenesis/genesis.go @@ -0,0 +1,32 @@ +package main + +import ( + "github.com/gnolang/contribs/gnogenesis/internal/balances" + "github.com/gnolang/contribs/gnogenesis/internal/generate" + "github.com/gnolang/contribs/gnogenesis/internal/txs" + "github.com/gnolang/contribs/gnogenesis/internal/validator" + "github.com/gnolang/contribs/gnogenesis/internal/verify" + "github.com/gnolang/gno/tm2/pkg/commands" +) + +func newGenesisCmd(io commands.IO) *commands.Command { + cmd := commands.NewCommand( + commands.Metadata{ + ShortUsage: " [flags] [...]", + ShortHelp: "gno genesis manipulation suite", + LongHelp: "Gno genesis.json manipulation suite, for managing genesis parameters", + }, + commands.NewEmptyConfig(), + commands.HelpExec, + ) + + cmd.AddSubCommands( + generate.NewGenerateCmd(io), + validator.NewValidatorCmd(io), + verify.NewVerifyCmd(io), + balances.NewBalancesCmd(io), + txs.NewTxsCmd(io), + ) + + return cmd +} diff --git a/contribs/gnogenesis/go.mod b/contribs/gnogenesis/go.mod new file mode 100644 index 00000000000..cdd8922fad5 --- /dev/null +++ b/contribs/gnogenesis/go.mod @@ -0,0 +1,62 @@ +module github.com/gnolang/contribs/gnogenesis + +go 1.22 + +require ( + github.com/gnolang/gno v0.0.0-00010101000000-000000000000 + github.com/stretchr/testify v1.9.0 +) + +replace github.com/gnolang/gno => ../.. + +require ( + dario.cat/mergo v1.0.1 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect + github.com/btcsuite/btcd/btcutil v1.1.6 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cockroachdb/apd/v3 v3.2.1 // indirect + github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect + github.com/gnolang/overflow v0.0.0-20170615021017-4d914c927216 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // 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/pmezard/go-difflib v1.0.0 // indirect + github.com/rs/cors v1.11.1 // indirect + github.com/rs/xid v1.6.0 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/zondax/hid v0.9.2 // indirect + github.com/zondax/ledger-go v0.14.3 // indirect + go.etcd.io/bbolt v1.3.11 // indirect + go.opentelemetry.io/otel v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0 // indirect + go.opentelemetry.io/otel/metric v1.29.0 // indirect + go.opentelemetry.io/otel/sdk v1.29.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.29.0 // indirect + go.opentelemetry.io/otel/trace v1.29.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect + google.golang.org/grpc v1.65.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/contribs/gnogenesis/go.sum b/contribs/gnogenesis/go.sum new file mode 100644 index 00000000000..28c509e381e --- /dev/null +++ b/contribs/gnogenesis/go.sum @@ -0,0 +1,230 @@ +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= +github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= +github.com/btcsuite/btcd v0.24.2 h1:aLmxPguqxza+4ag8R1I2nnJjSu2iFn/kqtHTIImswcY= +github.com/btcsuite/btcd v0.24.2/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg= +github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= +github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= +github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= +github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00= +github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c= +github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +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/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/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/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/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= +github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= +github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= +github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= +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/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +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/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +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/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= +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.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +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/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= +github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= +github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= +go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0/go.mod h1:t4BrYLHU450Zo9fnydWlIuswB1bm7rM8havDpWOJeDo= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0 h1:xvhQxJ/C9+RTnAj5DpTg7LSM1vbbMTiXt7e9hsfqHNw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0/go.mod h1:Fcvs2Bz1jkDM+Wf5/ozBGmi3tQ/c9zPKLnsipnfhGAo= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= +go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= +go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= +go.opentelemetry.io/otel/sdk/metric v1.29.0 h1:K2CfmJohnRgvZ9UAj2/FhIf/okdWcNdBwe1m8xFXiSY= +go.opentelemetry.io/otel/sdk/metric v1.29.0/go.mod h1:6zZLdCl2fkauYoZIOn/soQIDSWFmNSRcICarHfuhNJQ= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/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-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +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/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/gno.land/cmd/gnoland/genesis_balances.go b/contribs/gnogenesis/internal/balances/balances.go similarity index 68% rename from gno.land/cmd/gnoland/genesis_balances.go rename to contribs/gnogenesis/internal/balances/balances.go index c8cd1c539f5..bdfa5aa38d0 100644 --- a/gno.land/cmd/gnoland/genesis_balances.go +++ b/contribs/gnogenesis/internal/balances/balances.go @@ -1,23 +1,24 @@ -package main +package balances import ( "flag" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/tm2/pkg/commands" ) type balancesCfg struct { - commonCfg + common.Cfg } -// newBalancesCmd creates the genesis balances subcommand -func newBalancesCmd(io commands.IO) *commands.Command { +// NewBalancesCmd creates the genesis balances subcommand +func NewBalancesCmd(io commands.IO) *commands.Command { cfg := &balancesCfg{} cmd := commands.NewCommand( commands.Metadata{ Name: "balances", - ShortUsage: "balances [flags]", + ShortUsage: " [flags]", ShortHelp: "manages genesis.json account balances", LongHelp: "Manipulates the initial genesis.json account balances (pre-mines)", }, @@ -35,5 +36,5 @@ func newBalancesCmd(io commands.IO) *commands.Command { } func (c *balancesCfg) RegisterFlags(fs *flag.FlagSet) { - c.commonCfg.RegisterFlags(fs) + c.Cfg.RegisterFlags(fs) } diff --git a/gno.land/cmd/gnoland/genesis_balances_add.go b/contribs/gnogenesis/internal/balances/balances_add.go similarity index 98% rename from gno.land/cmd/gnoland/genesis_balances_add.go rename to contribs/gnogenesis/internal/balances/balances_add.go index f9a898715c8..a17a13f8bc8 100644 --- a/gno.land/cmd/gnoland/genesis_balances_add.go +++ b/contribs/gnogenesis/internal/balances/balances_add.go @@ -1,4 +1,4 @@ -package main +package balances import ( "bufio" @@ -77,7 +77,7 @@ func (c *balancesAddCfg) RegisterFlags(fs *flag.FlagSet) { func execBalancesAdd(ctx context.Context, cfg *balancesAddCfg, io commands.IO) error { // Load the genesis - genesis, loadErr := types.GenesisDocFromFile(cfg.rootCfg.genesisPath) + genesis, loadErr := types.GenesisDocFromFile(cfg.rootCfg.GenesisPath) if loadErr != nil { return fmt.Errorf("unable to load genesis, %w", loadErr) } @@ -156,7 +156,7 @@ func execBalancesAdd(ctx context.Context, cfg *balancesAddCfg, io commands.IO) e genesis.AppState = state // Save the updated genesis - if err := genesis.SaveAs(cfg.rootCfg.genesisPath); err != nil { + if err := genesis.SaveAs(cfg.rootCfg.GenesisPath); err != nil { return fmt.Errorf("unable to save genesis.json, %w", err) } diff --git a/gno.land/cmd/gnoland/genesis_balances_add_test.go b/contribs/gnogenesis/internal/balances/balances_add_test.go similarity index 92% rename from gno.land/cmd/gnoland/genesis_balances_add_test.go rename to contribs/gnogenesis/internal/balances/balances_add_test.go index 8f2879f9c57..29ffe19d95a 100644 --- a/gno.land/cmd/gnoland/genesis_balances_add_test.go +++ b/contribs/gnogenesis/internal/balances/balances_add_test.go @@ -1,4 +1,4 @@ -package main +package balances import ( "bytes" @@ -7,6 +7,7 @@ import ( "strings" "testing" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/gno.land/pkg/gnoland/ugnot" "github.com/gnolang/gno/tm2/pkg/amino" @@ -24,10 +25,8 @@ func TestGenesis_Balances_Add(t *testing.T) { t.Run("invalid genesis", func(t *testing.T) { // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "add", "--genesis-path", "dummy-path", @@ -35,7 +34,7 @@ func TestGenesis_Balances_Add(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - require.ErrorContains(t, cmdErr, errUnableToLoadGenesis.Error()) + require.ErrorContains(t, cmdErr, common.ErrUnableToLoadGenesis.Error()) }) t.Run("no sources selected", func(t *testing.T) { @@ -44,14 +43,12 @@ func TestGenesis_Balances_Add(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "add", "--genesis-path", tempGenesis.Name(), @@ -66,10 +63,8 @@ func TestGenesis_Balances_Add(t *testing.T) { t.Parallel() // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "add", "--genesis-path", "dummy-path", @@ -77,25 +72,23 @@ func TestGenesis_Balances_Add(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - assert.ErrorContains(t, cmdErr, errUnableToLoadGenesis.Error()) + assert.ErrorContains(t, cmdErr, common.ErrUnableToLoadGenesis.Error()) }) t.Run("balances from entries", func(t *testing.T) { t.Parallel() - dummyKeys := getDummyKeys(t, 2) + dummyKeys := common.GetDummyKeys(t, 2) tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "add", "--genesis-path", tempGenesis.Name(), @@ -155,10 +148,10 @@ func TestGenesis_Balances_Add(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) - dummyKeys := getDummyKeys(t, 10) + dummyKeys := common.GetDummyKeys(t, 10) amount := std.NewCoins(std.NewCoin(ugnot.Denom, 10)) balances := make([]string, len(dummyKeys)) @@ -182,10 +175,8 @@ func TestGenesis_Balances_Add(t *testing.T) { require.NoError(t, err) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "add", "--genesis-path", tempGenesis.Name(), @@ -233,11 +224,11 @@ func TestGenesis_Balances_Add(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) var ( - dummyKeys = getDummyKeys(t, 10) + dummyKeys = common.GetDummyKeys(t, 10) amount = std.NewCoins(std.NewCoin(ugnot.Denom, 10)) amountCoins = std.NewCoins(std.NewCoin(ugnot.Denom, 10)) gasFee = std.NewCoin(ugnot.Denom, 1000000) @@ -282,10 +273,8 @@ func TestGenesis_Balances_Add(t *testing.T) { require.NoError(t, err) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "add", "--genesis-path", tempGenesis.Name(), @@ -337,12 +326,12 @@ func TestGenesis_Balances_Add(t *testing.T) { t.Run("balances overwrite", func(t *testing.T) { t.Parallel() - dummyKeys := getDummyKeys(t, 10) + dummyKeys := common.GetDummyKeys(t, 10) tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() state := gnoland.GnoGenesisState{ // Set an initial balance value Balances: []gnoland.Balance{ @@ -356,10 +345,8 @@ func TestGenesis_Balances_Add(t *testing.T) { require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "add", "--genesis-path", tempGenesis.Name(), @@ -421,7 +408,7 @@ func TestBalances_GetBalancesFromTransactions(t *testing.T) { t.Parallel() var ( - dummyKeys = getDummyKeys(t, 10) + dummyKeys = common.GetDummyKeys(t, 10) amount = std.NewCoins(std.NewCoin(ugnot.Denom, 10)) amountCoins = std.NewCoins(std.NewCoin(ugnot.Denom, 10)) gasFee = std.NewCoin(ugnot.Denom, 1000000) @@ -479,7 +466,7 @@ func TestBalances_GetBalancesFromTransactions(t *testing.T) { t.Parallel() var ( - dummyKeys = getDummyKeys(t, 10) + dummyKeys = common.GetDummyKeys(t, 10) amountCoins = std.NewCoins(std.NewCoin(ugnot.Denom, 10)) gasFee = std.NewCoin("gnos", 1) // invalid fee txs = make([]std.Tx, 0) @@ -531,7 +518,7 @@ func TestBalances_GetBalancesFromTransactions(t *testing.T) { t.Parallel() var ( - dummyKeys = getDummyKeys(t, 10) + dummyKeys = common.GetDummyKeys(t, 10) amountCoins = std.NewCoins(std.NewCoin("gnogno", 10)) // invalid send amount gasFee = std.NewCoin(ugnot.Denom, 1) txs = make([]std.Tx, 0) diff --git a/gno.land/cmd/gnoland/genesis_balances_export.go b/contribs/gnogenesis/internal/balances/balances_export.go similarity index 89% rename from gno.land/cmd/gnoland/genesis_balances_export.go rename to contribs/gnogenesis/internal/balances/balances_export.go index ec05d115b97..df9d6795805 100644 --- a/gno.land/cmd/gnoland/genesis_balances_export.go +++ b/contribs/gnogenesis/internal/balances/balances_export.go @@ -1,10 +1,11 @@ -package main +package balances import ( "context" "fmt" "os" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/commands" @@ -28,14 +29,14 @@ func newBalancesExportCmd(balancesCfg *balancesCfg, io commands.IO) *commands.Co func execBalancesExport(cfg *balancesCfg, io commands.IO, args []string) error { // Load the genesis - genesis, loadErr := types.GenesisDocFromFile(cfg.genesisPath) + genesis, loadErr := types.GenesisDocFromFile(cfg.GenesisPath) if loadErr != nil { return fmt.Errorf("unable to load genesis, %w", loadErr) } // Load the genesis state if genesis.AppState == nil { - return errAppStateNotSet + return common.ErrAppStateNotSet } state := genesis.AppState.(gnoland.GnoGenesisState) @@ -47,7 +48,7 @@ func execBalancesExport(cfg *balancesCfg, io commands.IO, args []string) error { // Make sure the output file path is specified if len(args) == 0 { - return errNoOutputFile + return common.ErrNoOutputFile } // Open output file diff --git a/gno.land/cmd/gnoland/genesis_balances_export_test.go b/contribs/gnogenesis/internal/balances/balances_export_test.go similarity index 83% rename from gno.land/cmd/gnoland/genesis_balances_export_test.go rename to contribs/gnogenesis/internal/balances/balances_export_test.go index bd1f6152246..d4f4723df15 100644 --- a/gno.land/cmd/gnoland/genesis_balances_export_test.go +++ b/contribs/gnogenesis/internal/balances/balances_export_test.go @@ -1,10 +1,11 @@ -package main +package balances import ( "bufio" "context" "testing" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/gno.land/pkg/gnoland/ugnot" "github.com/gnolang/gno/tm2/pkg/commands" @@ -18,7 +19,7 @@ import ( func getDummyBalances(t *testing.T, count int) []gnoland.Balance { t.Helper() - dummyKeys := getDummyKeys(t, count) + dummyKeys := common.GetDummyKeys(t, count) amount := std.NewCoins(std.NewCoin(ugnot.Denom, 10)) balances := make([]gnoland.Balance, len(dummyKeys)) @@ -40,10 +41,8 @@ func TestGenesis_Balances_Export(t *testing.T) { t.Parallel() // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "export", "--genesis-path", "dummy-path", @@ -51,7 +50,7 @@ func TestGenesis_Balances_Export(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - assert.ErrorContains(t, cmdErr, errUnableToLoadGenesis.Error()) + assert.ErrorContains(t, cmdErr, common.ErrUnableToLoadGenesis.Error()) }) t.Run("invalid genesis app state", func(t *testing.T) { @@ -60,15 +59,13 @@ func TestGenesis_Balances_Export(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() genesis.AppState = nil // no app state require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "export", "--genesis-path", tempGenesis.Name(), @@ -76,7 +73,7 @@ func TestGenesis_Balances_Export(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - assert.ErrorContains(t, cmdErr, errAppStateNotSet.Error()) + assert.ErrorContains(t, cmdErr, common.ErrAppStateNotSet.Error()) }) t.Run("no output file specified", func(t *testing.T) { @@ -85,17 +82,15 @@ func TestGenesis_Balances_Export(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() genesis.AppState = gnoland.GnoGenesisState{ Balances: getDummyBalances(t, 1), } require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "export", "--genesis-path", tempGenesis.Name(), @@ -103,7 +98,7 @@ func TestGenesis_Balances_Export(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - assert.ErrorContains(t, cmdErr, errNoOutputFile.Error()) + assert.ErrorContains(t, cmdErr, common.ErrNoOutputFile.Error()) }) t.Run("valid balances export", func(t *testing.T) { @@ -115,7 +110,7 @@ func TestGenesis_Balances_Export(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() genesis.AppState = gnoland.GnoGenesisState{ Balances: balances, } @@ -126,10 +121,8 @@ func TestGenesis_Balances_Export(t *testing.T) { t.Cleanup(outputCleanup) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "export", "--genesis-path", tempGenesis.Name(), diff --git a/gno.land/cmd/gnoland/genesis_balances_remove.go b/contribs/gnogenesis/internal/balances/balances_remove.go similarity index 84% rename from gno.land/cmd/gnoland/genesis_balances_remove.go rename to contribs/gnogenesis/internal/balances/balances_remove.go index 58a02319c8d..ea2aefda5cc 100644 --- a/gno.land/cmd/gnoland/genesis_balances_remove.go +++ b/contribs/gnogenesis/internal/balances/balances_remove.go @@ -1,4 +1,4 @@ -package main +package balances import ( "context" @@ -6,16 +6,14 @@ import ( "flag" "fmt" + "github.com/gnolang/contribs/gnogenesis/internal/common" "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/crypto" ) -var ( - errUnableToLoadGenesis = errors.New("unable to load genesis") - errBalanceNotFound = errors.New("genesis balances entry does not exist") -) +var errBalanceNotFound = errors.New("genesis balances entry does not exist") type balancesRemoveCfg struct { rootCfg *balancesCfg @@ -53,9 +51,9 @@ func (c *balancesRemoveCfg) RegisterFlags(fs *flag.FlagSet) { func execBalancesRemove(cfg *balancesRemoveCfg, io commands.IO) error { // Load the genesis - genesis, loadErr := types.GenesisDocFromFile(cfg.rootCfg.genesisPath) + genesis, loadErr := types.GenesisDocFromFile(cfg.rootCfg.GenesisPath) if loadErr != nil { - return fmt.Errorf("%w, %w", errUnableToLoadGenesis, loadErr) + return fmt.Errorf("%w, %w", common.ErrUnableToLoadGenesis, loadErr) } // Validate the address @@ -66,7 +64,7 @@ func execBalancesRemove(cfg *balancesRemoveCfg, io commands.IO) error { // Check if the genesis state is set at all if genesis.AppState == nil { - return errAppStateNotSet + return common.ErrAppStateNotSet } // Construct the initial genesis balance sheet @@ -90,7 +88,7 @@ func execBalancesRemove(cfg *balancesRemoveCfg, io commands.IO) error { genesis.AppState = state // Save the updated genesis - if err := genesis.SaveAs(cfg.rootCfg.genesisPath); err != nil { + if err := genesis.SaveAs(cfg.rootCfg.GenesisPath); err != nil { return fmt.Errorf("unable to save genesis.json, %w", err) } diff --git a/gno.land/cmd/gnoland/genesis_balances_remove_test.go b/contribs/gnogenesis/internal/balances/balances_remove_test.go similarity index 81% rename from gno.land/cmd/gnoland/genesis_balances_remove_test.go rename to contribs/gnogenesis/internal/balances/balances_remove_test.go index ed11836ba4d..ab99a31c0a9 100644 --- a/gno.land/cmd/gnoland/genesis_balances_remove_test.go +++ b/contribs/gnogenesis/internal/balances/balances_remove_test.go @@ -1,9 +1,10 @@ -package main +package balances import ( "context" "testing" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/gno.land/pkg/gnoland/ugnot" "github.com/gnolang/gno/tm2/pkg/bft/types" @@ -19,10 +20,8 @@ func TestGenesis_Balances_Remove(t *testing.T) { t.Run("invalid genesis", func(t *testing.T) { // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "remove", "--genesis-path", "dummy-path", @@ -30,26 +29,24 @@ func TestGenesis_Balances_Remove(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - require.ErrorContains(t, cmdErr, errUnableToLoadGenesis.Error()) + require.ErrorContains(t, cmdErr, common.ErrUnableToLoadGenesis.Error()) }) t.Run("genesis app state not set", func(t *testing.T) { t.Parallel() - dummyKey := getDummyKey(t) + dummyKey := common.GetDummyKey(t) tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() genesis.AppState = nil // not set require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "remove", "--genesis-path", tempGenesis.Name(), @@ -59,18 +56,18 @@ func TestGenesis_Balances_Remove(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - require.ErrorContains(t, cmdErr, errAppStateNotSet.Error()) + require.ErrorContains(t, cmdErr, common.ErrAppStateNotSet.Error()) }) t.Run("address is present", func(t *testing.T) { t.Parallel() - dummyKey := getDummyKey(t) + dummyKey := common.GetDummyKey(t) tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() state := gnoland.GnoGenesisState{ // Set an initial balance value Balances: []gnoland.Balance{ @@ -84,10 +81,8 @@ func TestGenesis_Balances_Remove(t *testing.T) { require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "remove", "--genesis-path", tempGenesis.Name(), @@ -114,12 +109,12 @@ func TestGenesis_Balances_Remove(t *testing.T) { t.Run("address not present", func(t *testing.T) { t.Parallel() - dummyKey := getDummyKey(t) + dummyKey := common.GetDummyKey(t) tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() state := gnoland.GnoGenesisState{ Balances: []gnoland.Balance{}, // Empty initial balance } @@ -127,10 +122,8 @@ func TestGenesis_Balances_Remove(t *testing.T) { require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewBalancesCmd(commands.NewTestIO()) args := []string{ - "genesis", - "balances", "remove", "--genesis-path", tempGenesis.Name(), diff --git a/contribs/gnogenesis/internal/common/config.go b/contribs/gnogenesis/internal/common/config.go new file mode 100644 index 00000000000..99278b77764 --- /dev/null +++ b/contribs/gnogenesis/internal/common/config.go @@ -0,0 +1,35 @@ +package common + +import ( + "flag" + "time" + + "github.com/gnolang/gno/tm2/pkg/bft/types" +) + +const DefaultChainID = "dev" + +// Cfg is the common +// configuration for genesis commands +// that require a genesis.json +type Cfg struct { + GenesisPath string +} + +func (c *Cfg) RegisterFlags(fs *flag.FlagSet) { + fs.StringVar( + &c.GenesisPath, + "genesis-path", + "./genesis.json", + "the path to the genesis.json", + ) +} + +// GetDefaultGenesis returns the default genesis config +func GetDefaultGenesis() *types.GenesisDoc { + return &types.GenesisDoc{ + GenesisTime: time.Now(), + ChainID: DefaultChainID, + ConsensusParams: types.DefaultConsensusParams(), + } +} diff --git a/contribs/gnogenesis/internal/common/errors.go b/contribs/gnogenesis/internal/common/errors.go new file mode 100644 index 00000000000..6eff43e9dc7 --- /dev/null +++ b/contribs/gnogenesis/internal/common/errors.go @@ -0,0 +1,9 @@ +package common + +import "errors" + +var ( + ErrAppStateNotSet = errors.New("genesis app state not set") + ErrNoOutputFile = errors.New("no output file path specified") + ErrUnableToLoadGenesis = errors.New("unable to load genesis") +) diff --git a/contribs/gnogenesis/internal/common/helpers.go b/contribs/gnogenesis/internal/common/helpers.go new file mode 100644 index 00000000000..2b1f473aed1 --- /dev/null +++ b/contribs/gnogenesis/internal/common/helpers.go @@ -0,0 +1,52 @@ +package common + +import ( + "testing" + + "github.com/gnolang/gno/tm2/pkg/crypto" + "github.com/gnolang/gno/tm2/pkg/crypto/bip39" + "github.com/gnolang/gno/tm2/pkg/crypto/hd" + "github.com/gnolang/gno/tm2/pkg/crypto/keys/client" + "github.com/gnolang/gno/tm2/pkg/crypto/secp256k1" + "github.com/stretchr/testify/require" +) + +// GetDummyKey generates a random public key, +// and returns the key info +func GetDummyKey(t *testing.T) crypto.PubKey { + t.Helper() + + mnemonic, err := client.GenerateMnemonic(256) + require.NoError(t, err) + + seed := bip39.NewSeed(mnemonic, "") + + return generateKeyFromSeed(seed, 0).PubKey() +} + +// generateKeyFromSeed generates a private key from +// the provided seed and index +func generateKeyFromSeed(seed []byte, index uint32) crypto.PrivKey { + pathParams := hd.NewFundraiserParams(0, crypto.CoinType, index) + + masterPriv, ch := hd.ComputeMastersFromSeed(seed) + + //nolint:errcheck // This derivation can never error out, since the path params + // are always going to be valid + derivedPriv, _ := hd.DerivePrivateKeyForPath(masterPriv, ch, pathParams.String()) + + return secp256k1.PrivKeySecp256k1(derivedPriv) +} + +// GetDummyKeys generates random keys for testing +func GetDummyKeys(t *testing.T, count int) []crypto.PubKey { + t.Helper() + + dummyKeys := make([]crypto.PubKey, count) + + for i := 0; i < count; i++ { + dummyKeys[i] = GetDummyKey(t) + } + + return dummyKeys +} diff --git a/gno.land/cmd/gnoland/genesis_generate.go b/contribs/gnogenesis/internal/generate/generate.go similarity index 85% rename from gno.land/cmd/gnoland/genesis_generate.go rename to contribs/gnogenesis/internal/generate/generate.go index 751ac14ae62..729b904d548 100644 --- a/gno.land/cmd/gnoland/genesis_generate.go +++ b/contribs/gnogenesis/internal/generate/generate.go @@ -1,4 +1,4 @@ -package main +package generate import ( "context" @@ -6,12 +6,11 @@ import ( "fmt" "time" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/commands" ) -var defaultChainID = "dev" - type generateCfg struct { outputPath string chainID string @@ -22,14 +21,14 @@ type generateCfg struct { blockTimeIota int64 } -// newGenerateCmd creates the genesis generate subcommand -func newGenerateCmd(io commands.IO) *commands.Command { +// NewGenerateCmd creates the genesis generate subcommand +func NewGenerateCmd(io commands.IO) *commands.Command { cfg := &generateCfg{} return commands.NewCommand( commands.Metadata{ Name: "generate", - ShortUsage: "generate [flags]", + ShortUsage: "[flags]", ShortHelp: "generates a fresh genesis.json", LongHelp: "Generates a node's genesis.json based on specified parameters", }, @@ -58,7 +57,7 @@ func (c *generateCfg) RegisterFlags(fs *flag.FlagSet) { fs.StringVar( &c.chainID, "chain-id", - defaultChainID, + common.DefaultChainID, "the ID of the chain", ) @@ -93,7 +92,7 @@ func (c *generateCfg) RegisterFlags(fs *flag.FlagSet) { func execGenerate(cfg *generateCfg, io commands.IO) error { // Start with the default configuration - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() // Set the genesis time if cfg.genesisTime > 0 { @@ -142,12 +141,3 @@ func execGenerate(cfg *generateCfg, io commands.IO) error { return nil } - -// getDefaultGenesis returns the default genesis config -func getDefaultGenesis() *types.GenesisDoc { - return &types.GenesisDoc{ - GenesisTime: time.Now(), - ChainID: defaultChainID, - ConsensusParams: types.DefaultConsensusParams(), - } -} diff --git a/gno.land/cmd/gnoland/genesis_generate_test.go b/contribs/gnogenesis/internal/generate/generate_test.go similarity index 89% rename from gno.land/cmd/gnoland/genesis_generate_test.go rename to contribs/gnogenesis/internal/generate/generate_test.go index f078a161662..7ac02169d77 100644 --- a/gno.land/cmd/gnoland/genesis_generate_test.go +++ b/contribs/gnogenesis/internal/generate/generate_test.go @@ -1,4 +1,4 @@ -package main +package generate import ( "context" @@ -6,6 +6,7 @@ import ( "path/filepath" "testing" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/commands" "github.com/gnolang/gno/tm2/pkg/testutils" @@ -25,10 +26,8 @@ func TestGenesis_Generate(t *testing.T) { genesisPath := filepath.Join(tempDir, "genesis.json") // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewGenerateCmd(commands.NewTestIO()) args := []string{ - "genesis", - "generate", "--output-path", genesisPath, } @@ -42,7 +41,7 @@ func TestGenesis_Generate(t *testing.T) { require.NoError(t, readErr) // Make sure the default configuration is set - defaultGenesis := getDefaultGenesis() + defaultGenesis := common.GetDefaultGenesis() defaultGenesis.GenesisTime = genesis.GenesisTime assert.Equal(t, defaultGenesis, genesis) @@ -59,10 +58,8 @@ func TestGenesis_Generate(t *testing.T) { genesisPath := filepath.Join(tempDir, "genesis.json") // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewGenerateCmd(commands.NewTestIO()) args := []string{ - "genesis", - "generate", "--chain-id", chainID, "--output-path", @@ -91,10 +88,8 @@ func TestGenesis_Generate(t *testing.T) { genesisPath := filepath.Join(tempDir, "genesis.json") // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewGenerateCmd(commands.NewTestIO()) args := []string{ - "genesis", - "generate", "--block-max-tx-bytes", fmt.Sprintf("%d", blockMaxTxBytes), "--output-path", @@ -127,10 +122,8 @@ func TestGenesis_Generate(t *testing.T) { genesisPath := filepath.Join(tempDir, "genesis.json") // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewGenerateCmd(commands.NewTestIO()) args := []string{ - "genesis", - "generate", "--block-max-data-bytes", fmt.Sprintf("%d", blockMaxDataBytes), "--output-path", @@ -163,10 +156,8 @@ func TestGenesis_Generate(t *testing.T) { genesisPath := filepath.Join(tempDir, "genesis.json") // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewGenerateCmd(commands.NewTestIO()) args := []string{ - "genesis", - "generate", "--block-max-gas", fmt.Sprintf("%d", blockMaxGas), "--output-path", @@ -199,10 +190,8 @@ func TestGenesis_Generate(t *testing.T) { genesisPath := filepath.Join(tempDir, "genesis.json") // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewGenerateCmd(commands.NewTestIO()) args := []string{ - "genesis", - "generate", "--block-time-iota", fmt.Sprintf("%d", blockTimeIota), "--output-path", @@ -235,10 +224,8 @@ func TestGenesis_Generate(t *testing.T) { genesisPath := filepath.Join(tempDir, "genesis.json") // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewGenerateCmd(commands.NewTestIO()) args := []string{ - "genesis", - "generate", "--chain-id", invalidChainID, "--output-path", diff --git a/gno.land/cmd/gnoland/genesis_txs.go b/contribs/gnogenesis/internal/txs/txs.go similarity index 65% rename from gno.land/cmd/gnoland/genesis_txs.go rename to contribs/gnogenesis/internal/txs/txs.go index 46b8d1bd29c..f8a14eafefc 100644 --- a/gno.land/cmd/gnoland/genesis_txs.go +++ b/contribs/gnogenesis/internal/txs/txs.go @@ -1,9 +1,10 @@ -package main +package txs import ( "errors" "flag" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/commands" @@ -11,19 +12,19 @@ import ( ) type txsCfg struct { - commonCfg + common.Cfg } var errInvalidGenesisStateType = errors.New("invalid genesis state type") -// newTxsCmd creates the genesis txs subcommand -func newTxsCmd(io commands.IO) *commands.Command { +// NewTxsCmd creates the genesis txs subcommand +func NewTxsCmd(io commands.IO) *commands.Command { cfg := &txsCfg{} cmd := commands.NewCommand( commands.Metadata{ Name: "txs", - ShortUsage: "txs [flags]", + ShortUsage: " [flags]", ShortHelp: "manages the initial genesis transactions", LongHelp: "Manages genesis transactions through input files", }, @@ -42,7 +43,7 @@ func newTxsCmd(io commands.IO) *commands.Command { } func (c *txsCfg) RegisterFlags(fs *flag.FlagSet) { - c.commonCfg.RegisterFlags(fs) + c.Cfg.RegisterFlags(fs) } // appendGenesisTxs saves the given transactions to the genesis doc @@ -74,3 +75,35 @@ func appendGenesisTxs(genesis *types.GenesisDoc, txs []std.Tx) error { return nil } + +// txStore is a wrapper for TM2 transactions +type txStore []std.Tx + +// leftMerge merges the two tx stores, with +// preference to the left +func (i *txStore) leftMerge(b txStore) error { + // Build out the tx hash map + txHashMap := make(map[string]struct{}, len(*i)) + + for _, tx := range *i { + txHash, err := getTxHash(tx) + if err != nil { + return err + } + + txHashMap[txHash] = struct{}{} + } + + for _, tx := range b { + txHash, err := getTxHash(tx) + if err != nil { + return err + } + + if _, exists := txHashMap[txHash]; !exists { + *i = append(*i, tx) + } + } + + return nil +} diff --git a/gno.land/cmd/gnoland/genesis_txs_add.go b/contribs/gnogenesis/internal/txs/txs_add.go similarity index 97% rename from gno.land/cmd/gnoland/genesis_txs_add.go rename to contribs/gnogenesis/internal/txs/txs_add.go index 7e7fd25b21e..22b3b1b966a 100644 --- a/gno.land/cmd/gnoland/genesis_txs_add.go +++ b/contribs/gnogenesis/internal/txs/txs_add.go @@ -1,4 +1,4 @@ -package main +package txs import ( "github.com/gnolang/gno/tm2/pkg/commands" diff --git a/gno.land/cmd/gnoland/genesis_txs_add_packages.go b/contribs/gnogenesis/internal/txs/txs_add_packages.go similarity index 92% rename from gno.land/cmd/gnoland/genesis_txs_add_packages.go rename to contribs/gnogenesis/internal/txs/txs_add_packages.go index 56d165c070b..b07adc777a7 100644 --- a/gno.land/cmd/gnoland/genesis_txs_add_packages.go +++ b/contribs/gnogenesis/internal/txs/txs_add_packages.go @@ -1,4 +1,4 @@ -package main +package txs import ( "context" @@ -16,6 +16,7 @@ import ( var errInvalidPackageDir = errors.New("invalid package directory") var ( + // Keep in sync with gno.land/cmd/start.go genesisDeployAddress = crypto.MustAddressFromString("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5") // test1 genesisDeployFee = std.NewFee(50000, std.MustParseCoin(ugnot.ValueString(1000000))) ) @@ -42,7 +43,7 @@ func execTxsAddPackages( args []string, ) error { // Load the genesis - genesis, loadErr := types.GenesisDocFromFile(cfg.genesisPath) + genesis, loadErr := types.GenesisDocFromFile(cfg.GenesisPath) if loadErr != nil { return fmt.Errorf("unable to load genesis, %w", loadErr) } @@ -69,7 +70,7 @@ func execTxsAddPackages( } // Save the updated genesis - if err := genesis.SaveAs(cfg.genesisPath); err != nil { + if err := genesis.SaveAs(cfg.GenesisPath); err != nil { return fmt.Errorf("unable to save genesis.json, %w", err) } diff --git a/gno.land/cmd/gnoland/genesis_txs_add_packages_test.go b/contribs/gnogenesis/internal/txs/txs_add_packages_test.go similarity index 88% rename from gno.land/cmd/gnoland/genesis_txs_add_packages_test.go rename to contribs/gnogenesis/internal/txs/txs_add_packages_test.go index 20c4f84c9ed..c814ccde957 100644 --- a/gno.land/cmd/gnoland/genesis_txs_add_packages_test.go +++ b/contribs/gnogenesis/internal/txs/txs_add_packages_test.go @@ -1,4 +1,4 @@ -package main +package txs import ( "context" @@ -7,6 +7,7 @@ import ( "path/filepath" "testing" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/gno.land/pkg/gnoland" vmm "github.com/gnolang/gno/gno.land/pkg/sdk/vm" "github.com/gnolang/gno/tm2/pkg/bft/types" @@ -23,10 +24,8 @@ func TestGenesis_Txs_Add_Packages(t *testing.T) { t.Parallel() // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "add", "packages", "--genesis-path", @@ -35,7 +34,7 @@ func TestGenesis_Txs_Add_Packages(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - assert.ErrorContains(t, cmdErr, errUnableToLoadGenesis.Error()) + assert.ErrorContains(t, cmdErr, common.ErrUnableToLoadGenesis.Error()) }) t.Run("invalid package dir", func(t *testing.T) { @@ -44,14 +43,12 @@ func TestGenesis_Txs_Add_Packages(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "add", "packages", "--genesis-path", @@ -69,7 +66,7 @@ func TestGenesis_Txs_Add_Packages(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Prepare the package @@ -99,10 +96,8 @@ func TestGenesis_Txs_Add_Packages(t *testing.T) { ) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "add", "packages", "--genesis-path", diff --git a/gno.land/cmd/gnoland/genesis_txs_add_sheet.go b/contribs/gnogenesis/internal/txs/txs_add_sheet.go similarity index 93% rename from gno.land/cmd/gnoland/genesis_txs_add_sheet.go rename to contribs/gnogenesis/internal/txs/txs_add_sheet.go index 261a050029c..88673bc29bd 100644 --- a/gno.land/cmd/gnoland/genesis_txs_add_sheet.go +++ b/contribs/gnogenesis/internal/txs/txs_add_sheet.go @@ -1,4 +1,4 @@ -package main +package txs import ( "context" @@ -39,7 +39,7 @@ func execTxsAddSheet( args []string, ) error { // Load the genesis - genesis, loadErr := types.GenesisDocFromFile(cfg.genesisPath) + genesis, loadErr := types.GenesisDocFromFile(cfg.GenesisPath) if loadErr != nil { return fmt.Errorf("unable to load genesis, %w", loadErr) } @@ -74,7 +74,7 @@ func execTxsAddSheet( } // Save the updated genesis - if err := genesis.SaveAs(cfg.genesisPath); err != nil { + if err := genesis.SaveAs(cfg.GenesisPath); err != nil { return fmt.Errorf("unable to save genesis.json, %w", err) } diff --git a/gno.land/cmd/gnoland/genesis_txs_add_sheet_test.go b/contribs/gnogenesis/internal/txs/txs_add_sheet_test.go similarity index 89% rename from gno.land/cmd/gnoland/genesis_txs_add_sheet_test.go rename to contribs/gnogenesis/internal/txs/txs_add_sheet_test.go index a70446cfe6c..a174905c237 100644 --- a/gno.land/cmd/gnoland/genesis_txs_add_sheet_test.go +++ b/contribs/gnogenesis/internal/txs/txs_add_sheet_test.go @@ -1,4 +1,4 @@ -package main +package txs import ( "context" @@ -6,6 +6,7 @@ import ( "strings" "testing" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/gno.land/pkg/gnoland/ugnot" "github.com/gnolang/gno/tm2/pkg/amino" @@ -70,10 +71,8 @@ func TestGenesis_Txs_Add_Sheets(t *testing.T) { t.Parallel() // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "add", "sheets", "--genesis-path", @@ -82,7 +81,7 @@ func TestGenesis_Txs_Add_Sheets(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - assert.ErrorContains(t, cmdErr, errUnableToLoadGenesis.Error()) + assert.ErrorContains(t, cmdErr, common.ErrUnableToLoadGenesis.Error()) }) t.Run("invalid txs file", func(t *testing.T) { @@ -91,14 +90,12 @@ func TestGenesis_Txs_Add_Sheets(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "add", "sheets", "--genesis-path", @@ -117,14 +114,12 @@ func TestGenesis_Txs_Add_Sheets(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "add", "sheets", "--genesis-path", @@ -142,14 +137,12 @@ func TestGenesis_Txs_Add_Sheets(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "add", "sheets", "--genesis-path", @@ -171,7 +164,7 @@ func TestGenesis_Txs_Add_Sheets(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Prepare the transactions file @@ -187,10 +180,8 @@ func TestGenesis_Txs_Add_Sheets(t *testing.T) { require.NoError(t, err) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "add", "sheets", "--genesis-path", @@ -226,7 +217,7 @@ func TestGenesis_Txs_Add_Sheets(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() genesisState := gnoland.GnoGenesisState{ Txs: txs[0 : len(txs)/2], } @@ -247,10 +238,8 @@ func TestGenesis_Txs_Add_Sheets(t *testing.T) { require.NoError(t, err) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "add", "sheets", "--genesis-path", diff --git a/gno.land/cmd/gnoland/genesis_txs_export.go b/contribs/gnogenesis/internal/txs/txs_export.go similarity index 92% rename from gno.land/cmd/gnoland/genesis_txs_export.go rename to contribs/gnogenesis/internal/txs/txs_export.go index bf54236b31f..0409f1fd0ac 100644 --- a/gno.land/cmd/gnoland/genesis_txs_export.go +++ b/contribs/gnogenesis/internal/txs/txs_export.go @@ -1,19 +1,17 @@ -package main +package txs import ( "context" - "errors" "fmt" "os" + "github.com/gnolang/contribs/gnogenesis/internal/common" "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" ) -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 { return commands.NewCommand( @@ -32,7 +30,7 @@ func newTxsExportCmd(txsCfg *txsCfg, io commands.IO) *commands.Command { func execTxsExport(cfg *txsCfg, io commands.IO, args []string) error { // Load the genesis - genesis, loadErr := types.GenesisDocFromFile(cfg.genesisPath) + genesis, loadErr := types.GenesisDocFromFile(cfg.GenesisPath) if loadErr != nil { return fmt.Errorf("unable to load genesis, %w", loadErr) } @@ -51,7 +49,7 @@ func execTxsExport(cfg *txsCfg, io commands.IO, args []string) error { // Make sure the output file path is specified if len(args) == 0 { - return errNoOutputFile + return common.ErrNoOutputFile } // Open output file diff --git a/gno.land/cmd/gnoland/genesis_txs_export_test.go b/contribs/gnogenesis/internal/txs/txs_export_test.go similarity index 84% rename from gno.land/cmd/gnoland/genesis_txs_export_test.go rename to contribs/gnogenesis/internal/txs/txs_export_test.go index 9927f671efb..47fc594d2ec 100644 --- a/gno.land/cmd/gnoland/genesis_txs_export_test.go +++ b/contribs/gnogenesis/internal/txs/txs_export_test.go @@ -1,10 +1,11 @@ -package main +package txs import ( "bufio" "context" "testing" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/tm2/pkg/amino" "github.com/gnolang/gno/tm2/pkg/commands" @@ -21,10 +22,8 @@ func TestGenesis_Txs_Export(t *testing.T) { t.Parallel() // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "export", "--genesis-path", "dummy-path", @@ -32,7 +31,7 @@ func TestGenesis_Txs_Export(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - assert.ErrorContains(t, cmdErr, errUnableToLoadGenesis.Error()) + assert.ErrorContains(t, cmdErr, common.ErrUnableToLoadGenesis.Error()) }) t.Run("invalid genesis app state", func(t *testing.T) { @@ -41,15 +40,13 @@ func TestGenesis_Txs_Export(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() genesis.AppState = nil // no app state require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "export", "--genesis-path", tempGenesis.Name(), @@ -66,17 +63,15 @@ func TestGenesis_Txs_Export(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() genesis.AppState = gnoland.GnoGenesisState{ Txs: generateDummyTxs(t, 1), } require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "export", "--genesis-path", tempGenesis.Name(), @@ -84,7 +79,7 @@ func TestGenesis_Txs_Export(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - assert.ErrorContains(t, cmdErr, errNoOutputFile.Error()) + assert.ErrorContains(t, cmdErr, common.ErrNoOutputFile.Error()) }) t.Run("valid txs export", func(t *testing.T) { @@ -96,7 +91,7 @@ func TestGenesis_Txs_Export(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() genesis.AppState = gnoland.GnoGenesisState{ Txs: txs, } @@ -107,10 +102,8 @@ func TestGenesis_Txs_Export(t *testing.T) { t.Cleanup(outputCleanup) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "export", "--genesis-path", tempGenesis.Name(), diff --git a/gno.land/cmd/gnoland/genesis_txs_list.go b/contribs/gnogenesis/internal/txs/txs_list.go similarity index 86% rename from gno.land/cmd/gnoland/genesis_txs_list.go rename to contribs/gnogenesis/internal/txs/txs_list.go index c68fbc30803..c7867da5027 100644 --- a/gno.land/cmd/gnoland/genesis_txs_list.go +++ b/contribs/gnogenesis/internal/txs/txs_list.go @@ -1,4 +1,4 @@ -package main +package txs import ( "bytes" @@ -6,6 +6,7 @@ import ( "errors" "fmt" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/tm2/pkg/amino" "github.com/gnolang/gno/tm2/pkg/bft/types" @@ -33,9 +34,9 @@ func newTxsListCmd(txsCfg *txsCfg, io commands.IO) *commands.Command { } func execTxsListCmd(io commands.IO, cfg *txsCfg) error { - genesis, err := types.GenesisDocFromFile(cfg.genesisPath) + genesis, err := types.GenesisDocFromFile(cfg.GenesisPath) if err != nil { - return fmt.Errorf("%w, %w", errUnableToLoadGenesis, err) + return fmt.Errorf("%w, %w", common.ErrUnableToLoadGenesis, err) } gs, ok := genesis.AppState.(gnoland.GnoGenesisState) diff --git a/gno.land/cmd/gnoland/genesis_txs_list_test.go b/contribs/gnogenesis/internal/txs/txs_list_test.go similarity index 83% rename from gno.land/cmd/gnoland/genesis_txs_list_test.go rename to contribs/gnogenesis/internal/txs/txs_list_test.go index d18c2f4d641..5129533dc8f 100644 --- a/gno.land/cmd/gnoland/genesis_txs_list_test.go +++ b/contribs/gnogenesis/internal/txs/txs_list_test.go @@ -1,10 +1,11 @@ -package main +package txs import ( "bytes" "context" "testing" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -20,10 +21,8 @@ func TestGenesis_List_All(t *testing.T) { t.Parallel() // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "list", "--genesis-path", "", @@ -31,7 +30,7 @@ func TestGenesis_List_All(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - assert.ErrorIs(t, cmdErr, errUnableToLoadGenesis) + assert.ErrorIs(t, cmdErr, common.ErrUnableToLoadGenesis) }) t.Run("list all txs", func(t *testing.T) { @@ -43,7 +42,7 @@ func TestGenesis_List_All(t *testing.T) { // Generate dummy txs txs := generateDummyTxs(t, 10) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() genesis.AppState = gnoland.GnoGenesisState{ Txs: txs, } @@ -53,10 +52,8 @@ func TestGenesis_List_All(t *testing.T) { buf := bytes.NewBuffer(nil) cio.SetOut(commands.WriteNopCloser(buf)) - cmd := newRootCmd(cio) + cmd := NewTxsCmd(cio) args := []string{ - "genesis", - "txs", "list", "--genesis-path", tempGenesis.Name(), diff --git a/gno.land/cmd/gnoland/genesis_txs_remove.go b/contribs/gnogenesis/internal/txs/txs_remove.go similarity index 94% rename from gno.land/cmd/gnoland/genesis_txs_remove.go rename to contribs/gnogenesis/internal/txs/txs_remove.go index 49c650f4670..f767e19bc90 100644 --- a/gno.land/cmd/gnoland/genesis_txs_remove.go +++ b/contribs/gnogenesis/internal/txs/txs_remove.go @@ -1,4 +1,4 @@ -package main +package txs import ( "context" @@ -37,7 +37,7 @@ func newTxsRemoveCmd(txsCfg *txsCfg, io commands.IO) *commands.Command { func execTxsRemove(cfg *txsCfg, io commands.IO, args []string) error { // Load the genesis - genesis, loadErr := types.GenesisDocFromFile(cfg.genesisPath) + genesis, loadErr := types.GenesisDocFromFile(cfg.GenesisPath) if loadErr != nil { return fmt.Errorf("unable to load genesis, %w", loadErr) } @@ -87,7 +87,7 @@ func execTxsRemove(cfg *txsCfg, io commands.IO, args []string) error { genesis.AppState = state // Save the updated genesis - if err := genesis.SaveAs(cfg.genesisPath); err != nil { + if err := genesis.SaveAs(cfg.GenesisPath); err != nil { return fmt.Errorf("unable to save genesis.json, %w", err) } diff --git a/gno.land/cmd/gnoland/genesis_txs_remove_test.go b/contribs/gnogenesis/internal/txs/txs_remove_test.go similarity index 86% rename from gno.land/cmd/gnoland/genesis_txs_remove_test.go rename to contribs/gnogenesis/internal/txs/txs_remove_test.go index ff5af479449..c031e0d342e 100644 --- a/gno.land/cmd/gnoland/genesis_txs_remove_test.go +++ b/contribs/gnogenesis/internal/txs/txs_remove_test.go @@ -1,9 +1,10 @@ -package main +package txs import ( "context" "testing" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/commands" @@ -19,10 +20,8 @@ func TestGenesis_Txs_Remove(t *testing.T) { t.Parallel() // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "remove", "--genesis-path", "dummy-path", @@ -30,7 +29,7 @@ func TestGenesis_Txs_Remove(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - assert.ErrorContains(t, cmdErr, errUnableToLoadGenesis.Error()) + assert.ErrorContains(t, cmdErr, common.ErrUnableToLoadGenesis.Error()) }) t.Run("invalid genesis app state", func(t *testing.T) { @@ -39,15 +38,13 @@ func TestGenesis_Txs_Remove(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() genesis.AppState = nil // no app state require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "remove", "--genesis-path", tempGenesis.Name(), @@ -66,17 +63,15 @@ func TestGenesis_Txs_Remove(t *testing.T) { // Generate dummy txs txs := generateDummyTxs(t, 10) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() genesis.AppState = gnoland.GnoGenesisState{ Txs: txs, } require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "remove", "--genesis-path", tempGenesis.Name(), @@ -96,7 +91,7 @@ func TestGenesis_Txs_Remove(t *testing.T) { // Generate dummy txs txs := generateDummyTxs(t, 10) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() genesis.AppState = gnoland.GnoGenesisState{ Txs: txs, } @@ -106,10 +101,8 @@ func TestGenesis_Txs_Remove(t *testing.T) { require.NoError(t, err) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewTxsCmd(commands.NewTestIO()) args := []string{ - "genesis", - "txs", "remove", "--genesis-path", tempGenesis.Name(), diff --git a/gno.land/cmd/gnoland/genesis_validator.go b/contribs/gnogenesis/internal/validator/validator.go similarity index 68% rename from gno.land/cmd/gnoland/genesis_validator.go rename to contribs/gnogenesis/internal/validator/validator.go index 91d3e4af7dd..8cd84f5c9bf 100644 --- a/gno.land/cmd/gnoland/genesis_validator.go +++ b/contribs/gnogenesis/internal/validator/validator.go @@ -1,27 +1,28 @@ -package main +package validator import ( "flag" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/tm2/pkg/commands" ) type validatorCfg struct { - commonCfg + common.Cfg address string } -// newValidatorCmd creates the genesis validator subcommand -func newValidatorCmd(io commands.IO) *commands.Command { +// NewValidatorCmd creates the genesis validator subcommand +func NewValidatorCmd(io commands.IO) *commands.Command { cfg := &validatorCfg{ - commonCfg: commonCfg{}, + Cfg: common.Cfg{}, } cmd := commands.NewCommand( commands.Metadata{ Name: "validator", - ShortUsage: "validator [flags]", + ShortUsage: " [flags]", ShortHelp: "validator set management in genesis.json", LongHelp: "Manipulates the genesis.json validator set", }, @@ -38,7 +39,7 @@ func newValidatorCmd(io commands.IO) *commands.Command { } func (c *validatorCfg) RegisterFlags(fs *flag.FlagSet) { - c.commonCfg.RegisterFlags(fs) + c.Cfg.RegisterFlags(fs) fs.StringVar( &c.address, diff --git a/gno.land/cmd/gnoland/genesis_validator_add.go b/contribs/gnogenesis/internal/validator/validator_add.go similarity index 95% rename from gno.land/cmd/gnoland/genesis_validator_add.go rename to contribs/gnogenesis/internal/validator/validator_add.go index 6c44ad93f89..45744f98e82 100644 --- a/gno.land/cmd/gnoland/genesis_validator_add.go +++ b/contribs/gnogenesis/internal/validator/validator_add.go @@ -1,4 +1,4 @@ -package main +package validator import ( "context" @@ -71,7 +71,7 @@ func (c *validatorAddCfg) RegisterFlags(fs *flag.FlagSet) { func execValidatorAdd(cfg *validatorAddCfg, io commands.IO) error { // Load the genesis - genesis, loadErr := types.GenesisDocFromFile(cfg.rootCfg.genesisPath) + genesis, loadErr := types.GenesisDocFromFile(cfg.rootCfg.GenesisPath) if loadErr != nil { return fmt.Errorf("unable to load genesis, %w", loadErr) } @@ -124,7 +124,7 @@ func execValidatorAdd(cfg *validatorAddCfg, io commands.IO) error { genesis.Validators = append(genesis.Validators, validator) // Save the updated genesis - if err := genesis.SaveAs(cfg.rootCfg.genesisPath); err != nil { + if err := genesis.SaveAs(cfg.rootCfg.GenesisPath); err != nil { return fmt.Errorf("unable to save genesis.json, %w", err) } diff --git a/gno.land/cmd/gnoland/genesis_validator_add_test.go b/contribs/gnogenesis/internal/validator/validator_add_test.go similarity index 66% rename from gno.land/cmd/gnoland/genesis_validator_add_test.go rename to contribs/gnogenesis/internal/validator/validator_add_test.go index 528255b3029..4e6155137a3 100644 --- a/gno.land/cmd/gnoland/genesis_validator_add_test.go +++ b/contribs/gnogenesis/internal/validator/validator_add_test.go @@ -1,61 +1,18 @@ -package main +package validator import ( "context" "testing" + "github.com/gnolang/contribs/gnogenesis/internal/common" "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/crypto/bip39" - "github.com/gnolang/gno/tm2/pkg/crypto/hd" - "github.com/gnolang/gno/tm2/pkg/crypto/keys/client" - "github.com/gnolang/gno/tm2/pkg/crypto/secp256k1" "github.com/gnolang/gno/tm2/pkg/testutils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -// getDummyKey generates a random public key, -// and returns the key info -func getDummyKey(t *testing.T) crypto.PubKey { - t.Helper() - - mnemonic, err := client.GenerateMnemonic(256) - require.NoError(t, err) - - seed := bip39.NewSeed(mnemonic, "") - - return generateKeyFromSeed(seed, 0).PubKey() -} - -// generateKeyFromSeed generates a private key from -// the provided seed and index -func generateKeyFromSeed(seed []byte, index uint32) crypto.PrivKey { - pathParams := hd.NewFundraiserParams(0, crypto.CoinType, index) - - masterPriv, ch := hd.ComputeMastersFromSeed(seed) - - //nolint:errcheck // This derivation can never error out, since the path params - // are always going to be valid - derivedPriv, _ := hd.DerivePrivateKeyForPath(masterPriv, ch, pathParams.String()) - - return secp256k1.PrivKeySecp256k1(derivedPriv) -} - -// getDummyKeys generates random keys for testing -func getDummyKeys(t *testing.T, count int) []crypto.PubKey { - t.Helper() - - dummyKeys := make([]crypto.PubKey, count) - - for i := 0; i < count; i++ { - dummyKeys[i] = getDummyKey(t) - } - - return dummyKeys -} - func TestGenesis_Validator_Add(t *testing.T) { t.Parallel() @@ -63,10 +20,8 @@ func TestGenesis_Validator_Add(t *testing.T) { t.Parallel() // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewValidatorCmd(commands.NewTestIO()) args := []string{ - "genesis", - "validator", "add", "--genesis-path", "dummy-path", @@ -74,7 +29,7 @@ func TestGenesis_Validator_Add(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - assert.ErrorContains(t, cmdErr, errUnableToLoadGenesis.Error()) + assert.ErrorContains(t, cmdErr, common.ErrUnableToLoadGenesis.Error()) }) t.Run("invalid validator address", func(t *testing.T) { @@ -83,14 +38,12 @@ func TestGenesis_Validator_Add(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewValidatorCmd(commands.NewTestIO()) args := []string{ - "genesis", - "validator", "add", "--genesis-path", tempGenesis.Name(), @@ -109,16 +62,14 @@ func TestGenesis_Validator_Add(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) - key := getDummyKey(t) + key := common.GetDummyKey(t) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewValidatorCmd(commands.NewTestIO()) args := []string{ - "genesis", - "validator", "add", "--genesis-path", tempGenesis.Name(), @@ -139,16 +90,14 @@ func TestGenesis_Validator_Add(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) - key := getDummyKey(t) + key := common.GetDummyKey(t) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewValidatorCmd(commands.NewTestIO()) args := []string{ - "genesis", - "validator", "add", "--genesis-path", tempGenesis.Name(), @@ -169,16 +118,14 @@ func TestGenesis_Validator_Add(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) - key := getDummyKey(t) + key := common.GetDummyKey(t) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewValidatorCmd(commands.NewTestIO()) args := []string{ - "genesis", - "validator", "add", "--genesis-path", tempGenesis.Name(), @@ -201,16 +148,14 @@ func TestGenesis_Validator_Add(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) - dummyKeys := getDummyKeys(t, 2) + dummyKeys := common.GetDummyKeys(t, 2) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewValidatorCmd(commands.NewTestIO()) args := []string{ - "genesis", - "validator", "add", "--genesis-path", tempGenesis.Name(), @@ -233,8 +178,8 @@ func TestGenesis_Validator_Add(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - dummyKeys := getDummyKeys(t, 2) - genesis := getDefaultGenesis() + dummyKeys := common.GetDummyKeys(t, 2) + genesis := common.GetDefaultGenesis() // Set an existing validator genesis.Validators = append(genesis.Validators, types.GenesisValidator{ @@ -247,10 +192,8 @@ func TestGenesis_Validator_Add(t *testing.T) { require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewValidatorCmd(commands.NewTestIO()) args := []string{ - "genesis", - "validator", "add", "--genesis-path", tempGenesis.Name(), @@ -273,16 +216,14 @@ func TestGenesis_Validator_Add(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - key := getDummyKey(t) - genesis := getDefaultGenesis() + key := common.GetDummyKey(t) + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewValidatorCmd(commands.NewTestIO()) args := []string{ - "genesis", - "validator", "add", "--genesis-path", tempGenesis.Name(), diff --git a/gno.land/cmd/gnoland/genesis_validator_remove.go b/contribs/gnogenesis/internal/validator/validator_remove.go similarity index 92% rename from gno.land/cmd/gnoland/genesis_validator_remove.go rename to contribs/gnogenesis/internal/validator/validator_remove.go index 48a15a9abaf..0206fe7d58d 100644 --- a/gno.land/cmd/gnoland/genesis_validator_remove.go +++ b/contribs/gnogenesis/internal/validator/validator_remove.go @@ -1,4 +1,4 @@ -package main +package validator import ( "context" @@ -29,7 +29,7 @@ func newValidatorRemoveCmd(rootCfg *validatorCfg, io commands.IO) *commands.Comm func execValidatorRemove(cfg *validatorCfg, io commands.IO) error { // Load the genesis - genesis, loadErr := types.GenesisDocFromFile(cfg.genesisPath) + genesis, loadErr := types.GenesisDocFromFile(cfg.GenesisPath) if loadErr != nil { return fmt.Errorf("unable to load genesis, %w", loadErr) } @@ -58,7 +58,7 @@ func execValidatorRemove(cfg *validatorCfg, io commands.IO) error { genesis.Validators = append(genesis.Validators[:index], genesis.Validators[index+1:]...) // Save the updated genesis - if err := genesis.SaveAs(cfg.genesisPath); err != nil { + if err := genesis.SaveAs(cfg.GenesisPath); err != nil { return fmt.Errorf("unable to save genesis.json, %w", err) } diff --git a/gno.land/cmd/gnoland/genesis_validator_remove_test.go b/contribs/gnogenesis/internal/validator/validator_remove_test.go similarity index 81% rename from gno.land/cmd/gnoland/genesis_validator_remove_test.go rename to contribs/gnogenesis/internal/validator/validator_remove_test.go index e73e867c5c3..78821f4abee 100644 --- a/gno.land/cmd/gnoland/genesis_validator_remove_test.go +++ b/contribs/gnogenesis/internal/validator/validator_remove_test.go @@ -1,9 +1,10 @@ -package main +package validator import ( "context" "testing" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/commands" "github.com/gnolang/gno/tm2/pkg/testutils" @@ -18,10 +19,8 @@ func TestGenesis_Validator_Remove(t *testing.T) { t.Parallel() // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewValidatorCmd(commands.NewTestIO()) args := []string{ - "genesis", - "validator", "remove", "--genesis-path", "dummy-path", @@ -29,7 +28,7 @@ func TestGenesis_Validator_Remove(t *testing.T) { // Run the command cmdErr := cmd.ParseAndRun(context.Background(), args) - assert.ErrorContains(t, cmdErr, errUnableToLoadGenesis.Error()) + assert.ErrorContains(t, cmdErr, common.ErrUnableToLoadGenesis.Error()) }) t.Run("invalid validator address", func(t *testing.T) { @@ -38,14 +37,12 @@ func TestGenesis_Validator_Remove(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewValidatorCmd(commands.NewTestIO()) args := []string{ - "genesis", - "validator", "remove", "--genesis-path", tempGenesis.Name(), @@ -64,8 +61,8 @@ func TestGenesis_Validator_Remove(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - dummyKeys := getDummyKeys(t, 2) - genesis := getDefaultGenesis() + dummyKeys := common.GetDummyKeys(t, 2) + genesis := common.GetDefaultGenesis() // Set an existing validator genesis.Validators = append(genesis.Validators, types.GenesisValidator{ @@ -78,10 +75,8 @@ func TestGenesis_Validator_Remove(t *testing.T) { require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewValidatorCmd(commands.NewTestIO()) args := []string{ - "genesis", - "validator", "remove", "--genesis-path", tempGenesis.Name(), @@ -100,9 +95,9 @@ func TestGenesis_Validator_Remove(t *testing.T) { tempGenesis, cleanup := testutils.NewTestFile(t) t.Cleanup(cleanup) - dummyKey := getDummyKey(t) + dummyKey := common.GetDummyKey(t) - genesis := getDefaultGenesis() + genesis := common.GetDefaultGenesis() // Set an existing validator genesis.Validators = append(genesis.Validators, types.GenesisValidator{ @@ -115,10 +110,8 @@ func TestGenesis_Validator_Remove(t *testing.T) { require.NoError(t, genesis.SaveAs(tempGenesis.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewValidatorCmd(commands.NewTestIO()) args := []string{ - "genesis", - "validator", "remove", "--genesis-path", tempGenesis.Name(), diff --git a/gno.land/cmd/gnoland/genesis_verify.go b/contribs/gnogenesis/internal/verify/verify.go similarity index 80% rename from gno.land/cmd/gnoland/genesis_verify.go rename to contribs/gnogenesis/internal/verify/verify.go index 112b075a58c..97ad14cb7f6 100644 --- a/gno.land/cmd/gnoland/genesis_verify.go +++ b/contribs/gnogenesis/internal/verify/verify.go @@ -1,4 +1,4 @@ -package main +package verify import ( "context" @@ -6,6 +6,7 @@ import ( "flag" "fmt" + "github.com/gnolang/contribs/gnogenesis/internal/common" "github.com/gnolang/gno/gno.land/pkg/gnoland" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/commands" @@ -14,17 +15,17 @@ import ( var errInvalidGenesisState = errors.New("invalid genesis state type") type verifyCfg struct { - commonCfg + common.Cfg } -// newVerifyCmd creates the genesis verify subcommand -func newVerifyCmd(io commands.IO) *commands.Command { +// NewVerifyCmd creates the genesis verify subcommand +func NewVerifyCmd(io commands.IO) *commands.Command { cfg := &verifyCfg{} return commands.NewCommand( commands.Metadata{ Name: "verify", - ShortUsage: "verify [flags]", + ShortUsage: "[flags]", ShortHelp: "verifies a genesis.json", LongHelp: "Verifies a node's genesis.json", }, @@ -36,12 +37,12 @@ func newVerifyCmd(io commands.IO) *commands.Command { } func (c *verifyCfg) RegisterFlags(fs *flag.FlagSet) { - c.commonCfg.RegisterFlags(fs) + c.Cfg.RegisterFlags(fs) } func execVerify(cfg *verifyCfg, io commands.IO) error { // Load the genesis - genesis, loadErr := types.GenesisDocFromFile(cfg.genesisPath) + genesis, loadErr := types.GenesisDocFromFile(cfg.GenesisPath) if loadErr != nil { return fmt.Errorf("unable to load genesis, %w", loadErr) } @@ -73,7 +74,7 @@ func execVerify(cfg *verifyCfg, io commands.IO) error { } } - io.Printfln("Genesis at %s is valid", cfg.genesisPath) + io.Printfln("Genesis at %s is valid", cfg.GenesisPath) return nil } diff --git a/gno.land/cmd/gnoland/genesis_verify_test.go b/contribs/gnogenesis/internal/verify/verify_test.go similarity index 90% rename from gno.land/cmd/gnoland/genesis_verify_test.go rename to contribs/gnogenesis/internal/verify/verify_test.go index 9c93519e495..76009c34c94 100644 --- a/gno.land/cmd/gnoland/genesis_verify_test.go +++ b/contribs/gnogenesis/internal/verify/verify_test.go @@ -1,4 +1,4 @@ -package main +package verify import ( "context" @@ -53,10 +53,8 @@ func TestGenesis_Verify(t *testing.T) { require.NoError(t, g.SaveAs(tempFile.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewVerifyCmd(commands.NewTestIO()) args := []string{ - "genesis", - "verify", "--genesis-path", tempFile.Name(), } @@ -84,10 +82,8 @@ func TestGenesis_Verify(t *testing.T) { require.NoError(t, g.SaveAs(tempFile.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewVerifyCmd(commands.NewTestIO()) args := []string{ - "genesis", - "verify", "--genesis-path", tempFile.Name(), } @@ -112,10 +108,8 @@ func TestGenesis_Verify(t *testing.T) { require.NoError(t, g.SaveAs(tempFile.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewVerifyCmd(commands.NewTestIO()) args := []string{ - "genesis", - "verify", "--genesis-path", tempFile.Name(), } @@ -135,10 +129,8 @@ func TestGenesis_Verify(t *testing.T) { require.NoError(t, g.SaveAs(tempFile.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewVerifyCmd(commands.NewTestIO()) args := []string{ - "genesis", - "verify", "--genesis-path", tempFile.Name(), } @@ -159,10 +151,8 @@ func TestGenesis_Verify(t *testing.T) { require.NoError(t, g.SaveAs(tempFile.Name())) // Create the command - cmd := newRootCmd(commands.NewTestIO()) + cmd := NewVerifyCmd(commands.NewTestIO()) args := []string{ - "genesis", - "verify", "--genesis-path", tempFile.Name(), } diff --git a/contribs/gnogenesis/main.go b/contribs/gnogenesis/main.go new file mode 100644 index 00000000000..a5beb2518dd --- /dev/null +++ b/contribs/gnogenesis/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "context" + "os" + + "github.com/gnolang/gno/tm2/pkg/commands" +) + +func main() { + cmd := newGenesisCmd(commands.NewDefaultIO()) + + cmd.Execute(context.Background(), os.Args[1:]) +} diff --git a/docs/gno-infrastructure/validators/faq.md b/docs/gno-infrastructure/validators/faq.md index c345b49724a..1a065a5ca56 100644 --- a/docs/gno-infrastructure/validators/faq.md +++ b/docs/gno-infrastructure/validators/faq.md @@ -104,41 +104,6 @@ either a full node or a pruned node, it is important to retain enough blocks to ## Technical References -### How do I generate `genesis.json`? - -`genesis.json` is the file that is used to create the initial state of the chain. To generate `genesis.json`, use -the `gnoland genesis generate` command. Refer -to [this section](../../gno-tooling/cli/gnoland.md#gnoland-genesis-generate-flags) for various flags that allow you to -manipulate the file. - -:::warning - -Editing generated genesis.json manually is extremely dangerous. It may corrupt chain initial state which leads chain to -not start - -::: - -### How do I add or remove validators from `genesis.json`? - -Validators inside `genesis.json` will be included in the validator set at genesis. To manipulate the genesis validator -set, use the `gnoland genesis validator` command with the `add` or `remove` subcommands. Refer -to [this section](../../gno-tooling/cli/gnoland.md#gnoland-genesis-validator-flags) for flags that allow you to -configure the name or the voting power of the validator. - -### How do I add the balance information to the `genesis.json`? - -You may premine coins to various addresses. To modify the balances of addresses at genesis, use -the `gnoland genesis balances` command with the `add` or `remove` subcommands. Refer -to [this section](../../gno-tooling/cli/gnoland.md#gnoland-genesis-balances-add-flags) for various flags that allow you -to update the entire balance sheet with a file or modify the balance of a single address. - -:::info - -Not only `ugnot`, but other coins are accepted. However, be aware that coins other than `ugnot` may not work(send, and -etc.) properly. - -::: - ### How do I initialize `gno secrets`? The `gno secrets init` command allows you to initialize the private information required to run the validator, including diff --git a/docs/gno-infrastructure/validators/setting-up-a-new-chain.md b/docs/gno-infrastructure/validators/setting-up-a-new-chain.md index 0411fa3b02a..aab76eefbaf 100644 --- a/docs/gno-infrastructure/validators/setting-up-a-new-chain.md +++ b/docs/gno-infrastructure/validators/setting-up-a-new-chain.md @@ -19,7 +19,7 @@ Additionally, you will see the different options you can use to make your Gno in ## Installation -To install the `gnoland` binary, clone the Gno monorepo: +To install the `gnoland` and `gnogenesis` binaries, clone the Gno monorepo: ```bash git clone https://github.com/gnolang/gno.git @@ -30,7 +30,7 @@ Makefile to install the `gnoland` binary: ```bash cd gno.land -make install.gnoland +make install.gnoland install.gnogenesis ``` To verify that you've installed the binary properly and that you are able to use @@ -93,7 +93,8 @@ Let's break down the most important default settings: :::info Resetting the chain As mentioned, the working directory for the node is located in `data-dir`. To reset the chain, you need -to delete this directory and `genesis.json`, then start the node up again. If you are using the default node configuration, you can run +to delete this directory and `genesis.json`, then start the node up again. If you are using the default node +configuration, you can run `make fclean` from the `gno.land` sub-folder to delete the `gnoland-data` working directory. ::: @@ -201,7 +202,7 @@ executed. Generating an empty `genesis.json` is relatively straightforward: ```shell -gnoland genesis generate +gnogenesis generate ``` The resulting `genesis.json` is empty: @@ -232,7 +233,7 @@ This will generate a `genesis.json` in the calling directory, by default. To che generating the `genesis.json`, you can run the command using the `--help` flag: ```shell -gnoland genesis generate --help +gnogenesis generate --help USAGE generate [flags] @@ -257,7 +258,7 @@ present challenges with users who expect them to be present. The `examples` directory is located in the `$GNOROOT` location, or the local gno repository clone. ```bash -gnoland genesis txs add packages ./examples +gnogenesis txs add packages ./examples ``` ### 4. Add the initial validator set @@ -288,7 +289,7 @@ Updating the `genesis.json` is relatively simple, running the following command validator set: ```shell -gnoland genesis validator add \ +gnogenesis validator add \ --address g14j4dlsh3jzgmhezzp9v8xp7wxs4mvyskuw5ljl \ --pub-key gpub1pggj7ard9eg82cjtv4u52epjx56nzwgjyg9zqaqle3fdduqul4slg6zllypq9r8gj4wlfucy6qfnzmjcgqv675kxjz8jvk \ --name Cuttlas diff --git a/docs/gno-tooling/cli/gnoland.md b/docs/gno-tooling/cli/gnoland.md index 18175871d90..037a1f19d03 100644 --- a/docs/gno-tooling/cli/gnoland.md +++ b/docs/gno-tooling/cli/gnoland.md @@ -29,164 +29,6 @@ Starts the Gnoland blockchain node, with accompanying setup. | `log-level` | String | The log level for the gnoland node. (default: `debug`) | | `skip-failing-genesis-txs` | Boolean | Doesn’t panic when replaying invalid genesis txs. When starting a production-level chain, it is recommended to set this value to `true` to monitor and analyze failing transactions. (default: `false`) | -### gnoland genesis \ [flags] [\...] - -Gno `genesis.json` manipulation suite for managing genesis parameters. - -#### SUBCOMMANDS - -| Name | Description | -|-------------|---------------------------------------------| -| `generate` | Generates a fresh `genesis.json`. | -| `validator` | Validator set management in `genesis.json`. | -| `verify` | Verifies a `genesis.json`. | -| `balances` | Manages `genesis.json` account balances. | -| `txs` | Manages the initial genesis transactions. | - -### gnoland genesis generate [flags] - -Generates a node's `genesis.json` based on specified parameters. - -#### FLAGS - -| Name | Type | Description | -|------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `block-max-data-bytes` | Int | The max size of the block data.(default: `2000000`) | -| `block-max-gas` | Int | The max gas limit for the block. (default: `100000000`) | -| `block-max-tx-bytes` | Int | The max size of the block transaction. (default: `1000000`) | -| `block-time-itoa` | Int | The block time itoa (in ms). (default: `100`) | -| `chain-id` | String | The ID of the chain. (default: `dev`) | -| `genesis-time` | Int | The genesis creation time. (default: `utc now timestamp`) | -| `output-path` : | String | The output path for the `genesis.json`. If the genesis-time of the Genesis File is set to a future time, the chain will automatically start at that time if the node is online. (default: `./genesis.json`) | - -### gnoland genesis validator \ [flags] - -Manipulates the `genesis.json` validator set. - -#### SUBCOMANDS - -| Name | Description | -|----------|----------------------------------------------| -| `add` | Adds a new validator to the `genesis.json`. | -| `remove` | Removes a validator from the `genesis.json`. | - -#### FLAGS - -| Name | Type | Description | -|----------------|--------|------------------------------------------------------------| -| `address` | String | The gno bech32 address of the validator. | -| `genesis-path` | String | The path to the `genesis.json`. (default `./genesis.json`) | - -### gnoland genesis validator add [flags] - -Adds a new validator to the `genesis.json`. - -#### FLAGS - -| Name | Type | Description | -|----------------|--------|-----------------------------------------------------------------| -| `address` | String | The gno bech32 address of the validator. | -| `genesis-path` | String | The path to the `genesis.json`. (default: `./genesis.json`) | -| `name` | String | The name of the validator (must be unique). | -| `power` | Uint | The voting power of the validator (must be > 0). (default: `1`) | -| `pub-key` | String | The bech32 string representation of the validator's public key. | - -```bash -gnoland genesis validator add \ --address g1rzuwh5frve732k4futyw45y78rzuty4626zy6h \ --name test1 \ --pub-key gpub1pggj7ard9eg82cjtv4u52epjx56nzwgjyg9zplmcmggxyxyrch0zcyg684yxmerullv3l6hmau58sk4eyxskmny9h7lsnz - -Validator with address g1rzuwh5frve732k4futyw45y78rzuty4626zy6h added to genesis file -``` - -### gnoland genesis validator remove [flags] - -Removes a validator from the `genesis.json`. - -#### FLAGS - -| Name | Type | Description | -|----------------|--------|-------------------------------------------------------------| -| `address` | String | The gno bech32 address of the validator. | -| `genesis-path` | String | The path to the `genesis.json`. (default: `./genesis.json)` | - -```bash -gnoland genesis validator remove \ --address g1rzuwh5frve732k4futyw45y78rzuty4626zy6h - -Validator with address g1rzuwh5frve732k4futyw45y78rzuty4626zy6h removed from genesis file -``` - -### gnoland genesis verify \ [flags] [\…] - -Verifies a `genesis.json`. - -#### FLAGS - -| Name | Type | Description | -|----------------|--------|-----------------------------------------------------------| -| `genesis-path` | String | The path to the `genesis.json`. (default: `genesis.json`) | - -### gnoland genesis balances \ [flags] [\…] - -Manages `genesis.json` account balances. - -#### SUBCOMMANDS - -| Name | Description | -|----------|--------------------------------------------------------| -| `add` | Adds the balance information. | -| `remove` | Removes the balance information of a specific account. | - -### gnoland genesis balances add [flags] - -#### FLAGS - -| Name | Type | Description | -|-----------------|--------|--------------------------------------------------------------------------------------------| -| `balance-sheet` | String | The path to the balance file containing addresses in the format `
=ugnot`. | -| `genesis-path` | String | The path to the `genesis.json` (default: `./genesis.json`) | -| `parse-export` | String | The path to the transaction export containing a list of transactions (JSONL). | -| `single` | String | The direct balance addition in the format `
=ugnot`. | - -```bash -gnoland genesis balances add \ --single g1rzuwh5frve732k4futyw45y78rzuty4626zy6h=100ugnot - -1 pre-mines saved - -g1rzuwh5frve732k4futyw45y78rzuty4626zy6h:{[24 184 235 209 35 102 125 21 90 169 226 200 234 208 158 56 197 197 146 186] [{%!d(string=ugnot) 100}]}ugnot -``` - -### gnoland balances remove [flags] - -#### FLAGS - -| Name | Type | Description | -|----------------|--------|---------------------------------------------------------------------------------------------| -| `address` | String | The address of the account whose balance information should be removed from `genesis.json`. | -| `genesis-path` | String | The path to the `genesis.json`. (default: `./genesis.json`) | - -```bash -gnoland genesis balances remove \ --address=g1rzuwh5frve732k4futyw45y78rzuty4626zy6h - -Pre-mine information for address g1rzuwh5frve732k4futyw45y78rzuty4626zy6h removed -``` - -### gnoland txs \ [flags] [\…] - -Manages genesis transactions through input files. - -#### SUBCOMMANDS - -| Name | Description | -|----------|---------------------------------------------------| -| `add` | Imports transactions into the `genesis.json`. | -| `remove` | Removes the transactions from the `genesis.json`. | -| `export` | Exports the transactions from the `genesis.json`. | - ### gnoland secrets \ [flags] [\…] The gno secrets manipulation suite for managing the validator key, p2p key and diff --git a/gno.land/cmd/gnoland/genesis.go b/gno.land/cmd/gnoland/genesis.go deleted file mode 100644 index 37c0f8f2926..00000000000 --- a/gno.land/cmd/gnoland/genesis.go +++ /dev/null @@ -1,46 +0,0 @@ -package main - -import ( - "flag" - - "github.com/gnolang/gno/tm2/pkg/commands" -) - -func newGenesisCmd(io commands.IO) *commands.Command { - cmd := commands.NewCommand( - commands.Metadata{ - Name: "genesis", - ShortUsage: "genesis [flags] [...]", - ShortHelp: "gno genesis manipulation suite", - LongHelp: "Gno genesis.json manipulation suite, for managing genesis parameters", - }, - commands.NewEmptyConfig(), - commands.HelpExec, - ) - - cmd.AddSubCommands( - newGenerateCmd(io), - newValidatorCmd(io), - newVerifyCmd(io), - newBalancesCmd(io), - newTxsCmd(io), - ) - - return cmd -} - -// commonCfg is the common -// configuration for genesis commands -// that require a genesis.json -type commonCfg struct { - genesisPath string -} - -func (c *commonCfg) RegisterFlags(fs *flag.FlagSet) { - fs.StringVar( - &c.genesisPath, - "genesis-path", - "./genesis.json", - "the path to the genesis.json", - ) -} diff --git a/gno.land/cmd/gnoland/root.go b/gno.land/cmd/gnoland/root.go index b40a1160b0b..c6143ab9cd3 100644 --- a/gno.land/cmd/gnoland/root.go +++ b/gno.land/cmd/gnoland/root.go @@ -25,7 +25,6 @@ func newRootCmd(io commands.IO) *commands.Command { cmd.AddSubCommands( newStartCmd(io), - newGenesisCmd(io), newSecretsCmd(io), newConfigCmd(io), ) diff --git a/gno.land/cmd/gnoland/start.go b/gno.land/cmd/gnoland/start.go index 8d1ee81295f..77d7e20b8ef 100644 --- a/gno.land/cmd/gnoland/start.go +++ b/gno.land/cmd/gnoland/start.go @@ -14,6 +14,7 @@ import ( "time" "github.com/gnolang/gno/gno.land/pkg/gnoland" + "github.com/gnolang/gno/gno.land/pkg/gnoland/ugnot" "github.com/gnolang/gno/gno.land/pkg/log" "github.com/gnolang/gno/gnovm/pkg/gnoenv" abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types" @@ -25,6 +26,7 @@ import ( "github.com/gnolang/gno/tm2/pkg/crypto" "github.com/gnolang/gno/tm2/pkg/events" osm "github.com/gnolang/gno/tm2/pkg/os" + "github.com/gnolang/gno/tm2/pkg/std" "github.com/gnolang/gno/tm2/pkg/telemetry" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -42,6 +44,12 @@ var startGraphic = strings.ReplaceAll(` /___/ `, "'", "`") +var ( + // Keep in sync with contribs/gnogenesis/internal/txs/txs_add_packages.go + genesisDeployAddress = crypto.MustAddressFromString("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5") // test1 + genesisDeployFee = std.NewFee(50000, std.MustParseCoin(ugnot.ValueString(1000000))) +) + type startCfg struct { gnoRootDir string // TODO: remove as part of https://github.com/gnolang/gno/issues/1952 skipFailingGenesisTxs bool // TODO: remove as part of https://github.com/gnolang/gno/issues/1952 diff --git a/gno.land/cmd/gnoland/types.go b/gno.land/cmd/gnoland/types.go deleted file mode 100644 index a48bfaf7b31..00000000000 --- a/gno.land/cmd/gnoland/types.go +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import ( - "github.com/gnolang/gno/tm2/pkg/std" -) - -// txStore is a wrapper for TM2 transactions -type txStore []std.Tx - -// leftMerge merges the two tx stores, with -// preference to the left -func (i *txStore) leftMerge(b txStore) error { - // Build out the tx hash map - txHashMap := make(map[string]struct{}, len(*i)) - - for _, tx := range *i { - txHash, err := getTxHash(tx) - if err != nil { - return err - } - - txHashMap[txHash] = struct{}{} - } - - for _, tx := range b { - txHash, err := getTxHash(tx) - if err != nil { - return err - } - - if _, exists := txHashMap[txHash]; !exists { - *i = append(*i, tx) - } - } - - return nil -} diff --git a/tm2/README.md b/tm2/README.md index 0f6e0052933..2addfe8f550 100644 --- a/tm2/README.md +++ b/tm2/README.md @@ -35,7 +35,7 @@ - MISSION: be the basis for improving the encoding standard from proto3, because proto3 length-prefixing is slow, and we need "proto4" or "amino2". - LOOK at the auto-generated proto files! - https://github.com/gnolang/gno/blob/master/pkgs/bft/consensus/types/cstypes.proto + https://github.com/gnolang/gno/blob/master/tm2/pkg/bft/consensus/types/cstypes.proto for example. - There was work to remove this from the CosmosSDK because Amino wasn't ready, but now that it is, it makes sense to incorporate it into