From 069cd173f44ec988c91e5f27b62989c86640282f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 21 Oct 2022 16:55:43 +0200 Subject: [PATCH 001/166] switch to tendermint fork release v0.1.2-abciplus --- scripts/get_tendermint.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/get_tendermint.sh b/scripts/get_tendermint.sh index 8e74d3f851..9a9c692e69 100755 --- a/scripts/get_tendermint.sh +++ b/scripts/get_tendermint.sh @@ -6,8 +6,8 @@ set -Eo pipefail # https://github.com/tendermint/tendermint/releases/download/v0.34.13/tendermint_0.34.13_linux_amd64.tar.gz # https://github.com/heliaxdev/tendermint/releases/download/v0.1.1-abcipp/tendermint_0.1.0-abcipp_darwin_amd64.tar.gz TM_MAJORMINOR="0.1" -TM_PATCH="1" -TM_SUFFIX="-abcipp" +TM_PATCH="2" +TM_SUFFIX="-abciplus" TM_REPO="https://github.com/heliaxdev/tendermint" TM_VERSION="${TM_MAJORMINOR}.${TM_PATCH}${TM_SUFFIX}" From d014df533c7dc14db67a6a4a484552ef3b159088 Mon Sep 17 00:00:00 2001 From: Tomas Zemanovic Date: Mon, 24 Oct 2022 12:38:56 +0200 Subject: [PATCH 002/166] switch to tendermint fork release v0.1.3-abciplus --- scripts/get_tendermint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/get_tendermint.sh b/scripts/get_tendermint.sh index 9a9c692e69..c615aeae90 100755 --- a/scripts/get_tendermint.sh +++ b/scripts/get_tendermint.sh @@ -6,7 +6,7 @@ set -Eo pipefail # https://github.com/tendermint/tendermint/releases/download/v0.34.13/tendermint_0.34.13_linux_amd64.tar.gz # https://github.com/heliaxdev/tendermint/releases/download/v0.1.1-abcipp/tendermint_0.1.0-abcipp_darwin_amd64.tar.gz TM_MAJORMINOR="0.1" -TM_PATCH="2" +TM_PATCH="3" TM_SUFFIX="-abciplus" TM_REPO="https://github.com/heliaxdev/tendermint" From 65283a83db479db7c23f6b0a255a6226bdbd39c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Wed, 2 Nov 2022 12:11:47 +0100 Subject: [PATCH 003/166] docker/namada: upgrade tendermint to v0.1.3-abciplus --- docker/namada/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/namada/Dockerfile b/docker/namada/Dockerfile index 2335ea9f46..65ab9019d1 100644 --- a/docker/namada/Dockerfile +++ b/docker/namada/Dockerfile @@ -25,7 +25,7 @@ RUN make build-release FROM golang:1.18.0 as tendermint-builder WORKDIR /app -RUN git clone -b v0.1.1-abcipp --single-branch https://github.com/heliaxdev/tendermint.git && cd tendermint && make build +RUN git clone -b v0.1.3-abciplus --single-branch https://github.com/heliaxdev/tendermint.git && cd tendermint && make build FROM debian:bullseye-slim AS runtime ENV ANOMA_BASE_DIR=/.anoma From 3ac2c131ab53f88c3439c31309d052e845a96bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Wed, 16 Nov 2022 13:53:37 +0100 Subject: [PATCH 004/166] CI: use tendermint fork release v0.1.3-abciplus version --- .github/workflows/build-and-test-bridge.yml | 2 +- .github/workflows/build-and-test.yml | 2 +- .github/workflows/build-tendermint.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-and-test-bridge.yml b/.github/workflows/build-and-test-bridge.yml index cee43b941b..a221a69180 100644 --- a/.github/workflows/build-and-test-bridge.yml +++ b/.github/workflows/build-and-test-bridge.yml @@ -115,7 +115,7 @@ jobs: cache_key: anoma cache_version: v1 wait_for: anoma-release-eth (ubuntu-latest, ABCI Release build, anoma-e2e-release, v1) - tendermint_artifact: tendermint-unreleased-ad825dcadbd4b98c3f91ce5a711e4fb36a69c377 + tendermint_artifact: tendermint-unreleased-v0.1.3-abciplus env: CARGO_INCREMENTAL: 0 diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 1c4cbd3412..c6b6f28f98 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -117,7 +117,7 @@ jobs: cache_key: anoma cache_version: v1 wait_for: anoma-release (ubuntu-latest, ABCI Release build, anoma-e2e-release, v1) - tendermint_artifact: tendermint-unreleased-ad825dcadbd4b98c3f91ce5a711e4fb36a69c377 + tendermint_artifact: tendermint-unreleased-v0.1.3-abciplus env: CARGO_INCREMENTAL: 0 diff --git a/.github/workflows/build-tendermint.yml b/.github/workflows/build-tendermint.yml index 7914a39a49..40db1ce05d 100644 --- a/.github/workflows/build-tendermint.yml +++ b/.github/workflows/build-tendermint.yml @@ -23,7 +23,7 @@ jobs: make: - name: tendermint-unreleased repository: heliaxdev/tendermint - tendermint_version: ad825dcadbd4b98c3f91ce5a711e4fb36a69c377 + tendermint_version: v0.1.3-abciplus steps: - name: Build ${{ matrix.make.name }} From c8c8ae67946b1441744319d8d13a0a6be9cfa009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Mon, 21 Nov 2022 17:04:57 +0100 Subject: [PATCH 005/166] update to tendermint temp fork v0.1.4-abciplus --- .github/workflows/build-and-test-bridge.yml | 2 +- .github/workflows/build-and-test.yml | 2 +- .github/workflows/build-tendermint.yml | 2 +- docker/namada/Dockerfile | 2 +- scripts/get_tendermint.sh | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-and-test-bridge.yml b/.github/workflows/build-and-test-bridge.yml index a221a69180..c440facd1a 100644 --- a/.github/workflows/build-and-test-bridge.yml +++ b/.github/workflows/build-and-test-bridge.yml @@ -115,7 +115,7 @@ jobs: cache_key: anoma cache_version: v1 wait_for: anoma-release-eth (ubuntu-latest, ABCI Release build, anoma-e2e-release, v1) - tendermint_artifact: tendermint-unreleased-v0.1.3-abciplus + tendermint_artifact: tendermint-unreleased-v0.1.4-abciplus env: CARGO_INCREMENTAL: 0 diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index c6b6f28f98..1aacf5b3ea 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -117,7 +117,7 @@ jobs: cache_key: anoma cache_version: v1 wait_for: anoma-release (ubuntu-latest, ABCI Release build, anoma-e2e-release, v1) - tendermint_artifact: tendermint-unreleased-v0.1.3-abciplus + tendermint_artifact: tendermint-unreleased-v0.1.4-abciplus env: CARGO_INCREMENTAL: 0 diff --git a/.github/workflows/build-tendermint.yml b/.github/workflows/build-tendermint.yml index 40db1ce05d..b709699b68 100644 --- a/.github/workflows/build-tendermint.yml +++ b/.github/workflows/build-tendermint.yml @@ -23,7 +23,7 @@ jobs: make: - name: tendermint-unreleased repository: heliaxdev/tendermint - tendermint_version: v0.1.3-abciplus + tendermint_version: v0.1.4-abciplus steps: - name: Build ${{ matrix.make.name }} diff --git a/docker/namada/Dockerfile b/docker/namada/Dockerfile index 65ab9019d1..fe5a648e84 100644 --- a/docker/namada/Dockerfile +++ b/docker/namada/Dockerfile @@ -25,7 +25,7 @@ RUN make build-release FROM golang:1.18.0 as tendermint-builder WORKDIR /app -RUN git clone -b v0.1.3-abciplus --single-branch https://github.com/heliaxdev/tendermint.git && cd tendermint && make build +RUN git clone -b v0.1.4-abciplus --single-branch https://github.com/heliaxdev/tendermint.git && cd tendermint && make build FROM debian:bullseye-slim AS runtime ENV ANOMA_BASE_DIR=/.anoma diff --git a/scripts/get_tendermint.sh b/scripts/get_tendermint.sh index c615aeae90..024299ec93 100755 --- a/scripts/get_tendermint.sh +++ b/scripts/get_tendermint.sh @@ -6,7 +6,7 @@ set -Eo pipefail # https://github.com/tendermint/tendermint/releases/download/v0.34.13/tendermint_0.34.13_linux_amd64.tar.gz # https://github.com/heliaxdev/tendermint/releases/download/v0.1.1-abcipp/tendermint_0.1.0-abcipp_darwin_amd64.tar.gz TM_MAJORMINOR="0.1" -TM_PATCH="3" +TM_PATCH="4" TM_SUFFIX="-abciplus" TM_REPO="https://github.com/heliaxdev/tendermint" From 8ed6e272bd9dbe4cd089b5f94d46018a9404d7b2 Mon Sep 17 00:00:00 2001 From: Bengt Date: Tue, 13 Dec 2022 12:54:34 +0000 Subject: [PATCH 006/166] fixed testnets documentation --- documentation/docs/src/SUMMARY.md | 3 +-- .../namada-close-quarters-testnet-1.md | 24 ------------------- documentation/docs/src/testnets/testnets.md | 14 +++++++++++ 3 files changed, 15 insertions(+), 26 deletions(-) delete mode 100644 documentation/docs/src/testnets/namada-close-quarters-testnet-1.md create mode 100644 documentation/docs/src/testnets/testnets.md diff --git a/documentation/docs/src/SUMMARY.md b/documentation/docs/src/SUMMARY.md index ad92fc3ab8..ecf6deb66c 100644 --- a/documentation/docs/src/SUMMARY.md +++ b/documentation/docs/src/SUMMARY.md @@ -12,5 +12,4 @@ - [Governance](./user-guide/ledger/governance.md) - [Genesis validator setup](./user-guide/genesis-validator-setup.md) - [Applying to be a genesis validator](./user-guide/genesis-validator-apply.md) -- [Testnets](./testnets/README.md) - - [Namada Close Quarters Testnet 1](./testnets/namada-close-quarters-testnet-1.md) +- [Testnets](./testnets/testnets.md) diff --git a/documentation/docs/src/testnets/namada-close-quarters-testnet-1.md b/documentation/docs/src/testnets/namada-close-quarters-testnet-1.md deleted file mode 100644 index c4d6b3608c..0000000000 --- a/documentation/docs/src/testnets/namada-close-quarters-testnet-1.md +++ /dev/null @@ -1,24 +0,0 @@ -# Namada Close Quarters Testnet 1 - -This testnet introduces the following new features: - -- [on-chain governance](../user-guide/ledger/governance.md) - create and vote for proposals both onchain and offchain -- [MASP (multi-asset shielded pool) transfers](../user-guide/ledger/masp.md) - make private transfers of any Namada token - -Future testnets will include more features as described in [the Namada spec](https://specs.namada.net/master/architecture/namada.html), like IBC (inter-blockchain communication protocol), bridging to the Ethereum blockchain and more. - -## Chain information - -Latest values regarding the testnet that would be useful to have in your shell: - -```shell -export NAMADA_CHAIN_ID='namada-cq-2.a6ebeb093671093b21' -export NAMADA_COMMIT='f1afdffd5e43ad4bb448db7bf5bc1e23464350f7' -``` - -You will need to compile the binaries from source yourself, make sure you have checked out the specific commit `$NAMADA_COMMIT` to build from, then follow [the building from source guide](../user-guide/install.md#from-source). - -## Status - -- 2022-05-05: The chain has been setup to start today at 12:00 CET. -- 2022-05-02: We are currently preparing to launch the chain. Applications are open for people to be [genesis validators](../user-guide/genesis-validator-apply.md). diff --git a/documentation/docs/src/testnets/testnets.md b/documentation/docs/src/testnets/testnets.md new file mode 100644 index 0000000000..248d8849ed --- /dev/null +++ b/documentation/docs/src/testnets/testnets.md @@ -0,0 +1,14 @@ + +# Namada Testnets + +Testnets on Namada serve the purpose of allowing users on the internet to test the latest features of the protocol. Beware of bugs :warning: :ant: ! Pest control can be reached through any of our socials, and we greatly appreciate any bug reports :eyes: :airplane_arriving: + +Testnets are released on a fortnightly cycle (every other Tuesday). Sometimes changes are large, sometimes they are small. The [github changelog](https://github.com/anoma/namada/tree/main/.changelog) will specify exactly what changes have been made in between versions. + +The instructions to join the latest running testnet can be found [HERE](https://hackmd.io/WDhESkCeSWepuki1F1scxg) + +The block explorer is currently in development. The latest version can be found at [namada.world](https://namada.world/) + +We much appreciate any feedback, which we would gladly appreciate through either [twitter](https://twitter.com/namadanetwork), [reddit](https://www.reddit.com/r/namada), or [github](https://github.com/anoma/namada/issues). + +We look forward to seeing you there! From 758dfb5533cf4e21b5d4aa7bcd7d555899aec439 Mon Sep 17 00:00:00 2001 From: Bengt Date: Tue, 13 Dec 2022 17:52:58 +0000 Subject: [PATCH 007/166] acked comments --- documentation/docs/src/testnets/testnets.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/docs/src/testnets/testnets.md b/documentation/docs/src/testnets/testnets.md index 248d8849ed..8112499576 100644 --- a/documentation/docs/src/testnets/testnets.md +++ b/documentation/docs/src/testnets/testnets.md @@ -3,12 +3,12 @@ Testnets on Namada serve the purpose of allowing users on the internet to test the latest features of the protocol. Beware of bugs :warning: :ant: ! Pest control can be reached through any of our socials, and we greatly appreciate any bug reports :eyes: :airplane_arriving: -Testnets are released on a fortnightly cycle (every other Tuesday). Sometimes changes are large, sometimes they are small. The [github changelog](https://github.com/anoma/namada/tree/main/.changelog) will specify exactly what changes have been made in between versions. +Testnets are released on a fortnightly cycle (every other Tuesday). Sometimes changes are large, sometimes they are small. The [Github changelog](https://github.com/anoma/namada/tree/main/.changelog) will specify exactly what changes have been made in between versions. The instructions to join the latest running testnet can be found [HERE](https://hackmd.io/WDhESkCeSWepuki1F1scxg) The block explorer is currently in development. The latest version can be found at [namada.world](https://namada.world/) -We much appreciate any feedback, which we would gladly appreciate through either [twitter](https://twitter.com/namadanetwork), [reddit](https://www.reddit.com/r/namada), or [github](https://github.com/anoma/namada/issues). +We much appreciate any feedback, which we would gladly appreciate through either [Twitter](https://twitter.com/namadanetwork), [Reddit](https://www.reddit.com/r/namada), or [Github](https://github.com/anoma/namada/issues). We look forward to seeing you there! From 1168d5114b285039b689fea6490ebdb6fdbc4b88 Mon Sep 17 00:00:00 2001 From: Bengt Date: Thu, 15 Dec 2022 13:12:54 +0000 Subject: [PATCH 008/166] fixed compile error --- documentation/docs/src/SUMMARY.md | 2 +- documentation/docs/src/testnets/README.md | 16 ++++++++-------- documentation/docs/src/testnets/testnets.md | 14 -------------- 3 files changed, 9 insertions(+), 23 deletions(-) delete mode 100644 documentation/docs/src/testnets/testnets.md diff --git a/documentation/docs/src/SUMMARY.md b/documentation/docs/src/SUMMARY.md index ecf6deb66c..40f22fe321 100644 --- a/documentation/docs/src/SUMMARY.md +++ b/documentation/docs/src/SUMMARY.md @@ -12,4 +12,4 @@ - [Governance](./user-guide/ledger/governance.md) - [Genesis validator setup](./user-guide/genesis-validator-setup.md) - [Applying to be a genesis validator](./user-guide/genesis-validator-apply.md) -- [Testnets](./testnets/testnets.md) +- [Testnets](./testnets/README.md) diff --git a/documentation/docs/src/testnets/README.md b/documentation/docs/src/testnets/README.md index 6299cc839c..22336012cd 100644 --- a/documentation/docs/src/testnets/README.md +++ b/documentation/docs/src/testnets/README.md @@ -1,13 +1,13 @@ -# Testnets +# Namada Testnets -This section describes how to connect to the various testnets and to test selected features. +Testnets on Namada serve the purpose of allowing users on the internet to test the latest features of the protocol. Beware of bugs :warning: :ant: ! Pest control can be reached through any of our socials, and we greatly appreciate any bug reports :eyes: :airplane_arriving: -You may need to be using `namada` binaries built from a specific commit in order to interact with specific testnets. Use the below command with the chain ID of the testnet you want to join. +Testnets are released on a fortnightly cycle (every other Tuesday). Sometimes changes are large, sometimes they are small. The [Github changelog](https://github.com/anoma/namada/tree/main/.changelog) will specify exactly what changes have been made in between versions. -```shell -namada client utils join-network --chain-id=$NAMADA_CHAIN_ID -``` +The instructions to join the latest running testnet can be found [HERE](https://hackmd.io/WDhESkCeSWepuki1F1scxg) -## Current testnets +The block explorer is currently in development. The latest version can be found at [namada.world](https://namada.world/) -- [Namada Close Quarters Testnet 1](./namada-close-quarters-testnet-1.md) +We much appreciate any feedback, which we would gladly appreciate through either [Twitter](https://twitter.com/namadanetwork), [Reddit](https://www.reddit.com/r/namada), or [Github](https://github.com/anoma/namada/issues). + +We look forward to seeing you there! \ No newline at end of file diff --git a/documentation/docs/src/testnets/testnets.md b/documentation/docs/src/testnets/testnets.md deleted file mode 100644 index 8112499576..0000000000 --- a/documentation/docs/src/testnets/testnets.md +++ /dev/null @@ -1,14 +0,0 @@ - -# Namada Testnets - -Testnets on Namada serve the purpose of allowing users on the internet to test the latest features of the protocol. Beware of bugs :warning: :ant: ! Pest control can be reached through any of our socials, and we greatly appreciate any bug reports :eyes: :airplane_arriving: - -Testnets are released on a fortnightly cycle (every other Tuesday). Sometimes changes are large, sometimes they are small. The [Github changelog](https://github.com/anoma/namada/tree/main/.changelog) will specify exactly what changes have been made in between versions. - -The instructions to join the latest running testnet can be found [HERE](https://hackmd.io/WDhESkCeSWepuki1F1scxg) - -The block explorer is currently in development. The latest version can be found at [namada.world](https://namada.world/) - -We much appreciate any feedback, which we would gladly appreciate through either [Twitter](https://twitter.com/namadanetwork), [Reddit](https://www.reddit.com/r/namada), or [Github](https://github.com/anoma/namada/issues). - -We look forward to seeing you there! From 538daed986f13d4b964fbd1676c57f345ee68ee3 Mon Sep 17 00:00:00 2001 From: Bengt Date: Thu, 15 Dec 2022 15:13:45 +0000 Subject: [PATCH 009/166] removed some unnecessary docs --- documentation/docs/src/SUMMARY.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/documentation/docs/src/SUMMARY.md b/documentation/docs/src/SUMMARY.md index 40f22fe321..2c4ae23d93 100644 --- a/documentation/docs/src/SUMMARY.md +++ b/documentation/docs/src/SUMMARY.md @@ -10,6 +10,4 @@ - [Shielded transfers](./user-guide/ledger/masp.md) - [Interacting with PoS](./user-guide/ledger/pos.md) - [Governance](./user-guide/ledger/governance.md) - - [Genesis validator setup](./user-guide/genesis-validator-setup.md) - - [Applying to be a genesis validator](./user-guide/genesis-validator-apply.md) - [Testnets](./testnets/README.md) From 6d26905eefdb48bad1068f6492156ede155cf9c6 Mon Sep 17 00:00:00 2001 From: Mateusz Jasiuk Date: Thu, 15 Dec 2022 15:35:13 +0100 Subject: [PATCH 010/166] feat: add Send? --- apps/src/lib/client/types.rs | 4 ++-- shared/src/ledger/queries/mod.rs | 4 ++-- shared/src/ledger/queries/types.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/src/lib/client/types.rs b/apps/src/lib/client/types.rs index 5a26244474..1ed41e9c80 100644 --- a/apps/src/lib/client/types.rs +++ b/apps/src/lib/client/types.rs @@ -53,7 +53,7 @@ pub struct ParsedTxTransferArgs { pub amount: token::Amount, } -#[async_trait] +#[async_trait(?Send)] pub trait ShieldedTransferContext { async fn collect_unspent_notes( &mut self, @@ -70,7 +70,7 @@ pub trait ShieldedTransferContext { async fn query_epoch(&self, ledger_address: TendermintAddress) -> Epoch; } -#[async_trait] +#[async_trait(?Send)] impl ShieldedTransferContext for Context { async fn collect_unspent_notes( &mut self, diff --git a/shared/src/ledger/queries/mod.rs b/shared/src/ledger/queries/mod.rs index 4644909b1a..b155588cda 100644 --- a/shared/src/ledger/queries/mod.rs +++ b/shared/src/ledger/queries/mod.rs @@ -108,7 +108,7 @@ pub mod tm { InvalidHeight(BlockHeight), } - #[async_trait::async_trait] + #[async_trait::async_trait(?Send)] impl Client for crate::tendermint_rpc::HttpClient { type Error = Error; @@ -207,7 +207,7 @@ mod testing { } } - #[async_trait::async_trait] + #[async_trait::async_trait(?Send)] impl Client for TestClient where RPC: Router + Sync, diff --git a/shared/src/ledger/queries/types.rs b/shared/src/ledger/queries/types.rs index 35a3424822..0a15319af1 100644 --- a/shared/src/ledger/queries/types.rs +++ b/shared/src/ledger/queries/types.rs @@ -69,7 +69,7 @@ pub trait Router { /// A client with async request dispatcher method, which can be used to invoke /// type-safe methods from a root [`Router`], generated via `router!` macro. #[cfg(any(test, feature = "async-client"))] -#[async_trait::async_trait] +#[async_trait::async_trait(?Send)] pub trait Client { /// `std::io::Error` can happen in decoding with /// `BorshDeserialize::try_from_slice` From 43243be8767c9ed037fa21d483c6f0d77371f801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 16 Dec 2022 10:55:15 +0100 Subject: [PATCH 011/166] changelog: add #900 --- .changelog/unreleased/improvements/900-no-send-async-traits.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/unreleased/improvements/900-no-send-async-traits.md diff --git a/.changelog/unreleased/improvements/900-no-send-async-traits.md b/.changelog/unreleased/improvements/900-no-send-async-traits.md new file mode 100644 index 0000000000..4648b7617a --- /dev/null +++ b/.changelog/unreleased/improvements/900-no-send-async-traits.md @@ -0,0 +1,3 @@ +- Disable 'Send' on async traits that don't need 'Send' + futures. This allows to use them with 'wasm-bindgen'. + ([#900](https://github.com/anoma/namada/pull/900)) \ No newline at end of file From 6b4722ad82fe920a6c260d4a5e52dce0acd3653e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 16 Dec 2022 11:28:37 +0100 Subject: [PATCH 012/166] shared/ledger: re-export queries sub-routers --- shared/src/ledger/queries/mod.rs | 8 ++++++-- shared/src/ledger/queries/vp/mod.rs | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/shared/src/ledger/queries/mod.rs b/shared/src/ledger/queries/mod.rs index 4644909b1a..be70df2b21 100644 --- a/shared/src/ledger/queries/mod.rs +++ b/shared/src/ledger/queries/mod.rs @@ -1,13 +1,17 @@ //! Ledger read-only queries can be handled and dispatched via the [`RPC`] //! defined via `router!` macro. -use shell::{Shell, SHELL}; +// Re-export to show in rustdoc! +pub use shell::Shell; +use shell::SHELL; #[cfg(any(test, feature = "async-client"))] pub use types::Client; pub use types::{ EncodedResponseQuery, RequestCtx, RequestQuery, ResponseQuery, Router, }; -use vp::{Vp, VP}; +use vp::VP; +// Re-export to show in rustdoc! +pub use vp::{Pos, Vp}; use super::storage::{DBIter, StorageHasher, DB}; use super::storage_api; diff --git a/shared/src/ledger/queries/vp/mod.rs b/shared/src/ledger/queries/vp/mod.rs index ff7c694124..a4de26e20b 100644 --- a/shared/src/ledger/queries/vp/mod.rs +++ b/shared/src/ledger/queries/vp/mod.rs @@ -1,4 +1,6 @@ -use pos::{Pos, POS}; +// Re-export to show in rustdoc! +pub use pos::Pos; +use pos::POS; mod pos; // Validity predicate queries From 9e41de3a4b448c9693b3fa6e11fae7a82cefbdc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 16 Dec 2022 11:34:52 +0100 Subject: [PATCH 013/166] apps/client/tx: fix rustdoc warn for link --- apps/src/lib/client/tx.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/src/lib/client/tx.rs b/apps/src/lib/client/tx.rs index c0cc9d37db..bff1349732 100644 --- a/apps/src/lib/client/tx.rs +++ b/apps/src/lib/client/tx.rs @@ -722,7 +722,7 @@ impl ShieldedContext { /// associated to notes, memos, and diversifiers. And the set of notes that /// we have spent are updated. The witness map is maintained to make it /// easier to construct note merkle paths in other code. See - /// https://zips.z.cash/protocol/protocol.pdf#scan + /// pub fn scan_tx( &mut self, height: BlockHeight, From 5a36fe30fcb9405d6698ec09c6c45a7293c6eea6 Mon Sep 17 00:00:00 2001 From: Bengt Date: Fri, 16 Dec 2022 11:28:25 +0000 Subject: [PATCH 014/166] added more content --- .../docs/src/images/testnet_flowchart.png | Bin 0 -> 57570 bytes documentation/docs/src/testnets/README.md | 9 ++++++++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 documentation/docs/src/images/testnet_flowchart.png diff --git a/documentation/docs/src/images/testnet_flowchart.png b/documentation/docs/src/images/testnet_flowchart.png new file mode 100644 index 0000000000000000000000000000000000000000..35e4d6bc9acf6618b7c22dfe82a360a97648c110 GIT binary patch literal 57570 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 W{-W6=wRtXrAAMb;0~y*U{`@!Qc7T@v literal 0 HcmV?d00001 diff --git a/documentation/docs/src/testnets/README.md b/documentation/docs/src/testnets/README.md index 22336012cd..ce76e1482e 100644 --- a/documentation/docs/src/testnets/README.md +++ b/documentation/docs/src/testnets/README.md @@ -1,13 +1,20 @@ # Namada Testnets -Testnets on Namada serve the purpose of allowing users on the internet to test the latest features of the protocol. Beware of bugs :warning: :ant: ! Pest control can be reached through any of our socials, and we greatly appreciate any bug reports :eyes: :airplane_arriving: +Testnets on Namada serve the purpose of allowing users on the internet to test the latest features of the protocol. Beware of bugs 🚸 🐜 ! Pest control can be reached through any of our socials, and we greatly appreciate any bug reports 👀 🛩 Testnets are released on a fortnightly cycle (every other Tuesday). Sometimes changes are large, sometimes they are small. The [Github changelog](https://github.com/anoma/namada/tree/main/.changelog) will specify exactly what changes have been made in between versions. +## How to join the testnet +```admonish note The instructions to join the latest running testnet can be found [HERE](https://hackmd.io/WDhESkCeSWepuki1F1scxg) +``` +![testnet_flowchart](../images/testnet_flowchart.png) + +## Block explorer The block explorer is currently in development. The latest version can be found at [namada.world](https://namada.world/) +## Feedback appreciated! We much appreciate any feedback, which we would gladly appreciate through either [Twitter](https://twitter.com/namadanetwork), [Reddit](https://www.reddit.com/r/namada), or [Github](https://github.com/anoma/namada/issues). We look forward to seeing you there! \ No newline at end of file From 1afaa12eb5daafce57ca2e76374911164f97c670 Mon Sep 17 00:00:00 2001 From: Awa Sun Yin Date: Fri, 16 Dec 2022 13:27:28 +0100 Subject: [PATCH 015/166] edited the introduction and added more recent sources --- documentation/docs/src/README.md | 8 +++++--- documentation/docs/src/quick-start.md | 2 -- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/docs/src/README.md b/documentation/docs/src/README.md index d5631930b2..34f1357d86 100644 --- a/documentation/docs/src/README.md +++ b/documentation/docs/src/README.md @@ -12,9 +12,6 @@ Key innovations include: - Interoperability with Ethereum via a custom bridge with trust-minimisation - Vertically integrated user interfaces -To learn more, we recommend: -- Article: [Introducing Namada: Shielded Transfers with Any Assets](https://medium.com/namadanetwork/introducing-namada-shielded-transfers-with-any-assets-dce2e579384c) - ## Overview of features - Proof-of-Stake with governance to secure and evolve Namada - Fast-finality BFT with 4-second blocks @@ -26,6 +23,11 @@ To learn more, we recommend: - A reference interface - Ledger application +For high-level introductions, we recommend: +- Article: [Introducing Namada: Shielded Transfers with Any Assets](https://medium.com/namadanetwork/introducing-namada-shielded-transfers-with-any-assets-dce2e579384c) +- Article: [What is Namada?](https://blog.namada.net/what-is-namada/) +- [Talks & Podcasts](https://namada.net/talks) + To learn more about the protocol, we recommend the following in-depth resources: - Talk at ZK8 [Namada: asset-agnostic interchain privacy](https://youtu.be/5K6YxmZPFkE) - [Namada's specifications](https://specs.namada.net) diff --git a/documentation/docs/src/quick-start.md b/documentation/docs/src/quick-start.md index 2183d6641f..dade2125e4 100644 --- a/documentation/docs/src/quick-start.md +++ b/documentation/docs/src/quick-start.md @@ -21,8 +21,6 @@ A simple way to add these binaries to one's path is to run cp namada/target/release/namada* /usr/local/bin/ ``` - - ## Joining a network See [the testnets page](testnets) for details of how to join a testnet. The rest of this guide will assume you have joined a testnet chain using the `namadac utils join-network` command. From 81004f29715872876014e764886ff7791c788f67 Mon Sep 17 00:00:00 2001 From: Awa Sun Yin Date: Fri, 16 Dec 2022 13:39:45 +0100 Subject: [PATCH 016/166] renamed getting started, removed irrelevant parts of overview of binaries, restructured the index --- documentation/docs/src/SUMMARY.md | 13 ++++++---- ...ing-started.md => overview-of-binaries.md} | 24 ++----------------- 2 files changed, 11 insertions(+), 26 deletions(-) rename documentation/docs/src/user-guide/{getting-started.md => overview-of-binaries.md} (59%) diff --git a/documentation/docs/src/SUMMARY.md b/documentation/docs/src/SUMMARY.md index 2c4ae23d93..6f59db9af7 100644 --- a/documentation/docs/src/SUMMARY.md +++ b/documentation/docs/src/SUMMARY.md @@ -4,10 +4,15 @@ - [Quickstart](./quick-start.md) - [User guide](./user-guide/README.md) - [Installing Namada](./user-guide/install.md) - - [Getting started](./user-guide/getting-started.md) + - [Hardware requirements](./user-guide/install.md#hardware-requirements) + - [From source](./user-guide/install.md#from-source) + - [From binaries](./user-guide/install.md#from-binaries) + - [From docker](./user-guide/install.md#from-docker) + - [Overview of binaries](./user-guide/overview-of-binaries.md) - [Managing a wallet](./user-guide/wallet.md) - [The Ledger](./user-guide/ledger.md) - - [Shielded transfers](./user-guide/ledger/masp.md) - - [Interacting with PoS](./user-guide/ledger/pos.md) - - [Governance](./user-guide/ledger/governance.md) + - [Shielded transfers](./user-guide/ledger/masp.md) + - [Interacting with PoS](./user-guide/ledger/pos.md) + - [Governance](./user-guide/ledger/governance.md) - [Testnets](./testnets/README.md) + - [Namada Public Testnet 1]() diff --git a/documentation/docs/src/user-guide/getting-started.md b/documentation/docs/src/user-guide/overview-of-binaries.md similarity index 59% rename from documentation/docs/src/user-guide/getting-started.md rename to documentation/docs/src/user-guide/overview-of-binaries.md index e589bf4e5d..f3de942b6d 100644 --- a/documentation/docs/src/user-guide/getting-started.md +++ b/documentation/docs/src/user-guide/overview-of-binaries.md @@ -1,4 +1,4 @@ -# Getting started +# Overview of binaries This guide assumes that the Namada binaries are [installed](./install.md) and available on path. These are: @@ -19,24 +19,4 @@ To explore the command-line interface, add `--help` argument at any sub-command The binaries should be added to `$PATH` from the `make install` command. However, if this for some reason did not work, a solution may be to copy the binaries from `namada/target/release` to `home/$USER/.local/bin/` for example: `sudo cp namada/target/release/namada* /home/alice/.local/bin/` -``` - -## Join a network - -After you install Namada, you will need to join a live network (e.g. testnet) to be able to interact with a chain and execute most available commands. You can join a network with the following command: - -``` -namada client utils join-network --chain-id= -``` - -To join a testnet, head over to the [testnets](../testnets/README.md) section for details on how to do this. - -## Start your node - -As soon as you are connected to a network, you can start your local node with: - -``` -namada ledger -``` - -Learn more about the configuration of the Ledger in [The Ledger](./ledger.md) section +``` \ No newline at end of file From 9ca626c5231d8ff62264b5911fd94bac7dd3b79e Mon Sep 17 00:00:00 2001 From: Bengt Date: Fri, 16 Dec 2022 12:49:41 +0000 Subject: [PATCH 017/166] docker docs updated --- documentation/docs/src/user-guide/install.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/src/user-guide/install.md b/documentation/docs/src/user-guide/install.md index 441fe118f4..903d1611ff 100644 --- a/documentation/docs/src/user-guide/install.md +++ b/documentation/docs/src/user-guide/install.md @@ -94,4 +94,4 @@ Now, that you have all dependencies installed you can download the latest binary ## From Docker -Go to [heliaxdev dockerhub account](https://hub.docker.com/r/heliaxdev/namada) and pull the image. +The docker image can be found [here](https://github.com/anoma/namada/pkgs/container/namada) From c6b4334968604cb711db743c969f62e238c2d003 Mon Sep 17 00:00:00 2001 From: Awa Sun Yin Date: Fri, 16 Dec 2022 13:49:58 +0100 Subject: [PATCH 018/166] edited the index for the wallet section --- documentation/docs/src/SUMMARY.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/documentation/docs/src/SUMMARY.md b/documentation/docs/src/SUMMARY.md index 6f59db9af7..4a1eb85633 100644 --- a/documentation/docs/src/SUMMARY.md +++ b/documentation/docs/src/SUMMARY.md @@ -9,8 +9,14 @@ - [From binaries](./user-guide/install.md#from-binaries) - [From docker](./user-guide/install.md#from-docker) - [Overview of binaries](./user-guide/overview-of-binaries.md) - - [Managing a wallet](./user-guide/wallet.md) - [The Ledger](./user-guide/ledger.md) + - [Wallet guide](./user-guide/wallet.md) + - [Namada addresses](./user-guide/wallet.md#an-introduction-to-namada-addresses) + - [File system wallet](./user-guide/wallet.md#file-system-wallet) + - [Web wallet](./user-guide/wallet.md#web-wallet) + - [Paper wallet](./user-guide/wallet.md#paper-wallet) + - [Hardware wallet](./user-guide/wallet.md#hardware-wallet) + - [Sending and receiving NAM](./user-guide/wallet.md#send-and-receive-nam-tokens) - [Shielded transfers](./user-guide/ledger/masp.md) - [Interacting with PoS](./user-guide/ledger/pos.md) - [Governance](./user-guide/ledger/governance.md) From ec4e4356202970e9b3c248a37eae17a6c7c30858 Mon Sep 17 00:00:00 2001 From: Awa Sun Yin Date: Fri, 16 Dec 2022 13:55:13 +0100 Subject: [PATCH 019/166] broke down the PoS page into two --- documentation/docs/src/SUMMARY.md | 2 + .../docs/src/user-guide/ledger/pos.md | 157 +----------------- .../docs/src/user-guide/ledger/staking.md | 73 ++++++++ .../docs/src/user-guide/ledger/validators.md | 78 +++++++++ 4 files changed, 155 insertions(+), 155 deletions(-) create mode 100644 documentation/docs/src/user-guide/ledger/staking.md create mode 100644 documentation/docs/src/user-guide/ledger/validators.md diff --git a/documentation/docs/src/SUMMARY.md b/documentation/docs/src/SUMMARY.md index 4a1eb85633..d135863a8e 100644 --- a/documentation/docs/src/SUMMARY.md +++ b/documentation/docs/src/SUMMARY.md @@ -19,6 +19,8 @@ - [Sending and receiving NAM](./user-guide/wallet.md#send-and-receive-nam-tokens) - [Shielded transfers](./user-guide/ledger/masp.md) - [Interacting with PoS](./user-guide/ledger/pos.md) + - [Staking](./user-guide/ledger/staking.md) + - [Validators](./user-guide/ledger/validators.md) - [Governance](./user-guide/ledger/governance.md) - [Testnets](./testnets/README.md) - [Namada Public Testnet 1]() diff --git a/documentation/docs/src/user-guide/ledger/pos.md b/documentation/docs/src/user-guide/ledger/pos.md index 8448dd48bb..a268d679fe 100644 --- a/documentation/docs/src/user-guide/ledger/pos.md +++ b/documentation/docs/src/user-guide/ledger/pos.md @@ -1,4 +1,4 @@ -# 🔏 Interacting with the Proof-of-Stake system +# 🔏 Interacting with the Cubic Proof-of-Stake system The Namada Proof of Stake system uses the NAM token as the staking token. It features delegation to any number of validators and customizable validator validity predicates. @@ -18,157 +18,4 @@ To query the current epoch: ```shell namada client epoch -``` - -## Delegating - -You can delegate to any number of validators at any time. When you delegate tokens, the delegation won't count towards the validator's stake (which in turn determines its voting power) until the beginning of epoch `n + 2` in the current epoch `n` (the literal `2` is set by PoS parameter `pipeline_len`). The delegated amount of tokens will be deducted from your account immediately, and will be credited to the PoS system's account. - -To submit a delegation that bonds tokens from the source address to a validator with alias `validator-1`: - -```shell -namada client bond \ - --source my-new-acc \ - --validator validator-1 \ - --amount 12.34 -``` - -You can query your delegations: - -```shell -namada client bonds --owner my-new-acc -``` - -The result of this query will inform the epoch from which your delegations will be active. - -Because the PoS system is just an account, you can query its balance, which is the sum of all staked tokens: - -```shell -namada client balance --owner PoS -``` - -### Slashes - -Should a validator exhibit punishable behavior, the delegations towards this validator are also liable for slashing. Only the delegations that were active in the epoch in which the fault occurred will be slashed by the slash rate of the fault type. If any of your delegations have been slashed, this will be displayed in the `bonds` query. You can also find all the slashes applied with: - -```shell -namada client slashes -``` - -### Unbonding - -While your tokens are being delegated, they are locked-in the PoS system and hence are not liquid until you withdraw them. To do that, you first need to send a transaction to “unbond” your tokens. You can unbond any amount, up to the sum of all your delegations to the given validator, even before they become active. - -To submit an unbonding of a delegation of tokens from a source address to the validator: - -```shell -namada client unbond \ - --source my-new-acc \ - --validator validator-1 \ - --amount 1.2 -``` - -When you unbond tokens, you won't be able to withdraw them immediately. Instead, tokens unbonded in the epoch `n` will be withdrawable starting from the epoch `n + 6` (the literal `6` is set by PoS parameter `unbonding_len`). After you unbond some tokens, you will be able to see when you can withdraw them via `bonds` query: - -```shell -namada client bonds --owner my-new-acc -``` - -When the chain reaches the epoch in which you can withdraw the tokens (or anytime after), you can submit a withdrawal of unbonded delegation of tokens back to your account: - -```shell -namada client withdraw \ - --source my-new-acc \ - --validator validator-1 -``` - -Upon success, the withdrawn tokens will be credited back your account and debited from the PoS system. - -### Validators' Voting Power - -To see all validators and their voting power, which is exactly equal to the amount of staked NAM tokens from their self-bonds and delegations, you can query: - -```shell -namada client bonded-stake -``` - -With this command, you can specify `--epoch` to find the voting powers at some future epoch. Note that only the voting powers for the current and the next epoch are final. - -## 📒 PoS Validators - -### Generate a validator account - -To register a new validator account, run: - -```shell -namada client init-validator \ - --alias my-validator \ - --source my-new-acc \ - --commission-rate - --max-commission-rate-change -``` - -The commission rate charged by the validator for delegation rewards and the maximum change per epoch in the commission rate charged by the validator for delegation rewards. Both are expressed as a decimal between 0 and 1. *Staking rewards are not yet implemented*. - -This command will generate the keys required for running a validator: - -- Consensus key, which is used in [signing blocks in Tendermint](https://docs.tendermint.com/master/nodes/validators.html#validator-keys). -- Validator account key for signing transactions on the validator account, such as token self-bonding, unbonding and withdrawal, validator keys, validity predicate, state and metadata updates. - -Then, it submits a transaction to the ledger that generates the new validator account with established address, which can be used to receive new delegations. - -The keys and the alias of the address will be saved in your wallet. Your local ledger node will also be setup to run this validator, you just have to shut it down with e.g. `Ctrl + C`, then start it again with the same command: - -```shell -namada ledger -``` - -The ledger will then use the validator consensus key to sign blocks, should your validator account acquire enough voting power to be included in the active validator set. The size of the active validator set is limited to `128` (the limit is set by the PoS `max_validator_slots` parameter). - -Note that the balance of NAM tokens that is in your validator account does not count towards your validator's stake and voting power: - -```shell -namada client balance --owner my-validator --token NAM -``` - -That is, the balance of your account's address is a regular liquid balance that you can transfer using your validator account key, depending on the rules of the validator account's validity predicate. The default validity predicate allows you to transfer it with a signed transaction and/or stake it in the PoS system. - -### Self-bonding - -You can submit a self-bonding transaction of tokens from a validator account to the PoS system with: - -```shell -namada client bond \ - --validator my-validator \ - --amount 3.3 -``` - -### Determine your voting power - -A validator's voting power is determined by the sum of all their active self-bonds and delegations of tokens, with slashes applied, if any. - -The same rules apply to delegations. When you self-bond tokens, the bonded amount won't count towards your validator's stake (which in turn determines your power) until the beginning of epoch `n + 2` in the current epoch `n`. The bonded amount of tokens will be deducted from the validator's account immediately and will be credited to the PoS system's account. - -While your tokens are being self-bonded, they are locked-in the PoS system and hence are not liquid until you withdraw them. To do that, you first need to send a transaction to “unbond” your tokens. You can unbond any amount, up to the sum of all your self-bonds, even before they become active. - -### Self-unbonding - -To submit an unbonding of self-bonded tokens from your validator: - -```shell -namada client unbond \ - --validator my-validator \ - --amount 0.3 -``` - -Again, when you unbond tokens, you won't be able to withdraw them immediately. Instead, tokens unbonded in the epoch `n` will be withdrawable starting from the epoch `n + 6`. After you unbond some tokens, you will be able to see when you can withdraw them via `bonds` query: - -```shell -namada client bonds --validator my-validator -``` - -When the chain reaches the epoch in which you can withdraw the tokens (or anytime after), you can submit a withdrawal of unbonded tokens back to your validator account: - -```shell -namada client withdraw --validator my-validator -``` +``` \ No newline at end of file diff --git a/documentation/docs/src/user-guide/ledger/staking.md b/documentation/docs/src/user-guide/ledger/staking.md new file mode 100644 index 0000000000..517b2745d2 --- /dev/null +++ b/documentation/docs/src/user-guide/ledger/staking.md @@ -0,0 +1,73 @@ +# Delegating (Staking) + +You can delegate to any number of validators at any time. When you delegate tokens, the delegation won't count towards the validator's stake (which in turn determines its voting power) until the beginning of epoch `n + 2` in the current epoch `n` (the literal `2` is set by PoS parameter `pipeline_len`). The delegated amount of tokens will be deducted from your account immediately, and will be credited to the PoS system's account. + +To submit a delegation that bonds tokens from the source address to a validator with alias `validator-1`: + +```shell +namada client bond \ + --source my-new-acc \ + --validator validator-1 \ + --amount 12.34 +``` + +You can query your delegations: + +```shell +namada client bonds --owner my-new-acc +``` + +The result of this query will inform the epoch from which your delegations will be active. + +Because the PoS system is just an account, you can query its balance, which is the sum of all staked tokens: + +```shell +namada client balance --owner PoS +``` + +## Slashes + +Should a validator exhibit punishable behavior, the delegations towards this validator are also liable for slashing. Only the delegations that were active in the epoch in which the fault occurred will be slashed by the slash rate of the fault type. If any of your delegations have been slashed, this will be displayed in the `bonds` query. You can also find all the slashes applied with: + +```shell +namada client slashes +``` + +## Unbonding + +While your tokens are being delegated, they are locked-in the PoS system and hence are not liquid until you withdraw them. To do that, you first need to send a transaction to “unbond” your tokens. You can unbond any amount, up to the sum of all your delegations to the given validator, even before they become active. + +To submit an unbonding of a delegation of tokens from a source address to the validator: + +```shell +namada client unbond \ + --source my-new-acc \ + --validator validator-1 \ + --amount 1.2 +``` + +When you unbond tokens, you won't be able to withdraw them immediately. Instead, tokens unbonded in the epoch `n` will be withdrawable starting from the epoch `n + 6` (the literal `6` is set by PoS parameter `unbonding_len`). After you unbond some tokens, you will be able to see when you can withdraw them via `bonds` query: + +```shell +namada client bonds --owner my-new-acc +``` + +When the chain reaches the epoch in which you can withdraw the tokens (or anytime after), you can submit a withdrawal of unbonded delegation of tokens back to your account: + +```shell +namada client withdraw \ + --source my-new-acc \ + --validator validator-1 +``` + +Upon success, the withdrawn tokens will be credited back your account and debited from the PoS system. + +## Validators' Voting Power + +To see all validators and their voting power, which is exactly equal to the amount of staked NAM tokens from their self-bonds and delegations, you can query: + +```shell +namada client bonded-stake +``` + +With this command, you can specify `--epoch` to find the voting powers at some future epoch. Note that only the voting powers for the current and the next epoch are final. \ No newline at end of file diff --git a/documentation/docs/src/user-guide/ledger/validators.md b/documentation/docs/src/user-guide/ledger/validators.md new file mode 100644 index 0000000000..09159cdf3e --- /dev/null +++ b/documentation/docs/src/user-guide/ledger/validators.md @@ -0,0 +1,78 @@ +# 📒 PoS Validators + +## Generate a validator account + +To register a new validator account, run: + +```shell +namada client init-validator \ + --alias my-validator \ + --source my-new-acc \ + --commission-rate + --max-commission-rate-change +``` + +The commission rate charged by the validator for delegation rewards and the maximum change per epoch in the commission rate charged by the validator for delegation rewards. Both are expressed as a decimal between 0 and 1. *Staking rewards are not yet implemented*. + +This command will generate the keys required for running a validator: + +- Consensus key, which is used in [signing blocks in Tendermint](https://docs.tendermint.com/master/nodes/validators.html#validator-keys). +- Validator account key for signing transactions on the validator account, such as token self-bonding, unbonding and withdrawal, validator keys, validity predicate, state and metadata updates. + +Then, it submits a transaction to the ledger that generates the new validator account with established address, which can be used to receive new delegations. + +The keys and the alias of the address will be saved in your wallet. Your local ledger node will also be setup to run this validator, you just have to shut it down with e.g. `Ctrl + C`, then start it again with the same command: + +```shell +namada ledger +``` + +The ledger will then use the validator consensus key to sign blocks, should your validator account acquire enough voting power to be included in the active validator set. The size of the active validator set is limited to `128` (the limit is set by the PoS `max_validator_slots` parameter). + +Note that the balance of NAM tokens that is in your validator account does not count towards your validator's stake and voting power: + +```shell +namada client balance --owner my-validator --token NAM +``` + +That is, the balance of your account's address is a regular liquid balance that you can transfer using your validator account key, depending on the rules of the validator account's validity predicate. The default validity predicate allows you to transfer it with a signed transaction and/or stake it in the PoS system. + +## Self-bonding + +You can submit a self-bonding transaction of tokens from a validator account to the PoS system with: + +```shell +namada client bond \ + --validator my-validator \ + --amount 3.3 +``` + +## Determine your voting power + +A validator's voting power is determined by the sum of all their active self-bonds and delegations of tokens, with slashes applied, if any. + +The same rules apply to delegations. When you self-bond tokens, the bonded amount won't count towards your validator's stake (which in turn determines your power) until the beginning of epoch `n + 2` in the current epoch `n`. The bonded amount of tokens will be deducted from the validator's account immediately and will be credited to the PoS system's account. + +While your tokens are being self-bonded, they are locked-in the PoS system and hence are not liquid until you withdraw them. To do that, you first need to send a transaction to “unbond” your tokens. You can unbond any amount, up to the sum of all your self-bonds, even before they become active. + +## Self-unbonding + +To submit an unbonding of self-bonded tokens from your validator: + +```shell +namada client unbond \ + --validator my-validator \ + --amount 0.3 +``` + +Again, when you unbond tokens, you won't be able to withdraw them immediately. Instead, tokens unbonded in the epoch `n` will be withdrawable starting from the epoch `n + 6`. After you unbond some tokens, you will be able to see when you can withdraw them via `bonds` query: + +```shell +namada client bonds --validator my-validator +``` + +When the chain reaches the epoch in which you can withdraw the tokens (or anytime after), you can submit a withdrawal of unbonded tokens back to your validator account: + +```shell +namada client withdraw --validator my-validator +``` From a9f45b473cd8849aa262aba5f8aedaae34189798 Mon Sep 17 00:00:00 2001 From: Awa Sun Yin Date: Fri, 16 Dec 2022 13:58:09 +0100 Subject: [PATCH 020/166] split the governance page into two --- documentation/docs/src/SUMMARY.md | 2 + .../docs/src/user-guide/ledger/governance.md | 138 +----------------- .../user-guide/ledger/off-chain-governance.md | 47 ++++++ .../user-guide/ledger/on-chain-governance.md | 87 +++++++++++ 4 files changed, 137 insertions(+), 137 deletions(-) create mode 100644 documentation/docs/src/user-guide/ledger/off-chain-governance.md create mode 100644 documentation/docs/src/user-guide/ledger/on-chain-governance.md diff --git a/documentation/docs/src/SUMMARY.md b/documentation/docs/src/SUMMARY.md index d135863a8e..9d299558a2 100644 --- a/documentation/docs/src/SUMMARY.md +++ b/documentation/docs/src/SUMMARY.md @@ -22,5 +22,7 @@ - [Staking](./user-guide/ledger/staking.md) - [Validators](./user-guide/ledger/validators.md) - [Governance](./user-guide/ledger/governance.md) + - [On-chain proposals](./user-guide/ledger/on-chain-governance.md) + - [Off-chain proposals](./user-guide/ledger/off-chain-governance.md) - [Testnets](./testnets/README.md) - [Namada Public Testnet 1]() diff --git a/documentation/docs/src/user-guide/ledger/governance.md b/documentation/docs/src/user-guide/ledger/governance.md index 0936b75629..75319cb91d 100644 --- a/documentation/docs/src/user-guide/ledger/governance.md +++ b/documentation/docs/src/user-guide/ledger/governance.md @@ -5,140 +5,4 @@ The Namada governance mechanism gives users the possibility to upgrade the proto There are two different mechanism to create a proposal: - [On-chain proposals](#on-chain-proposals): Proposal is voted on and tallied on-chain. This can optionally include proposal code to be executed if the proposal is accepted. -- [Off-chain proposals](#off-chain-proposals) - -## On-chain proposals - -### Create a proposal - -Assuming you have an account with at least 500 NAM token (in this example we are going to use `my-new-acc`), lets get the corresponding address - -```shell -namada wallet address find --alias `my-new-acc` -``` - -Now, we need to create a json file `proposal.json` holding the content of our proposal. Copy the below text into a json file. - -```json -{ - "content": { - "title": "Proposal title", - "authors": "email@proposal.n", - "discussions-to": "www.github.com/anoma/aip/1", - "created": "2022-03-10T08:54:37Z", - "license": "MIT", - "abstract": "Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros. Nullam sed ex justo. Ut at placerat ipsum, sit amet rhoncus libero. Sed blandit non purus non suscipit. Phasellus sed quam nec augue bibendum bibendum ut vitae urna. Sed odio diam, ornare nec sapien eget, congue viverra enim.", - "motivation": "Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices.", - "details": "Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros.", - "requires": "2" - }, - "author": "TODO", - "voting_start_epoch": 3, - "voting_end_epoch": 6, - "grace_epoch": 12, - "proposal_code_path": "./wasm_for_tests/tx_no_op.wasm" -} -``` - -You should change the value of: - -- `Author` field with the address of `my-new-acc`. -- `voting_start_epoch` with a future epoch (must be a multiple of 3) for which you want the voting to begin -- `voting_end_epoch` with an epoch greater than `voting_start_epoch`, a multiple of 3, and by which no further votes will be accepted -- `grace_epoch` with an epoch greater than `voting_end_epoch` + 6, in which the proposal, if passed, will come into effect -- `proposal_code_path` with the absolute path of the wasm file to execute (or remove the field completely) - -As soon as your `proposal.json` file is ready, you can submit the proposal with (making sure to be in the same directory as the `proposal.json` file): - -```shell -namada client init-proposal --data-path proposal.json -``` - -The transaction should have been accepted. You can query all the proposals with: - -```shell -namada client query-proposal -``` - -or a single proposal with - -```shell -namada client query-proposal --proposal-id 0 -``` - -where `0` is the proposal id. - -### Vote a proposal - -Only validators and delegators can vote. Assuming you have a validator or a delegator account (in this example we are going to use `validator`), you can send a vote with the following command: - -```shell -namada client vote-proposal \ - --proposal-id 0 \ - --vote yay \ - --signer validator -``` - -where `--vote` can be either `yay` or `nay`. - -### Check the result - -As soon as the ledger reaches the epoch defined in the json as `voting_end_epoch`, no votes will be accepted. The code definied in `proposal_code` json field will be executed at the beginning of `grace_epoch` epoch. You can use the following commands to check the status of a proposal: - -```shell -namada client query-proposal --proposal-id 0 -``` - -or to just check the result: - -```shell -namada client query-proposal-result --proposal-id 0 -``` - -## Off-chain proposals - -If for any reason issuing an on-chain proposal is not adequate to your needs, you still have the option to create an off-chain proposal. - -### Create proposal - -Create the same json file as in the on-chain proposal and use the following command: - -```shell -namada client init-proposal \ - --data-path proposal.json \ - --offline -``` - -This command will create a `proposal` file same directory where the command was launched. - -### Vote on proposal - -To vote on an offline proposal use the following command: - -```shell -namada client vote-proposal --data-path proposal \ - --vote yay \ - --signer validator \ - --offline -``` - -This command will create a `proposal-vote-${address}` file (where address is the `--signer` address). - -### Tally off-chain proposal - -To compute the tally for an offline proposal we need to collect - -- `proposal` file (must have this name) -- all the `proposal-vote-${address}` files - -All those files will have to be in a folder (lets call it `offline-proposal`). - -Now you can use the following command: - -```shell -namada client query-proposal-result \ - --offline \ - --data-path `offline-proposal` -``` - -which will tell you the proposal result. +- [Off-chain proposals](#off-chain-proposals) \ No newline at end of file diff --git a/documentation/docs/src/user-guide/ledger/off-chain-governance.md b/documentation/docs/src/user-guide/ledger/off-chain-governance.md new file mode 100644 index 0000000000..540e21dd52 --- /dev/null +++ b/documentation/docs/src/user-guide/ledger/off-chain-governance.md @@ -0,0 +1,47 @@ +# Off-chain proposals + +If for any reason issuing an on-chain proposal is not adequate to your needs, you still have the option to create an off-chain proposal. + +## Create proposal + +Create the same json file as in the on-chain proposal and use the following command: + +```shell +namada client init-proposal \ + --data-path proposal.json \ + --offline +``` + +This command will create a `proposal` file same directory where the command was launched. + +## Vote on proposal + +To vote on an offline proposal use the following command: + +```shell +namada client vote-proposal --data-path proposal \ + --vote yay \ + --signer validator \ + --offline +``` + +This command will create a `proposal-vote-${address}` file (where address is the `--signer` address). + +## Tally off-chain proposal + +To compute the tally for an offline proposal we need to collect + +- `proposal` file (must have this name) +- all the `proposal-vote-${address}` files + +All those files will have to be in a folder (lets call it `offline-proposal`). + +Now you can use the following command: + +```shell +namada client query-proposal-result \ + --offline \ + --data-path `offline-proposal` +``` + +which will tell you the proposal result. diff --git a/documentation/docs/src/user-guide/ledger/on-chain-governance.md b/documentation/docs/src/user-guide/ledger/on-chain-governance.md new file mode 100644 index 0000000000..9223bf19ea --- /dev/null +++ b/documentation/docs/src/user-guide/ledger/on-chain-governance.md @@ -0,0 +1,87 @@ +# On-chain proposals + +## Create a proposal + +Assuming you have an account with at least 500 NAM token (in this example we are going to use `my-new-acc`), lets get the corresponding address + +```shell +namada wallet address find --alias `my-new-acc` +``` + +Now, we need to create a json file `proposal.json` holding the content of our proposal. Copy the below text into a json file. + +```json +{ + "content": { + "title": "Proposal title", + "authors": "email@proposal.n", + "discussions-to": "www.github.com/anoma/aip/1", + "created": "2022-03-10T08:54:37Z", + "license": "MIT", + "abstract": "Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros. Nullam sed ex justo. Ut at placerat ipsum, sit amet rhoncus libero. Sed blandit non purus non suscipit. Phasellus sed quam nec augue bibendum bibendum ut vitae urna. Sed odio diam, ornare nec sapien eget, congue viverra enim.", + "motivation": "Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices.", + "details": "Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros.", + "requires": "2" + }, + "author": "TODO", + "voting_start_epoch": 3, + "voting_end_epoch": 6, + "grace_epoch": 12, + "proposal_code_path": "./wasm_for_tests/tx_no_op.wasm" +} +``` + +You should change the value of: + +- `Author` field with the address of `my-new-acc`. +- `voting_start_epoch` with a future epoch (must be a multiple of 3) for which you want the voting to begin +- `voting_end_epoch` with an epoch greater than `voting_start_epoch`, a multiple of 3, and by which no further votes will be accepted +- `grace_epoch` with an epoch greater than `voting_end_epoch` + 6, in which the proposal, if passed, will come into effect +- `proposal_code_path` with the absolute path of the wasm file to execute (or remove the field completely) + +As soon as your `proposal.json` file is ready, you can submit the proposal with (making sure to be in the same directory as the `proposal.json` file): + +```shell +namada client init-proposal --data-path proposal.json +``` + +The transaction should have been accepted. You can query all the proposals with: + +```shell +namada client query-proposal +``` + +or a single proposal with + +```shell +namada client query-proposal --proposal-id 0 +``` + +where `0` is the proposal id. + +## Vote a proposal + +Only validators and delegators can vote. Assuming you have a validator or a delegator account (in this example we are going to use `validator`), you can send a vote with the following command: + +```shell +namada client vote-proposal \ + --proposal-id 0 \ + --vote yay \ + --signer validator +``` + +where `--vote` can be either `yay` or `nay`. + +## Check the result + +As soon as the ledger reaches the epoch defined in the json as `voting_end_epoch`, no votes will be accepted. The code definied in `proposal_code` json field will be executed at the beginning of `grace_epoch` epoch. You can use the following commands to check the status of a proposal: + +```shell +namada client query-proposal --proposal-id 0 +``` + +or to just check the result: + +```shell +namada client query-proposal-result --proposal-id 0 +``` From 76bccc08e36325995cf5d7b51ab4e1ef3199e198 Mon Sep 17 00:00:00 2001 From: Awa Sun Yin Date: Fri, 16 Dec 2022 14:21:47 +0100 Subject: [PATCH 021/166] added testnet instructions into sections --- documentation/docs/src/SUMMARY.md | 6 ++- documentation/docs/src/testnets/README.md | 13 +++-- .../docs/src/testnets/environment-setup.md | 46 +++++++++++++++++ .../src/testnets/post-genesis-validator.md | 51 +++++++++++++++++++ .../src/testnets/pre-genesis-validator.md | 19 +++++++ .../testnets/run-your-genesis-validator.md | 48 +++++++++++++++++ .../docs/src/testnets/running-a-full-node.md | 15 ++++++ 7 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 documentation/docs/src/testnets/environment-setup.md create mode 100644 documentation/docs/src/testnets/post-genesis-validator.md create mode 100644 documentation/docs/src/testnets/pre-genesis-validator.md create mode 100644 documentation/docs/src/testnets/run-your-genesis-validator.md create mode 100644 documentation/docs/src/testnets/running-a-full-node.md diff --git a/documentation/docs/src/SUMMARY.md b/documentation/docs/src/SUMMARY.md index 9d299558a2..40e169cabe 100644 --- a/documentation/docs/src/SUMMARY.md +++ b/documentation/docs/src/SUMMARY.md @@ -25,4 +25,8 @@ - [On-chain proposals](./user-guide/ledger/on-chain-governance.md) - [Off-chain proposals](./user-guide/ledger/off-chain-governance.md) - [Testnets](./testnets/README.md) - - [Namada Public Testnet 1]() + - [Environment setup](./testnets/environment-setup.md) + - [Pre-genesis validator](./testnets/pre-genesis-validator.md) + - [Running your genesis validator](./testnets/run-your-genesis-validator.md) + - [Running a full node](./testnets/running-a-full-node.md) + - [Becoming a validator post-genesis](./testnets/post-genesis-validator.md) diff --git a/documentation/docs/src/testnets/README.md b/documentation/docs/src/testnets/README.md index ce76e1482e..daea4eab39 100644 --- a/documentation/docs/src/testnets/README.md +++ b/documentation/docs/src/testnets/README.md @@ -1,8 +1,15 @@ # Namada Testnets -Testnets on Namada serve the purpose of allowing users on the internet to test the latest features of the protocol. Beware of bugs 🚸 🐜 ! Pest control can be reached through any of our socials, and we greatly appreciate any bug reports 👀 🛩 +For more context read: +- [Announcing Namada Public Testnets](https://blog.namada.net/announcing-namada-public-testnets/) -Testnets are released on a fortnightly cycle (every other Tuesday). Sometimes changes are large, sometimes they are small. The [Github changelog](https://github.com/anoma/namada/tree/main/.changelog) will specify exactly what changes have been made in between versions. +## Namada protocol versions + +A testnet might deploy different versions of the Namada protocol. To see in-detail what each protocol version includes, refer to the [Github changelog](https://github.com/anoma/namada/tree/main/.changelog), which specify what changes have been made in between versions. + +## Report a bug + +If you found a bug, please submit an issue with the `bug` [issue template](https://github.com/anoma/namada/issues/new/choose). ## How to join the testnet ```admonish note @@ -14,7 +21,7 @@ The instructions to join the latest running testnet can be found [HERE](https:// ## Block explorer The block explorer is currently in development. The latest version can be found at [namada.world](https://namada.world/) -## Feedback appreciated! +## Community We much appreciate any feedback, which we would gladly appreciate through either [Twitter](https://twitter.com/namadanetwork), [Reddit](https://www.reddit.com/r/namada), or [Github](https://github.com/anoma/namada/issues). We look forward to seeing you there! \ No newline at end of file diff --git a/documentation/docs/src/testnets/environment-setup.md b/documentation/docs/src/testnets/environment-setup.md new file mode 100644 index 0000000000..3e2467e935 --- /dev/null +++ b/documentation/docs/src/testnets/environment-setup.md @@ -0,0 +1,46 @@ +## 1) Environment setup + +- Export the following variables: + ```bash + export NAMADA_TAG=v0.11.0 + export TM_HASH=v0.1.4-abciplus + ``` +- Clone namada repository and build binaries + ```bash + git clone https://github.com/anoma/namada && cd namada && git checkout $NAMADA_TAG + ``` +- Build binaries + - `make build-release` + - There may be some additional requirements you may have to install (linux): + ```bash + sudo apt-get update -y + sudo apt-get install build-essential make pkg-config libssl-dev libclang-dev -y + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + ``` +- Install the heliaxdev/tendermint fork + ```bash + git clone https://github.com/heliaxdev/tendermint && cd tendermint && git checkout $TM_HASH + make build + ``` + The above requires that golang is correctly installed with the correct $PATH setup + - In linux, this can be resolved by + - `sudo snap install go --channel=1.18/stable --classic` +- Copy both the namada and tendermint binaries to somewhere on $PATH (or uselol the relative paths) + - This step may or may not be necessary + - namada binaries can be found in `/target/release` + - tendermint is in `build/tendermint` +- Open ports on your machine: + - 26656 + - 26657 + - To check if ports are open you can setup a simple server and curl the port from another host + - Inside the namada folder, run + ``` bash + { printf 'HTTP/1.0 200 OK\r\nContent-Length: %d\r\n\r\n' "$(wc -c < namada)"; cat namada; } | nc -l $PORT` + ``` + - From another host run one of the two commands: + - `nmap $IP -p$PORT` + - `curl $IP:$PORT >/dev/null` +- Make sure you are using the correct tendermint version + - `tendermint version` should output `0.1.4-abciplus` +- Make sure you are using the correct Namada version + - `namada --version` should output `Namada v0.11.0` diff --git a/documentation/docs/src/testnets/post-genesis-validator.md b/documentation/docs/src/testnets/post-genesis-validator.md new file mode 100644 index 0000000000..a7c99b069b --- /dev/null +++ b/documentation/docs/src/testnets/post-genesis-validator.md @@ -0,0 +1,51 @@ +# 5) Become a validator post genesis + +After genesis, you can still join the network as a user and become a validator through self-bonding. + +After following step 4), create a user account through the following command + +```bash +namada wallet address gen --alias my-account +``` + +Now choose a name for your validator: + +```bash! +export VALIDATOR_ALIAS="your-validator-name" +``` + +A validator account requires additional keys compared to a user account, so start by initialising a validator account: + +```bash! +namada client init-validator \ + --alias $VALIDATOR_ALIAS \ + --source my-account \ + --commission-rate \ + --max-commission-rate-change + +``` + +Then ensure you have enough NAM in order to self bond. Each voting power requires 1000 NAM, and you must be in the top 120 validators in terms of voting-power in order to become an active validator. You can see other validators' voting power through: + +```bash! +namada client bonded-stake +``` + +## Faucet + +In order to gain more NAM, the following command can be run: +```bash! +namadac transfer \ + --token NAM \ + --amount 1000 \ + --source faucet \ + --target $VALIDATOR_ALIAS \ + --signer $VALIDATOR_ALIAS +``` +Note: A maximum amount of 1000 NAM can be sourced from the faucet per transaction, so to get more, run this multiple times + +```bash! +namada client bond \ + --validator $VALIDATOR_ALIAS \ + --amount +``` diff --git a/documentation/docs/src/testnets/pre-genesis-validator.md b/documentation/docs/src/testnets/pre-genesis-validator.md new file mode 100644 index 0000000000..f5f2cd03b9 --- /dev/null +++ b/documentation/docs/src/testnets/pre-genesis-validator.md @@ -0,0 +1,19 @@ +## 2) Generate pre-genesis validator setup + +- Create a pre-genesis file inside the `namada` repository. + - + ``` bash + cd namada + export ALIAS="CHOOSE_A_NAME_FOR_YOUR_VALIDATOR" + export PUBLIC_IP="LAPTOP_OR_SERVER_IP" + namada client utils init-genesis-validator --alias $ALIAS --max-commission-rate-change 0.01 --commission-rate 0.05 --net-address $PUBLIC_IP:26656 + ``` + - Expect the message `Pre-genesis TOML written to .namada/pre-genesis/[your-alias]/validator.toml` +- This will generate a folder inside `namada/.namada`. + - `cat namada/.namada/pre-genesis/$ALIAS/validator.toml` + +## 2.1) Submitting the config +If you want to be a genesis validator for the testnet, please make a pull request to https://github.com/anoma/namada-testnets adding your validator.toml file to the relevant directory (e.g. `namada-close-quarters-testnet-5` for the `namada-cq-5` testnet), renaming it to `$alias.toml`. e.g. if you chose your alias to be "bertha", submit the file with the name `bertha.toml`. You can see what an example PR looks like [here](https://github.com/anoma/namada-testnets/pull/29). + +## 2.2) Wait for launch +Wait until the testnet is launched and a `CHAIN_ID` has been distributed. diff --git a/documentation/docs/src/testnets/run-your-genesis-validator.md b/documentation/docs/src/testnets/run-your-genesis-validator.md new file mode 100644 index 0000000000..9d7aaddf4c --- /dev/null +++ b/documentation/docs/src/testnets/run-your-genesis-validator.md @@ -0,0 +1,48 @@ +## 3) MANDATORY: Reset your validator node +- You can skip to 3.1 if you don't need to reset the ledger state +- This is the right time to save any logs file you want to share with us! +- Save your `pre-genesis` folder in the ledger base directory + - `mkdir backup-pregenesis && cp -r .anoma/pre-genesis backup-pregenesis/` +- Delete ledger base directory **[WARNING: THIS WILL ALSO DELETE YOUR VALIDATOR KEYS, DO NOT RUN UNLESS YOU'VE BACKED IT UP]** + - `rm -rf .anoma` +- Check that namada and tendermint binaries are correct (see step 1) +- If you have you are a genesis validator from the previous testnet continue with the instructions below otherwise go to step `3.1` +- Inside the `backup-genesis` folder there are 2 files `validator.toml` and `wallet.toml`. You need make some changes to those: + - Remove `staking_reward_public_key` from `validator.toml` + - Remove `rewards_key` from `wallet.toml` + - Add the following two field to `validator.toml` + ``` + commission_rate = 0.05 + max_commission_rate_change = 0.01 + ``` +- Create a `.namada` folder + - `mkdir .namada` + - `mkdir .namada/pre-genesis` +- Copy the backuped file back to `.namada/pre-genesis` folder + - `cp -r backup-pregenesis/* .namada/pre-genesis/` + + + +## 3.1) Run your node as a genesis validator + +- Wait for the genesis file to be ready, `CHAIN_ID`. +- Join the network with the `CHAIN_ID` + ``` bash + export CHAIN_ID="qc-testnet-5.1.025a61165acd05e" + namada client utils join-network \ + --chain-id $CHAIN_ID --genesis-validator $ALIAS + ``` +- Start your node and sync + - `NAMADA_TM_STDOUT=true namada node ledger run` + - if you want more logs + - `NAMADA_LOG=debug NAMADA_TM_STDOUT=true namada node ledger run` + - if you want to save logs to a file + - `TIMESTAMP=$(date +%s)` + - `NAMADA_LOG=debug NAMADA_TM_STDOUT=true namada node ledger run &> logs-${TIMESTAMP}.txt` + - `tail -f -n 20 logs-${TIMESTAMP}.txt` (in another shell) +- If started correctly you should see a the following log: + - `[] This node is a validator ...` + \ No newline at end of file diff --git a/documentation/docs/src/testnets/running-a-full-node.md b/documentation/docs/src/testnets/running-a-full-node.md new file mode 100644 index 0000000000..5e1fbc9dff --- /dev/null +++ b/documentation/docs/src/testnets/running-a-full-node.md @@ -0,0 +1,15 @@ +# 4) Run your full node as a user +- Wait for the genesis file to be ready, you will receive a `$CHAIN_ID`. +- Join the network with the `CHAIN_ID` +```bash + export CHAIN_ID="qc-testnet-5.1.025a61165acd05e" + namada client utils join-network --chain-id $CHAIN_ID + ``` +- Start your node and sync + - `NAMADA_TM_STDOUT=true namada node ledger run` + - if you want more logs + - `NAMADA_LOG=debug ANOMA_TM_STDOUT=true namada node ledger run` + - if you want to save logs to a file + - `TIMESTAMP=$(date +%s)` + - `ANOMA_LOG=debug NAMADA_TM_STDOUT=true namada node ledger run &> logs-${TIMESTAMP}.txt` + - `tail -f -n 20 logs-${TIMESTAMP}.txt` (in another shell) \ No newline at end of file From 88956a08127f88191b96ffd2afcb1de2f555f94b Mon Sep 17 00:00:00 2001 From: Awa Sun Yin Date: Fri, 16 Dec 2022 14:29:06 +0100 Subject: [PATCH 022/166] deleted old docs, edited the general testnet readme --- documentation/docs/src/testnets/README.md | 22 +- .../docs/src/testnets/environment-setup.md | 2 +- .../docs/src/testnets/gov-masp-devnet-1.md | 17 -- .../docs/src/testnets/internal-testnet-1.md | 198 ------------------ .../src/testnets/pre-genesis-validator.md | 2 +- .../testnets/run-your-genesis-validator.md | 2 +- 6 files changed, 18 insertions(+), 225 deletions(-) delete mode 100644 documentation/docs/src/testnets/gov-masp-devnet-1.md delete mode 100644 documentation/docs/src/testnets/internal-testnet-1.md diff --git a/documentation/docs/src/testnets/README.md b/documentation/docs/src/testnets/README.md index daea4eab39..32a2f9d117 100644 --- a/documentation/docs/src/testnets/README.md +++ b/documentation/docs/src/testnets/README.md @@ -11,17 +11,25 @@ A testnet might deploy different versions of the Namada protocol. To see in-deta If you found a bug, please submit an issue with the `bug` [issue template](https://github.com/anoma/namada/issues/new/choose). -## How to join the testnet -```admonish note -The instructions to join the latest running testnet can be found [HERE](https://hackmd.io/WDhESkCeSWepuki1F1scxg) -``` +## How to join a Namada testnet + 1. [Environment setup](./testnets/environment-setup.md) + 2. [Pre-genesis validator](./testnets/pre-genesis-validator.md) + 3. [Running your genesis validator](./testnets/run-your-genesis-validator.md) + 4. [Running a full node](./testnets/running-a-full-node.md) + 5. [Becoming a validator post-genesis](./testnets/post-genesis-validator.md) ![testnet_flowchart](../images/testnet_flowchart.png) +## Testnet versions +All public testnets will be listed here: +- Namada public testnet 1: + - Namada protocol version: `v0.12.0` + - Tendermint version: `v0.1.4-abciplus` + - Genesis time: 21st of December 2022 at 17:00 UTC + - CHAIN_ID: `TBD` + ## Block explorer The block explorer is currently in development. The latest version can be found at [namada.world](https://namada.world/) ## Community -We much appreciate any feedback, which we would gladly appreciate through either [Twitter](https://twitter.com/namadanetwork), [Reddit](https://www.reddit.com/r/namada), or [Github](https://github.com/anoma/namada/issues). - -We look forward to seeing you there! \ No newline at end of file +For questions or feedback, feel free to post or comment on [Reddit](https://www.reddit.com/r/namada) or [Github](https://github.com/anoma/namada/issues). Don't forget to [follow Namada](https://twitter.com/namadanetwork) on Twitter for testnet relevant updates. \ No newline at end of file diff --git a/documentation/docs/src/testnets/environment-setup.md b/documentation/docs/src/testnets/environment-setup.md index 3e2467e935..c7f0e902a3 100644 --- a/documentation/docs/src/testnets/environment-setup.md +++ b/documentation/docs/src/testnets/environment-setup.md @@ -1,4 +1,4 @@ -## 1) Environment setup +# 1) Environment setup - Export the following variables: ```bash diff --git a/documentation/docs/src/testnets/gov-masp-devnet-1.md b/documentation/docs/src/testnets/gov-masp-devnet-1.md deleted file mode 100644 index 2e1a517a80..0000000000 --- a/documentation/docs/src/testnets/gov-masp-devnet-1.md +++ /dev/null @@ -1,17 +0,0 @@ -# MASP + Governance devnet - -This devnet contains the following new features: - -- [on-chain governance](../user-guide/ledger/governance.md) - create and vote for proposals both onchain and offchain -- [MASP (multi-asset shielded pool) transfers](../user-guide/ledger/masp.md) - make private transfers of any Namada token - -## Chain information - -Latest values regarding the testnet that would be useful to have in your shell: - -```shell -export NAMADA_CHAIN_ID='namada-gov-masp.3f1b25f2ee35b2e' -export NAMADA_COMMIT='f1afdffd5e43ad4bb448db7bf5bc1e23464350f7' -``` - -You can install Namada by following the instructions from the [Install User Guide](../user-guide/install.md). Note that the binaries should be built from `$NAMADA_COMMIT` rather than `master` or a release tag like `v0.5.0`. diff --git a/documentation/docs/src/testnets/internal-testnet-1.md b/documentation/docs/src/testnets/internal-testnet-1.md deleted file mode 100644 index 4545b843f2..0000000000 --- a/documentation/docs/src/testnets/internal-testnet-1.md +++ /dev/null @@ -1,198 +0,0 @@ -# Internal Testnet 1 - ->⚠️ the values below might change frequently. - -Latest values regarding the testnet that would be useful to have in your shell: - -```shell -export NAMADA_TESTNET_CHAIN_ID='namada-masp-0.3.51d2f83a8412b95' -export NAMADA_TESTNET_BRANCH='internal/testnet-n1' -export NAMADA_TESTNET_COMMIT='0184e64e044366ec370d1431ddf4691b4bd3a5b4' -``` - -## Installing Namada - -You can install Namada by following the instructions from the [Install User Guide](../user-guide/install.md). Note that the binaries should be built from `$NAMADA_TESTNET_BRANCH` rather than `master` or a release tag like `v0.5.0`. - -## Setting up Namada - -At this point, depending on your installation choice, we will assume that the `namada` binaries are available on path and built from the latest testnet branch. - -### Join a network - -To join the current testnet, you need to download the configuration files. This can be done easily with: - -```shell -namadac utils join-network --chain-id $NAMADA_TESTNET_CHAIN_ID -``` - -It should output something like this where the chain id might differ: - -```shell -Downloading config release from https://github.com/heliaxdev/anoma-network-config/releases/download/namada-masp-0.3.51d2f83a8412b95/namada-masp-0.3.51d2f83a8412b95.tar.gz ... -Successfully configured for chain ID namada-masp-0.3.51d2f83a8412b9` -``` - -The above command downloads the folder `.namada` which contains a global config file `global-config.toml`; the genesis file for the specified chain id `{chain-id}.toml` and its corresponding configuration folder `{chain-id}` which contains the checksums for the wasm files under `wasm` and the p2p config `config.toml`. - -### Setup the MASP parameters - -Namada uses a multi-asset shielded pool (MASP) to enable private transfers. The pool relies on three circuits which require each individually their randomly generated parameters to work. - ->⚠️ Normally, the parameters are downloaded through the `masp` crate by the client, but in case of troubles you should get them from someone in the team and follow the instructions below. - - - -The parameters need to be extracted to the correct folder where the node will read the parameters from. - -**Ubuntu** - -```shell -mkdir ~/.masp-params -tar -xvf masp-params.tar.gz ~/.masp-params -``` - -**Mac** - -```shell -mkdir ~/Library/Application\ Support/MASPParams/ -tar -xvf masp-params.tar.gz ~/Library/Application\ Support/MASPParams/ -``` - -### Start a node - -At this point, you are ready to start your Namada node with: - -```shell -namada ledger -``` - -To keep your node running after closing your terminal, you can optionally use a terminal multiplexer like `tmux`. - -## Using Namada - -### Shielded transfers - -Shielded balances are owned by a particular spending key. In this -testnet, spending keys are just arbitrary hexadecimal strings, provided -on the command line. - -To try out shielded transfers, you will first need an ordinary -transparent account with some token balance. Example commands for that: - -``` -namadaw address gen --alias my-implicit -namadac init-account --source my-implicit --public-key my-implicit --alias my-established -namadac transfer --token btc --amount 1000 --source faucet --target my-established --signer my-established -``` - -The testnet tokens which the faucet can provide you are named `NAM`, -`BTC`, `ETH`, `DOT`, `Schnitzel`, `Apfel`, and `Kartoffel`. The faucet -will transfer these in increments of 1000 at a time. - -Once you have an ordinary transparent account with some tokens, you -should select a spending key to hold your shielded balances. This is -just some hexadecimal string, like `1234`, `abcd`, or -`030cdcc0a43765d4645e22adbf9944b58c646d162c9a08890a08cc49a9580c9e`. Try -to select one that is unique to you (i.e., probably don't use `1234`); -you could randomly generate one with e.g. `openssl rand -hex 32`. The -wallet does not yet support spending keys, so make a note of yours -somewhere. - -Shielded transfers work with the `namadac transfer` command, but either -`--source`, `--target`, or both are replaced. `--source` may be replaced -with `--spending-key` to spend a shielded balance, but if you are -following along, you don't have a shielded balance to spend yet. -`--target` may be replaced with `--payment-address` to create a shielded -balance. - -To create a payment address from your spending key, use: - -```shell -namadaw masp gen-payment-addr --spending-key [your spending key] -``` - -This will generate a different payment address each time you run it. -Payment addresses can be reused or discarded as you like, and can't be -correlated with one another. - -Once you have a payment address, transfer a balance from your -transparent account to your shielded spending key with something like: - -```shell -namadac transfer --source my-established --payment-address [your payment address] --token btc --amount 100 -``` - -Once this transfer goes through, you can view your spending key's -balance: - -```shell -namadac balance --spending-key [your spending key] -``` - -However, your spending key is the secret key to all your shielded -balances, and you may not want to use it just to view balances. For this -purpose, you can derive the viewing key: - -```shell -namadaw masp derive-view-key --spending-key [your spending key] -namadac balance --viewing-key [your viewing key] -``` - -The viewing key can also be used to generate payment addresses, with -e.g. `namadaw masp gen-payment-addr --viewing-key [your viewing key]`. - -Now that you have a shielded balance, it can either be transferred to a -different shielded payment address (shielded to shielded): - -```shell -namadac transfer --spending-key [your spending key] --payment-address [someone's payment address] --token btc --amount 50 --signer my-established -``` - -or to a transparent account (shielded to transparent): - -```shell -namadac transfer --spending-key [your spending key] --target [some transparent account] --token btc --amount 50 --signer my-established -``` - -Note that for both of these types of transfer, `--signer` must be -specified. However, any transparent account can sign these transactions. - -## Troubleshooting - -### Build from Source - -Build the provided validity predicate and transaction wasm modules - -```shell -make build-wasm-scripts-docker -``` - -### Node is not starting - -**"No state could be found"** - -If you get the following log, it means that Tendermint is not installed properly on your machine or not available on path. To solve this issue, install Tendermint by following the [Install User Guide](../user-guide/install.md). - -```shell -2022-03-30T07:21:09.212187Z INFO namada_apps::cli::context: Chain ID: namada-masp-0.3.51d2f83a8412b95 -2022-03-30T07:21:09.213968Z INFO namada_apps::node::ledger: Available logical cores: 8 -2022-03-30T07:21:09.213989Z INFO namada_apps::node::ledger: Using 4 threads for Rayon. -2022-03-30T07:21:09.213994Z INFO namada_apps::node::ledger: Using 4 threads for Tokio. -2022-03-30T07:21:09.217867Z INFO namada_apps::node::ledger: VP WASM compilation cache size not configured, using 1/6 of available memory. -2022-03-30T07:21:09.218908Z INFO namada_apps::node::ledger: Available memory: 15.18 GiB -2022-03-30T07:21:09.218934Z INFO namada_apps::node::ledger: VP WASM compilation cache size: 2.53 GiB -2022-03-30T07:21:09.218943Z INFO namada_apps::node::ledger: Tx WASM compilation cache size not configured, using 1/6 of available memory. -2022-03-30T07:21:09.218947Z INFO namada_apps::node::ledger: Tx WASM compilation cache size: 2.53 GiB -2022-03-30T07:21:09.218954Z INFO namada_apps::node::ledger: Block cache size not configured, using 1/3 of available memory. -2022-03-30T07:21:09.218959Z INFO namada_apps::node::ledger: RocksDB block cache size: 5.06 GiB -2022-03-30T07:21:09.218996Z INFO namada_apps::node::ledger::storage::rocksdb: Using 2 compactions threads for RocksDB. -2022-03-30T07:21:09.219196Z INFO namada_apps::node::ledger: Tendermint node is no longer running. -2022-03-30T07:21:09.232544Z INFO namada::ledger::storage: No state could be found -2022-03-30T07:21:09.232709Z INFO namada_apps::node::ledger: Tendermint has exited, shutting down... -2022-03-30T07:21:09.232794Z INFO namada_apps::node::ledger: Namada ledger node started. -2022-03-30T07:21:09.232849Z INFO namada_apps::node::ledger: Namada ledger node has shut down. -``` diff --git a/documentation/docs/src/testnets/pre-genesis-validator.md b/documentation/docs/src/testnets/pre-genesis-validator.md index f5f2cd03b9..e21b58056a 100644 --- a/documentation/docs/src/testnets/pre-genesis-validator.md +++ b/documentation/docs/src/testnets/pre-genesis-validator.md @@ -1,4 +1,4 @@ -## 2) Generate pre-genesis validator setup +# 2) Generate pre-genesis validator setup - Create a pre-genesis file inside the `namada` repository. - diff --git a/documentation/docs/src/testnets/run-your-genesis-validator.md b/documentation/docs/src/testnets/run-your-genesis-validator.md index 9d7aaddf4c..863aecc664 100644 --- a/documentation/docs/src/testnets/run-your-genesis-validator.md +++ b/documentation/docs/src/testnets/run-your-genesis-validator.md @@ -1,4 +1,4 @@ -## 3) MANDATORY: Reset your validator node +# 3) MANDATORY: Reset your validator node - You can skip to 3.1 if you don't need to reset the ledger state - This is the right time to save any logs file you want to share with us! - Save your `pre-genesis` folder in the ledger base directory From 1e8525e48f0d7b2f45ea1bf6baa44637b5d9f6ee Mon Sep 17 00:00:00 2001 From: Awa Sun Yin Date: Fri, 16 Dec 2022 14:39:04 +0100 Subject: [PATCH 023/166] reviewed all sections in joining a testnet --- documentation/docs/src/testnets/README.md | 1 - documentation/docs/src/testnets/environment-setup.md | 10 +++++++++- .../docs/src/testnets/pre-genesis-validator.md | 6 +++--- .../docs/src/testnets/run-your-genesis-validator.md | 4 ++-- documentation/docs/src/testnets/running-a-full-node.md | 2 +- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/documentation/docs/src/testnets/README.md b/documentation/docs/src/testnets/README.md index 32a2f9d117..ac6a9ff64a 100644 --- a/documentation/docs/src/testnets/README.md +++ b/documentation/docs/src/testnets/README.md @@ -17,7 +17,6 @@ If you found a bug, please submit an issue with the `bug` [issue template](https 3. [Running your genesis validator](./testnets/run-your-genesis-validator.md) 4. [Running a full node](./testnets/running-a-full-node.md) 5. [Becoming a validator post-genesis](./testnets/post-genesis-validator.md) - ![testnet_flowchart](../images/testnet_flowchart.png) ## Testnet versions diff --git a/documentation/docs/src/testnets/environment-setup.md b/documentation/docs/src/testnets/environment-setup.md index c7f0e902a3..358cf016b1 100644 --- a/documentation/docs/src/testnets/environment-setup.md +++ b/documentation/docs/src/testnets/environment-setup.md @@ -2,9 +2,11 @@ - Export the following variables: ```bash - export NAMADA_TAG=v0.11.0 + export NAMADA_TAG=v0.12.0 export TM_HASH=v0.1.4-abciplus ``` + +## Installing Namada - Clone namada repository and build binaries ```bash git clone https://github.com/anoma/namada && cd namada && git checkout $NAMADA_TAG @@ -17,6 +19,8 @@ sudo apt-get install build-essential make pkg-config libssl-dev libclang-dev -y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` + +## Installing Tendermint - Install the heliaxdev/tendermint fork ```bash git clone https://github.com/heliaxdev/tendermint && cd tendermint && git checkout $TM_HASH @@ -29,6 +33,8 @@ - This step may or may not be necessary - namada binaries can be found in `/target/release` - tendermint is in `build/tendermint` + +## Check ports - Open ports on your machine: - 26656 - 26657 @@ -40,6 +46,8 @@ - From another host run one of the two commands: - `nmap $IP -p$PORT` - `curl $IP:$PORT >/dev/null` + +## Verifying your installation - Make sure you are using the correct tendermint version - `tendermint version` should output `0.1.4-abciplus` - Make sure you are using the correct Namada version diff --git a/documentation/docs/src/testnets/pre-genesis-validator.md b/documentation/docs/src/testnets/pre-genesis-validator.md index e21b58056a..85465cd4fb 100644 --- a/documentation/docs/src/testnets/pre-genesis-validator.md +++ b/documentation/docs/src/testnets/pre-genesis-validator.md @@ -13,7 +13,7 @@ - `cat namada/.namada/pre-genesis/$ALIAS/validator.toml` ## 2.1) Submitting the config -If you want to be a genesis validator for the testnet, please make a pull request to https://github.com/anoma/namada-testnets adding your validator.toml file to the relevant directory (e.g. `namada-close-quarters-testnet-5` for the `namada-cq-5` testnet), renaming it to `$alias.toml`. e.g. if you chose your alias to be "bertha", submit the file with the name `bertha.toml`. You can see what an example PR looks like [here](https://github.com/anoma/namada-testnets/pull/29). +If you want to be a genesis validator for the testnet, please make a pull request to https://github.com/anoma/namada-testnets adding your validator.toml file to the relevant directory (e.g. `namada-public-testnet-1` for the public testnet 1), renaming it to `$alias.toml`. e.g. if you chose your alias to be "bertha", submit the file with the name `bertha.toml`. You can see what an example PR looks like [here](https://github.com/anoma/namada-testnets/pull/29). -## 2.2) Wait for launch -Wait until the testnet is launched and a `CHAIN_ID` has been distributed. +## 2.2) Wait for the CHAIN_ID +Wait until corresponding `CHAIN_ID` has been distributed. diff --git a/documentation/docs/src/testnets/run-your-genesis-validator.md b/documentation/docs/src/testnets/run-your-genesis-validator.md index 863aecc664..6adf2d164a 100644 --- a/documentation/docs/src/testnets/run-your-genesis-validator.md +++ b/documentation/docs/src/testnets/run-your-genesis-validator.md @@ -1,5 +1,5 @@ # 3) MANDATORY: Reset your validator node -- You can skip to 3.1 if you don't need to reset the ledger state +- **You can skip to 3.1 if you don't need to reset the ledger state** - This is the right time to save any logs file you want to share with us! - Save your `pre-genesis` folder in the ledger base directory - `mkdir backup-pregenesis && cp -r .anoma/pre-genesis backup-pregenesis/` @@ -31,7 +31,7 @@ With the new update, the folder will be located in the `.namada` folder rather t - Wait for the genesis file to be ready, `CHAIN_ID`. - Join the network with the `CHAIN_ID` ``` bash - export CHAIN_ID="qc-testnet-5.1.025a61165acd05e" + export CHAIN_ID="TBD" namada client utils join-network \ --chain-id $CHAIN_ID --genesis-validator $ALIAS ``` diff --git a/documentation/docs/src/testnets/running-a-full-node.md b/documentation/docs/src/testnets/running-a-full-node.md index 5e1fbc9dff..b8948f922a 100644 --- a/documentation/docs/src/testnets/running-a-full-node.md +++ b/documentation/docs/src/testnets/running-a-full-node.md @@ -2,7 +2,7 @@ - Wait for the genesis file to be ready, you will receive a `$CHAIN_ID`. - Join the network with the `CHAIN_ID` ```bash - export CHAIN_ID="qc-testnet-5.1.025a61165acd05e" + export CHAIN_ID="TBD" namada client utils join-network --chain-id $CHAIN_ID ``` - Start your node and sync From fec48ba27f6e6179bca8c4cbd47dc1ea552c77a4 Mon Sep 17 00:00:00 2001 From: Bengt Date: Fri, 16 Dec 2022 13:40:52 +0000 Subject: [PATCH 024/166] ammended gians comments --- documentation/docs/src/user-guide/install.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/src/user-guide/install.md b/documentation/docs/src/user-guide/install.md index 903d1611ff..52b2ff4b87 100644 --- a/documentation/docs/src/user-guide/install.md +++ b/documentation/docs/src/user-guide/install.md @@ -94,4 +94,4 @@ Now, that you have all dependencies installed you can download the latest binary ## From Docker -The docker image can be found [here](https://github.com/anoma/namada/pkgs/container/namada) +You can find the Namada docker image [here](https://github.com/anoma/namada/pkgs/container/namada) From 1be3c02f61e9884cab962a7b514023dba8f8e8f1 Mon Sep 17 00:00:00 2001 From: Bengt Date: Fri, 16 Dec 2022 15:14:31 +0000 Subject: [PATCH 025/166] fixed compile error --- documentation/docs/src/SUMMARY.md | 24 +-- documentation/docs/src/testnets/README.md | 14 +- .../testnets/run-your-genesis-validator.md | 2 +- .../{install.md => install/README.md} | 0 .../src/user-guide/install/from-binary.md | 27 +++ .../src/user-guide/install/from-docker.md | 3 + .../src/user-guide/install/from-source.md | 39 +++++ .../docs/src/user-guide/install/hardware.md | 11 ++ documentation/docs/src/user-guide/ledger.md | 2 +- documentation/docs/src/user-guide/wallet.md | 158 ------------------ .../docs/src/user-guide/wallet/README.md | 13 ++ .../an-introduction-to-namada-addresses.md | 64 +++++++ .../user-guide/wallet/file-system-wallet.md | 11 ++ .../src/user-guide/wallet/hardware-wallet.md | 3 + .../src/user-guide/wallet/paper-wallet.md | 3 + .../wallet/send-and-receive-nam-tokens.md | 55 ++++++ .../docs/src/user-guide/wallet/web-wallet.md | 3 + 17 files changed, 253 insertions(+), 179 deletions(-) rename documentation/docs/src/user-guide/{install.md => install/README.md} (100%) create mode 100644 documentation/docs/src/user-guide/install/from-binary.md create mode 100644 documentation/docs/src/user-guide/install/from-docker.md create mode 100644 documentation/docs/src/user-guide/install/from-source.md create mode 100644 documentation/docs/src/user-guide/install/hardware.md delete mode 100644 documentation/docs/src/user-guide/wallet.md create mode 100644 documentation/docs/src/user-guide/wallet/README.md create mode 100644 documentation/docs/src/user-guide/wallet/an-introduction-to-namada-addresses.md create mode 100644 documentation/docs/src/user-guide/wallet/file-system-wallet.md create mode 100644 documentation/docs/src/user-guide/wallet/hardware-wallet.md create mode 100644 documentation/docs/src/user-guide/wallet/paper-wallet.md create mode 100644 documentation/docs/src/user-guide/wallet/send-and-receive-nam-tokens.md create mode 100644 documentation/docs/src/user-guide/wallet/web-wallet.md diff --git a/documentation/docs/src/SUMMARY.md b/documentation/docs/src/SUMMARY.md index 40e169cabe..80763182b2 100644 --- a/documentation/docs/src/SUMMARY.md +++ b/documentation/docs/src/SUMMARY.md @@ -3,20 +3,20 @@ - [Introduction](./README.md) - [Quickstart](./quick-start.md) - [User guide](./user-guide/README.md) - - [Installing Namada](./user-guide/install.md) - - [Hardware requirements](./user-guide/install.md#hardware-requirements) - - [From source](./user-guide/install.md#from-source) - - [From binaries](./user-guide/install.md#from-binaries) - - [From docker](./user-guide/install.md#from-docker) + - [Installing Namada](./user-guide/install/README.md) + - [Hardware requirements](./user-guide/install/hardware.md) + - [From source](./user-guide/install/from-source.md) + - [From binaries](./user-guide/install/from-binary.md) + - [From docker](./user-guide/install/from-docker.md) - [Overview of binaries](./user-guide/overview-of-binaries.md) - [The Ledger](./user-guide/ledger.md) - - [Wallet guide](./user-guide/wallet.md) - - [Namada addresses](./user-guide/wallet.md#an-introduction-to-namada-addresses) - - [File system wallet](./user-guide/wallet.md#file-system-wallet) - - [Web wallet](./user-guide/wallet.md#web-wallet) - - [Paper wallet](./user-guide/wallet.md#paper-wallet) - - [Hardware wallet](./user-guide/wallet.md#hardware-wallet) - - [Sending and receiving NAM](./user-guide/wallet.md#send-and-receive-nam-tokens) + - [Wallet guide](./user-guide/wallet/README.md) + - [Namada addresses](./user-guide/wallet/an-introduction-to-namada-addresses.md) + - [File system wallet](./user-guide/wallet/file-system-wallet.md) + - [Web wallet](./user-guide/wallet/web-wallet.md) + - [Paper wallet](./user-guide/wallet/paper-wallet.md) + - [Hardware wallet](./user-guide/wallet/hardware-wallet.md) + - [Sending and receiving NAM](./user-guide/wallet/send-and-receive-nam-tokens.md) - [Shielded transfers](./user-guide/ledger/masp.md) - [Interacting with PoS](./user-guide/ledger/pos.md) - [Staking](./user-guide/ledger/staking.md) diff --git a/documentation/docs/src/testnets/README.md b/documentation/docs/src/testnets/README.md index ac6a9ff64a..dc8b89bcba 100644 --- a/documentation/docs/src/testnets/README.md +++ b/documentation/docs/src/testnets/README.md @@ -5,18 +5,18 @@ For more context read: ## Namada protocol versions -A testnet might deploy different versions of the Namada protocol. To see in-detail what each protocol version includes, refer to the [Github changelog](https://github.com/anoma/namada/tree/main/.changelog), which specify what changes have been made in between versions. +A testnet might deploy different versions of the Namada protocol. To see in-detail what each protocol version includes, refer to the [Github changelog](https://github.com/anoma/namada/tree/main/.changelog), which specifies what changes have been made in between versions. ## Report a bug -If you found a bug, please submit an issue with the `bug` [issue template](https://github.com/anoma/namada/issues/new/choose). +If you find a bug, please submit an issue with the `bug` [issue template](https://github.com/anoma/namada/issues/new/choose). ## How to join a Namada testnet - 1. [Environment setup](./testnets/environment-setup.md) - 2. [Pre-genesis validator](./testnets/pre-genesis-validator.md) - 3. [Running your genesis validator](./testnets/run-your-genesis-validator.md) - 4. [Running a full node](./testnets/running-a-full-node.md) - 5. [Becoming a validator post-genesis](./testnets/post-genesis-validator.md) + 1. [Environment setup](./environment-setup.md) + 2. [Pre-genesis validator](./pre-genesis-validator.md) + 3. [Running your genesis validator](./run-your-genesis-validator.md) + 4. [Running a full node](./running-a-full-node.md) + 5. [Becoming a validator post-genesis](./post-genesis-validator.md) ![testnet_flowchart](../images/testnet_flowchart.png) ## Testnet versions diff --git a/documentation/docs/src/testnets/run-your-genesis-validator.md b/documentation/docs/src/testnets/run-your-genesis-validator.md index 6adf2d164a..ccf0c1d314 100644 --- a/documentation/docs/src/testnets/run-your-genesis-validator.md +++ b/documentation/docs/src/testnets/run-your-genesis-validator.md @@ -3,7 +3,7 @@ - This is the right time to save any logs file you want to share with us! - Save your `pre-genesis` folder in the ledger base directory - `mkdir backup-pregenesis && cp -r .anoma/pre-genesis backup-pregenesis/` -- Delete ledger base directory **[WARNING: THIS WILL ALSO DELETE YOUR VALIDATOR KEYS, DO NOT RUN UNLESS YOU'VE BACKED IT UP]** +- Delete ledger base directory **(WARNING: THIS WILL ALSO DELETE YOUR VALIDATOR KEYS, DO NOT RUN UNLESS YOU'VE BACKED IT UP)** - `rm -rf .anoma` - Check that namada and tendermint binaries are correct (see step 1) - If you have you are a genesis validator from the previous testnet continue with the instructions below otherwise go to step `3.1` diff --git a/documentation/docs/src/user-guide/install.md b/documentation/docs/src/user-guide/install/README.md similarity index 100% rename from documentation/docs/src/user-guide/install.md rename to documentation/docs/src/user-guide/install/README.md diff --git a/documentation/docs/src/user-guide/install/from-binary.md b/documentation/docs/src/user-guide/install/from-binary.md new file mode 100644 index 0000000000..05b9155fed --- /dev/null +++ b/documentation/docs/src/user-guide/install/from-binary.md @@ -0,0 +1,27 @@ +## From Binaries + +```admonish warning +Prebuilt binaries might not be available for a specific release or architecture, in this case you have to [build from source](#from-source). +``` + +If you'd like to install Namada from binaries you will have to install some dependencies first: [Tendermint](https://docs.tendermint.com/master/introduction/install.html) `0.34.x` and GLIBC `v2.29` or higher. + +Let's install Tendermint. + +You can either follow the instructions on the [Tendermint guide](https://docs.tendermint.com/master/introduction/install.html) or download the `get_tendermint.sh` script from the [Namada repository](https://github.com/anoma/namada/blob/master/scripts/install/get_tendermint.sh) and execute it (will ask you for `root` access): + +```shell +curl -LO https://raw.githubusercontent.com/namada/namada/main/scripts/install/get_tendermint.sh +chmod +x get_tendermint.sh +./get_tendermint.sh +``` + +Finally, you should have GLIBC `v2.29` or higher. + +**MacOS**: the system-provided glibc should be recent enough. + +**Ubuntu 20.04**: this is installed by default and you don't have to do anything more. + +**Ubuntu 18.04**: glibc has `v2.27` by default which is lower than the required version to run Namada. We recommend to directly [install from source](#from-source) or upgrade to Ubuntu 19.04, instead of updating glibc to the required version, since the latter way can be a messy and tedious task. In case, updating glibc would interest you this [website](http://www.linuxfromscratch.org/lfs/view/9.0-systemd/chapter05/glibc.html) gives you the steps to build the package from source. + +Now, that you have all dependencies installed you can download the latest binary release from our [releases page](https://github.com/anoma/namada/releases) by choosing the appropriate architecture. \ No newline at end of file diff --git a/documentation/docs/src/user-guide/install/from-docker.md b/documentation/docs/src/user-guide/install/from-docker.md new file mode 100644 index 0000000000..d4b2febbc5 --- /dev/null +++ b/documentation/docs/src/user-guide/install/from-docker.md @@ -0,0 +1,3 @@ +## From Docker + +Go to [heliaxdev dockerhub account](https://hub.docker.com/r/heliaxdev/namada) and pull the image. \ No newline at end of file diff --git a/documentation/docs/src/user-guide/install/from-source.md b/documentation/docs/src/user-guide/install/from-source.md new file mode 100644 index 0000000000..8736afff26 --- /dev/null +++ b/documentation/docs/src/user-guide/install/from-source.md @@ -0,0 +1,39 @@ +## From Source + +If you'd like to install Namada from source you will have to install some dependencies first: [Rust](https://www.rust-lang.org/tools/install), [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git), Clang, OpenSSL and LLVM. + +First, [install Rust](https://www.rust-lang.org/tools/install) by following the instructions from the official page. + +At the end of the installation, make sure that Cargo's bin directory ($HOME/.cargo/bin) is available on your PATH environment variable. You can either restart your shell or run `source $HOME/.cargo/env` to continue. + +If you already have Rust installed, make sure you're using the latest version by running: + +```shell +rustup update +``` + +Then, install the remaining dependencies. + +**Ubuntu:** running the following command should install everything needed: + +```shell +sudo apt-get install -y make git-core libssl-dev pkg-config libclang-12-dev build-essential +``` + +**Mac:** installing the Xcode command line tools should provide you with almost everything you need: + +```shell +xcode-select --install +``` + +Now, that you have all dependencies installed you can clone the source code from the [Namada repository](https://github.com/anoma/namada) and build it with: + +```admonish warning +During internal and private testnets, checkout the latest testnet branch using `git checkout $NAMADA_TESTNET_BRANCH`. +``` + +```shell +git clone https://github.com/anoma/namada.git +cd namada +make install +``` \ No newline at end of file diff --git a/documentation/docs/src/user-guide/install/hardware.md b/documentation/docs/src/user-guide/install/hardware.md new file mode 100644 index 0000000000..176c82be46 --- /dev/null +++ b/documentation/docs/src/user-guide/install/hardware.md @@ -0,0 +1,11 @@ +## Hardware Requirements + +This section covers the minimum and recommended hardware requirements for engaging with Namada as a validator node. + +### Minimal Hardware Requirements + +| Hardware | Minimal Specifications | +| -------- | -------- | +| CPU | x86_64 or arm64 processor with at least 4 physical cores | +| RAM | 16GB DDR4 | +| Storage | at least 60GB SSD (NVMe SSD is recommended. HDD will be enough for localnet only) | \ No newline at end of file diff --git a/documentation/docs/src/user-guide/ledger.md b/documentation/docs/src/user-guide/ledger.md index 4de7d67d72..bd02ff6e77 100644 --- a/documentation/docs/src/user-guide/ledger.md +++ b/documentation/docs/src/user-guide/ledger.md @@ -6,7 +6,7 @@ To start a local Namada ledger node, run: namada ledger ``` -> Note: You need to have [joined a network](./getting-started.md) before you start the ledger. It throws an error if no network has been configured. +> Note: You need to have [joined a network](../quick-start.md) before you start the ledger. It throws an error if no network has been configured. The node will attempt to connect to the persistent validator nodes and other peers in the network, and synchronize to the latest block. diff --git a/documentation/docs/src/user-guide/wallet.md b/documentation/docs/src/user-guide/wallet.md deleted file mode 100644 index 8095ab596f..0000000000 --- a/documentation/docs/src/user-guide/wallet.md +++ /dev/null @@ -1,158 +0,0 @@ -# Namada Wallet Guide - -This document describes the different wallet concepts and options that are available to users of Namada who want to be able to [send, receive and interact](#send-and-receive-nam-tokens) with NAM tokens on the Namada blockchain. - - - - -Check out the different options to generate a wallet: - -- [File System Wallet](#file-system-wallet) -- [Web Wallet](#web-wallet) -- [Paper Wallet](#paper-wallet) -- [Hardware Wallet](#hardware-wallet) - -## An introduction to Namada Addresses -The purpose of the Namada wallet is to provide a user-interface to store and manage both keys and addresses. In this context, keys are (potentially) very large integers that have some meaning on an eliptic curve. Keys are the fundamental building blocks for accounts on Namada. Keys come in the form of *pairs* (secret and public), can be used to derive the **account address** (first 40 chars of the SHA256 hash of the public key). - - -All accounts in Namada have a unique address, exactly one Validity Predicate and optionally any additional data in its dynamic storage sub-space. - -There are currently 3 types of account addresses: -- **Implicit *(not fully supported yet)*:** An implicit account is derived from your keypair and can be used to authorize certain transactions from the account. They can be used as recipients of transactions even if the account has not been used on-chain before. -- **Established:** Used for accounts that allow the deployment of custom validation logic. These must be created on-chain via a transaction (e.g. [initialize an account](#initialize-an-established-account)). The address is generated on-chain and is not known until the transaction is applied (the user provides randomness). -- **Internal:** Special internal accounts, such as protocol parameters account, PoS and IBC. - -## Manage keypairs - -Namada uses [ed25519](https://en.wikipedia.org/wiki/EdDSA#Ed25519) keypairs for signing cryptographic operations on the blockchain. - -To manage your keys, various sub-commands are available under: - -```shell -namada wallet key -``` - -### Generate a keypair - -It is possible to generate keys using the CLI. By doing so, an implicit account address is also derived in the process and added to storage. - -```shell -namada wallet key gen --alias my-key -``` - -```admonish note -The derived implicit address shares the same `my-key` alias. The previous command has the same effect as `namada wallet address gen --alias my-key`. -``` - -### List all known keys - -```shell -namada wallet key list -``` - -## Manage addresses - - -To manage addresses, similar to keys, various sub-commands are available: - -```shell -namada wallet address -``` - -### Generate an implicit address - -```shell -namada wallet address gen --alias my-account -``` - -```admonish note - -Note that this will also generate and save a key from which the address was derived and save it under the same `my-account` alias. Thus, this command has the same effect as `namada wallet key gen --alias my-account`. -``` - -### List all known addresses - -```shell -namada wallet address list -``` - -## File System Wallet - -By default, the Namada Wallet is stored under `.namada/{chain_id}/wallet.toml` where keys are stored encrypted. You can change the default base directory path with `--base-dir` and you can allow the storage of unencrypted keypairs with the flag `--unsafe-dont-encrypt`. - -If the wallet doesn't already exist, it will be created for you as soon as you run a command that tries to access the wallet. A newly created wallet will be pre-loaded with some internal addresses like `pos`, `pos_slash_pool`, `masp` and more. - -Currently, the Namada client can load the password via: - -- **Stdin:** the client will prompt for a password. -- **Env variable:** by exporting a ENV variable called `NAMADA_WALLET_PASSWORD` with value of the actual password. -- **File:** by exporting an ENV variable called `NAMADA_WALLET_PASSWORD_FILE` with value containing the path to a file containing the password. - -## Web Wallet - -The Web Wallet for Namada is currently in closed beta. - -## Paper Wallet - -At the moment, the Namada CLI doesn't provide a Paper Wallet. - -## Hardware Wallet - -The Ledger Hardware Wallet is currently in development. - -## Send and Receive NAM tokens - -In Namada, tokens are implemented as accounts with the [Token Validity Predicate](https://github.com/anoma/namada/blob/namada/wasm/wasm_source/src/vp_token.rs). It checks that its total supply is preserved in any transaction that uses this token. Your wallet will be pre-loaded with some token addresses that are initialized in the genesis block. - -### Initialize an established account - -If you already have a key in your wallet, you can skip this step. Otherwise, [generate a new keypair](#generate-a-keypair) now. - -Then, send a transaction to initialize your new established account and save its address with the alias `my-new-acc`. The `my-key` public key will be written into the account's storage for authorizing future transactions. We also sign this transaction with `my-key`. - -```shell -namada client init-account \ - --alias my-new-acc \ - --public-key my-key \ - --source my-key -``` - -Once this transaction has been applied, the client will automatically see the new address created by the transaction and add it to your Wallet with the chosen alias `my-new-acc`. - -This command uses the prebuilt [User Validity Predicate](https://github.com/anoma/namada/blob/namada/wasm/wasm_source/src/vp_user.rs). - -### Send a Payment - -To submit a regular token transfer from your account to the `validator-1` address: - -```shell -namada client transfer \ - --source my-new-acc \ - --target validator-1 \ - --token NAM \ - --amount 10 -``` - -This command will attempt to find and use the key of the source address to sign the transaction. - -### See your balance - -To query token balances for a specific token and/or owner: - -```shell -namada client balance --token NAM --owner my-new-acc -``` - -```admonish note -For any client command that submits a transaction (`init-account`, `transfer`, `tx`, `update` and [PoS transactions](ledger/pos.md)), you can use the `--dry-run` flag to simulate the transaction being applied in the block and see what would be the result. - -``` - -### See every known addresses' balance - -You can see the token's addresses known by the client when you query all tokens balances: - -```shell -namada client balance -``` diff --git a/documentation/docs/src/user-guide/wallet/README.md b/documentation/docs/src/user-guide/wallet/README.md new file mode 100644 index 0000000000..ea76e076c8 --- /dev/null +++ b/documentation/docs/src/user-guide/wallet/README.md @@ -0,0 +1,13 @@ +# Namada Wallet Guide + +This document describes the different wallet concepts and options that are available to users of Namada who want to be able to [send, receive and interact](#send-and-receive-nam-tokens) with NAM tokens on the Namada blockchain. + + + + +Check out the different options to generate a wallet: + +- [File System Wallet](./file-system-wallet.md) +- [Web Wallet](./web-wallet.md) +- [Paper Wallet](./paper-wallet.md) +- [Hardware Wallet](./hardware-wallet.md) diff --git a/documentation/docs/src/user-guide/wallet/an-introduction-to-namada-addresses.md b/documentation/docs/src/user-guide/wallet/an-introduction-to-namada-addresses.md new file mode 100644 index 0000000000..755f9a05ef --- /dev/null +++ b/documentation/docs/src/user-guide/wallet/an-introduction-to-namada-addresses.md @@ -0,0 +1,64 @@ +# An introduction to Namada Addresses +The purpose of the Namada wallet is to provide a user-interface to store and manage both keys and addresses. In this context, keys are (potentially) very large integers that have some meaning on an eliptic curve. Keys are the fundamental building blocks for accounts on Namada. Keys come in the form of *pairs* (secret and public), can be used to derive the **account address** (first 40 chars of the SHA256 hash of the public key). + + +All accounts in Namada have a unique address, exactly one Validity Predicate and optionally any additional data in its dynamic storage sub-space. + +There are currently 3 types of account addresses: +- **Implicit *(not fully supported yet)*:** An implicit account is derived from your keypair and can be used to authorize certain transactions from the account. They can be used as recipients of transactions even if the account has not been used on-chain before. +- **Established:** Used for accounts that allow the deployment of custom validation logic. These must be created on-chain via a transaction (e.g. [initialize an account](#initialize-an-established-account)). The address is generated on-chain and is not known until the transaction is applied (the user provides randomness). +- **Internal:** Special internal accounts, such as protocol parameters account, PoS and IBC. + +## Manage keypairs + +Namada uses [ed25519](https://en.wikipedia.org/wiki/EdDSA#Ed25519) keypairs for signing cryptographic operations on the blockchain. + +To manage your keys, various sub-commands are available under: + +```shell +namada wallet key +``` + +### Generate a keypair + +It is possible to generate keys using the CLI. By doing so, an implicit account address is also derived in the process and added to storage. + +```shell +namada wallet key gen --alias my-key +``` + +```admonish note +The derived implicit address shares the same `my-key` alias. The previous command has the same effect as `namada wallet address gen --alias my-key`. +``` + +### List all known keys + +```shell +namada wallet key list +``` + +## Manage addresses + + +To manage addresses, similar to keys, various sub-commands are available: + +```shell +namada wallet address +``` + +### Generate an implicit address + +```shell +namada wallet address gen --alias my-account +``` + +```admonish note + +Note that this will also generate and save a key from which the address was derived and save it under the same `my-account` alias. Thus, this command has the same effect as `namada wallet key gen --alias my-account`. +``` + +### List all known addresses + +```shell +namada wallet address list +``` \ No newline at end of file diff --git a/documentation/docs/src/user-guide/wallet/file-system-wallet.md b/documentation/docs/src/user-guide/wallet/file-system-wallet.md new file mode 100644 index 0000000000..0398d79bab --- /dev/null +++ b/documentation/docs/src/user-guide/wallet/file-system-wallet.md @@ -0,0 +1,11 @@ +## File System Wallet + +By default, the Namada Wallet is stored under `.namada/{chain_id}/wallet.toml` where keys are stored encrypted. You can change the default base directory path with `--base-dir` and you can allow the storage of unencrypted keypairs with the flag `--unsafe-dont-encrypt`. + +If the wallet doesn't already exist, it will be created for you as soon as you run a command that tries to access the wallet. A newly created wallet will be pre-loaded with some internal addresses like `pos`, `pos_slash_pool`, `masp` and more. + +Currently, the Namada client can load the password via: + +- **Stdin:** the client will prompt for a password. +- **Env variable:** by exporting a ENV variable called `NAMADA_WALLET_PASSWORD` with value of the actual password. +- **File:** by exporting an ENV variable called `NAMADA_WALLET_PASSWORD_FILE` with value containing the path to a file containing the password. \ No newline at end of file diff --git a/documentation/docs/src/user-guide/wallet/hardware-wallet.md b/documentation/docs/src/user-guide/wallet/hardware-wallet.md new file mode 100644 index 0000000000..1cd84c481e --- /dev/null +++ b/documentation/docs/src/user-guide/wallet/hardware-wallet.md @@ -0,0 +1,3 @@ +## Hardware Wallet + +The Ledger Hardware Wallet is currently in development. \ No newline at end of file diff --git a/documentation/docs/src/user-guide/wallet/paper-wallet.md b/documentation/docs/src/user-guide/wallet/paper-wallet.md new file mode 100644 index 0000000000..34fe8afd17 --- /dev/null +++ b/documentation/docs/src/user-guide/wallet/paper-wallet.md @@ -0,0 +1,3 @@ +## Paper Wallet + +At the moment, the Namada CLI doesn't provide a Paper Wallet. \ No newline at end of file diff --git a/documentation/docs/src/user-guide/wallet/send-and-receive-nam-tokens.md b/documentation/docs/src/user-guide/wallet/send-and-receive-nam-tokens.md new file mode 100644 index 0000000000..0fef910baa --- /dev/null +++ b/documentation/docs/src/user-guide/wallet/send-and-receive-nam-tokens.md @@ -0,0 +1,55 @@ +## Send and Receive NAM tokens + +In Namada, tokens are implemented as accounts with the [Token Validity Predicate](https://github.com/anoma/namada/blob/namada/wasm/wasm_source/src/vp_token.rs). It checks that its total supply is preserved in any transaction that uses this token. Your wallet will be pre-loaded with some token addresses that are initialized in the genesis block. + +### Initialize an established account + +If you already have a key in your wallet, you can skip this step. Otherwise, [generate a new keypair](#generate-a-keypair) now. + +Then, send a transaction to initialize your new established account and save its address with the alias `my-new-acc`. The `my-key` public key will be written into the account's storage for authorizing future transactions. We also sign this transaction with `my-key`. + +```shell +namada client init-account \ + --alias my-new-acc \ + --public-key my-key \ + --source my-key +``` + +Once this transaction has been applied, the client will automatically see the new address created by the transaction and add it to your Wallet with the chosen alias `my-new-acc`. + +This command uses the prebuilt [User Validity Predicate](https://github.com/anoma/namada/blob/namada/wasm/wasm_source/src/vp_user.rs). + +### Send a Payment + +To submit a regular token transfer from your account to the `validator-1` address: + +```shell +namada client transfer \ + --source my-new-acc \ + --target validator-1 \ + --token NAM \ + --amount 10 +``` + +This command will attempt to find and use the key of the source address to sign the transaction. + +### See your balance + +To query token balances for a specific token and/or owner: + +```shell +namada client balance --token NAM --owner my-new-acc +``` + +```admonish note +For any client command that submits a transaction (`init-account`, `transfer`, `tx`, `update` and [PoS transactions](ledger/pos.md)), you can use the `--dry-run` flag to simulate the transaction being applied in the block and see what would be the result. + +``` + +### See every known addresses' balance + +You can see the token's addresses known by the client when you query all tokens balances: + +```shell +namada client balance +``` \ No newline at end of file diff --git a/documentation/docs/src/user-guide/wallet/web-wallet.md b/documentation/docs/src/user-guide/wallet/web-wallet.md new file mode 100644 index 0000000000..77d9d10c99 --- /dev/null +++ b/documentation/docs/src/user-guide/wallet/web-wallet.md @@ -0,0 +1,3 @@ +## Web Wallet + +The Web Wallet for Namada is currently in closed beta. \ No newline at end of file From 3cf95a998cbdfd31a8aa6616345975e969ca906d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 16 Dec 2022 17:25:25 +0100 Subject: [PATCH 026/166] changelog: add #909 --- .changelog/unreleased/improvements/909-fix-queries-rustdoc.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/909-fix-queries-rustdoc.md diff --git a/.changelog/unreleased/improvements/909-fix-queries-rustdoc.md b/.changelog/unreleased/improvements/909-fix-queries-rustdoc.md new file mode 100644 index 0000000000..727f9ac685 --- /dev/null +++ b/.changelog/unreleased/improvements/909-fix-queries-rustdoc.md @@ -0,0 +1,2 @@ +- Make queries data structures public for inclusion in rustdoc. + ([#909](https://github.com/anoma/namada/pull/909)) From df69fab64a1b9793a3939df8e3e2ddd1d69baa1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 16 Dec 2022 17:30:00 +0100 Subject: [PATCH 027/166] changelog: add #667 --- .../unreleased/miscellaneous/667-tendermint-v0.1.4-abciplus.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/miscellaneous/667-tendermint-v0.1.4-abciplus.md diff --git a/.changelog/unreleased/miscellaneous/667-tendermint-v0.1.4-abciplus.md b/.changelog/unreleased/miscellaneous/667-tendermint-v0.1.4-abciplus.md new file mode 100644 index 0000000000..ea96cf2adc --- /dev/null +++ b/.changelog/unreleased/miscellaneous/667-tendermint-v0.1.4-abciplus.md @@ -0,0 +1,2 @@ +- Update tendermint to v0.1.4-abciplus. + ([#667](https://github.com/anoma/namada/pull/667)) \ No newline at end of file From 603c5624e5a3022e8b8acc2e89e853c6d5102a79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 16 Dec 2022 17:42:37 +0100 Subject: [PATCH 028/166] test in apps/ledger/storage: test prefix iterators --- apps/src/lib/node/ledger/storage/mod.rs | 63 ++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/apps/src/lib/node/ledger/storage/mod.rs b/apps/src/lib/node/ledger/storage/mod.rs index f24cffa6a3..cb9d6eb21d 100644 --- a/apps/src/lib/node/ledger/storage/mod.rs +++ b/apps/src/lib/node/ledger/storage/mod.rs @@ -50,10 +50,13 @@ fn new_blake2b() -> Blake2b { #[cfg(test)] mod tests { + use borsh::BorshSerialize; + use itertools::Itertools; use namada::ledger::storage::types; - use namada::types::address; + use namada::ledger::storage_api; use namada::types::chain::ChainId; use namada::types::storage::{BlockHash, BlockHeight, Key}; + use namada::types::{address, storage}; use proptest::collection::vec; use proptest::prelude::*; use proptest::test_runner::Config; @@ -344,4 +347,62 @@ mod tests { Ok(()) } + + /// Test the prefix iterator with RocksDB. + #[test] + fn test_persistent_storage_prefix_iter() { + let db_path = + TempDir::new().expect("Unable to create a temporary DB directory"); + let mut storage = PersistentStorage::open( + db_path.path(), + ChainId::default(), + address::nam(), + None, + ); + + let prefix = storage::Key::parse("prefix").unwrap(); + let mismatched_prefix = storage::Key::parse("different").unwrap(); + // We'll write sub-key in some random order to check prefix iter's order + let sub_keys = [2_i32, 1, i32::MAX, -1, 260, -2, i32::MIN, 5, 0]; + + for i in sub_keys.iter() { + let key = prefix.push(i).unwrap(); + let value = i.try_to_vec().unwrap(); + storage.write(&key, value).unwrap(); + + let key = mismatched_prefix.push(i).unwrap(); + let value = (i / 2).try_to_vec().unwrap(); + storage.write(&key, value).unwrap(); + } + storage.commit().unwrap(); + + // Then try to iterate over their prefix + let iter = storage_api::iter_prefix(&storage, &prefix) + .unwrap() + .map(Result::unwrap); + + // The order has to be sorted by sub-key value + let expected = sub_keys + .iter() + .sorted() + .map(|i| (prefix.push(i).unwrap(), *i)); + itertools::assert_equal(iter, expected); + + // Try to iterate over their prefix in reverse + let iter = storage_api::rev_iter_prefix(&storage, &prefix) + .unwrap() + .map(|res| { + let (key, val): (storage::Key, i32) = Result::unwrap(res); + (key, val) + }); + + // The order has to be reverse sorted by sub-key value + let expected = sub_keys + .iter() + .sorted() + .rev() + .map(|i| (prefix.push(i).unwrap(), *i / 2)); + + itertools::assert_equal(iter, expected); + } } From 8a0638bd38153b31507d64216707fd8765070b05 Mon Sep 17 00:00:00 2001 From: Awa Sun Yin Date: Fri, 16 Dec 2022 17:50:03 +0100 Subject: [PATCH 029/166] missing install.md --- documentation/docs/src/user-guide/install.md | 100 +++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 documentation/docs/src/user-guide/install.md diff --git a/documentation/docs/src/user-guide/install.md b/documentation/docs/src/user-guide/install.md new file mode 100644 index 0000000000..027343390e --- /dev/null +++ b/documentation/docs/src/user-guide/install.md @@ -0,0 +1,100 @@ +# Install Namada + +```admonish warning +At the moment, Namada only supports Linux and macOS. +``` + +## Hardware Requirements + +This section covers the minimum and recommended hardware requirements for engaging with Namada as a validator node. + +### Minimal Hardware Requirements + +| Hardware | Minimal Specifications | +| -------- | -------- | +| CPU | x86_64 or arm64 processor with at least 4 physical cores | +| RAM | 16GB DDR4 | +| Storage | at least 60GB SSD (NVMe SSD is recommended. HDD will be enough for localnet only) | + +There are different ways to install Namada: + +- [Install Namada](#install-namada) + - [Hardware Requirements](#hardware-requirements) + - [Minimal Hardware Requirements](#minimal-hardware-requirements) + - [From Source](#from-source) + - [From Binaries](#from-binaries) + - [From Docker](#from-docker) + +## From Source + +If you'd like to install Namada from source you will have to install some dependencies first: [Rust](https://www.rust-lang.org/tools/install), [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git), Clang, OpenSSL and LLVM. + +First, [install Rust](https://www.rust-lang.org/tools/install) by following the instructions from the official page. + +At the end of the installation, make sure that Cargo's bin directory ($HOME/.cargo/bin) is available on your PATH environment variable. You can either restart your shell or run `source $HOME/.cargo/env` to continue. + +If you already have Rust installed, make sure you're using the latest version by running: + +```shell +rustup update +``` + +Then, install the remaining dependencies. + +**Ubuntu:** running the following command should install everything needed: + +```shell +sudo apt-get install -y make git-core libssl-dev pkg-config libclang-12-dev build-essential +``` + +**Mac:** installing the Xcode command line tools should provide you with almost everything you need: + +```shell +xcode-select --install +``` + +Now, that you have all dependencies installed you can clone the source code from the [Namada repository](https://github.com/anoma/namada) and build it with: + +```admonish warning +During internal and private testnets, checkout the latest testnet branch using `git checkout $NAMADA_TESTNET_BRANCH`. +``` + +```shell +git clone https://github.com/anoma/namada.git +cd namada +make install +``` + +## From Binaries + +```admonish warning +Prebuilt binaries might not be available for a specific release or architecture, in this case you have to [build from source](#from-source). +``` + +If you'd like to install Namada from binaries you will have to install some dependencies first: [Tendermint](https://docs.tendermint.com/master/introduction/install.html) `0.34.x` and GLIBC `v2.29` or higher. + +Let's install Tendermint. + +You can either follow the instructions on the [Tendermint guide](https://docs.tendermint.com/master/introduction/install.html) or download the `get_tendermint.sh` script from the [Namada repository](https://github.com/anoma/namada/blob/master/scripts/install/get_tendermint.sh) and execute it (will ask you for `root` access): + +```shell +curl -LO https://raw.githubusercontent.com/namada/namada/main/scripts/install/get_tendermint.sh +chmod +x get_tendermint.sh +./get_tendermint.sh +``` + +Finally, you should have GLIBC `v2.29` or higher. + +**MacOS**: the system-provided glibc should be recent enough. + +**Ubuntu 20.04**: this is installed by default and you don't have to do anything more. + +**Ubuntu 18.04**: glibc has `v2.27` by default which is lower than the required version to run Namada. We recommend to directly [install from source](#from-source) or upgrade to Ubuntu 19.04, instead of updating glibc to the required version, since the latter way can be a messy and tedious task. In case, updating glibc would interest you this [website](http://www.linuxfromscratch.org/lfs/view/9.0-systemd/chapter05/glibc.html) gives you the steps to build the package from source. + +Now, that you have all dependencies installed you can download the latest binary release from our [releases page](https://github.com/anoma/namada/releases) by choosing the appropriate architecture. + +[fixme]: <> (update docker config as soon as Namada is transferred fully to Namada) + +## From Docker + +You can find the Namada docker image [here](https://github.com/anoma/namada/pkgs/container/namada) \ No newline at end of file From f78ee6079e6ed69765167d5ad988c50a0fbacfe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 16 Dec 2022 17:56:37 +0100 Subject: [PATCH 030/166] storage: remove rev_iter_prefix, which doesn't work as expected --- apps/src/lib/node/ledger/storage/mod.rs | 17 ----- apps/src/lib/node/ledger/storage/rocksdb.rs | 9 +-- core/src/ledger/storage/mockdb.rs | 14 ---- core/src/ledger/storage/mod.rs | 20 ------ core/src/ledger/storage_api/mod.rs | 78 --------------------- core/src/ledger/vp_env.rs | 7 -- shared/src/ledger/native_vp/mod.rs | 26 ------- shared/src/ledger/vp_host_fns.rs | 16 ----- shared/src/vm/host_env.rs | 64 ----------------- shared/src/vm/wasm/host_env.rs | 2 - tests/src/vm_host_env/mod.rs | 26 ------- tests/src/vm_host_env/tx.rs | 1 - tests/src/vm_host_env/vp.rs | 1 - tx_prelude/src/lib.rs | 16 +---- vm_env/src/lib.rs | 14 ---- vp_prelude/src/lib.rs | 36 +--------- 16 files changed, 6 insertions(+), 341 deletions(-) diff --git a/apps/src/lib/node/ledger/storage/mod.rs b/apps/src/lib/node/ledger/storage/mod.rs index cb9d6eb21d..1bd1446c51 100644 --- a/apps/src/lib/node/ledger/storage/mod.rs +++ b/apps/src/lib/node/ledger/storage/mod.rs @@ -387,22 +387,5 @@ mod tests { .sorted() .map(|i| (prefix.push(i).unwrap(), *i)); itertools::assert_equal(iter, expected); - - // Try to iterate over their prefix in reverse - let iter = storage_api::rev_iter_prefix(&storage, &prefix) - .unwrap() - .map(|res| { - let (key, val): (storage::Key, i32) = Result::unwrap(res); - (key, val) - }); - - // The order has to be reverse sorted by sub-key value - let expected = sub_keys - .iter() - .sorted() - .rev() - .map(|i| (prefix.push(i).unwrap(), *i / 2)); - - itertools::assert_equal(iter, expected); } } diff --git a/apps/src/lib/node/ledger/storage/rocksdb.rs b/apps/src/lib/node/ledger/storage/rocksdb.rs index 86980813fc..fa7c981697 100644 --- a/apps/src/lib/node/ledger/storage/rocksdb.rs +++ b/apps/src/lib/node/ledger/storage/rocksdb.rs @@ -891,11 +891,7 @@ impl<'iter> DBIter<'iter> for RocksDB { &'iter self, prefix: &Key, ) -> PersistentPrefixIterator<'iter> { - iter_prefix(self, prefix, Direction::Forward) - } - - fn rev_iter_prefix(&'iter self, prefix: &Key) -> Self::PrefixIter { - iter_prefix(self, prefix, Direction::Reverse) + iter_prefix(self, prefix) } fn iter_results(&'iter self) -> PersistentPrefixIterator<'iter> { @@ -922,7 +918,6 @@ impl<'iter> DBIter<'iter> for RocksDB { fn iter_prefix<'iter>( db: &'iter RocksDB, prefix: &Key, - direction: Direction, ) -> PersistentPrefixIterator<'iter> { let db_prefix = "subspace/".to_owned(); let prefix = format!("{}{}", db_prefix, prefix); @@ -937,7 +932,7 @@ fn iter_prefix<'iter>( read_opts.set_iterate_upper_bound(upper_prefix); let iter = db.0.iterator_opt( - IteratorMode::From(prefix.as_bytes(), direction), + IteratorMode::From(prefix.as_bytes(), Direction::Forward), read_opts, ); PersistentPrefixIterator(PrefixIterator::new(iter, db_prefix)) diff --git a/core/src/ledger/storage/mockdb.rs b/core/src/ledger/storage/mockdb.rs index 011d8faac8..ac96e12cf5 100644 --- a/core/src/ledger/storage/mockdb.rs +++ b/core/src/ledger/storage/mockdb.rs @@ -456,20 +456,6 @@ impl<'iter> DBIter<'iter> for MockDB { ) } - fn rev_iter_prefix(&'iter self, prefix: &Key) -> Self::PrefixIter { - let db_prefix = "subspace/".to_owned(); - let prefix = format!("{}{}", db_prefix, prefix); - let iter = self.0.borrow().clone().into_iter(); - MockPrefixIterator::new( - MockIterator { - prefix, - iter, - reverse_order: true, - }, - db_prefix, - ) - } - fn iter_results(&'iter self) -> MockPrefixIterator { let db_prefix = "results/".to_owned(); let prefix = "results".to_owned(); diff --git a/core/src/ledger/storage/mod.rs b/core/src/ledger/storage/mod.rs index 8285e58bab..4c34a6c2c4 100644 --- a/core/src/ledger/storage/mod.rs +++ b/core/src/ledger/storage/mod.rs @@ -305,10 +305,6 @@ pub trait DBIter<'iter> { /// ordered by the storage keys. fn iter_prefix(&'iter self, prefix: &Key) -> Self::PrefixIter; - /// Read account subspace key value pairs with the given prefix from the DB, - /// reverse ordered by the storage keys. - fn rev_iter_prefix(&'iter self, prefix: &Key) -> Self::PrefixIter; - /// Read results subspace key value pairs from the DB fn iter_results(&'iter self) -> Self::PrefixIter; } @@ -515,15 +511,6 @@ where (self.db.iter_prefix(prefix), prefix.len() as _) } - /// Returns a prefix iterator, reverse ordered by storage keys, and the gas - /// cost - pub fn rev_iter_prefix( - &self, - prefix: &Key, - ) -> (>::PrefixIter, u64) { - (self.db.rev_iter_prefix(prefix), prefix.len() as _) - } - /// Returns a prefix iterator and the gas cost pub fn iter_results(&self) -> (>::PrefixIter, u64) { (self.db.iter_results(), 0) @@ -1033,13 +1020,6 @@ where Ok(self.db.iter_prefix(prefix)) } - fn rev_iter_prefix( - &'iter self, - prefix: &crate::types::storage::Key, - ) -> std::result::Result { - Ok(self.db.rev_iter_prefix(prefix)) - } - fn iter_next( &self, iter: &mut Self::PrefixIter, diff --git a/core/src/ledger/storage_api/mod.rs b/core/src/ledger/storage_api/mod.rs index 7c842a6136..dde9eb5ade 100644 --- a/core/src/ledger/storage_api/mod.rs +++ b/core/src/ledger/storage_api/mod.rs @@ -68,16 +68,6 @@ pub trait StorageRead<'iter> { prefix: &storage::Key, ) -> Result; - /// Storage prefix iterator in reverse order of the storage keys. It will - /// try to get an iterator from the storage. - /// - /// For a more user-friendly iterator API, use [`fn@rev_iter_prefix`] or - /// [`fn@rev_iter_prefix_bytes`] instead. - fn rev_iter_prefix( - &'iter self, - prefix: &storage::Key, - ) -> Result; - /// Storage prefix iterator. It will try to read from the storage. fn iter_next( &self, @@ -195,71 +185,3 @@ where }); Ok(iter) } - -/// Iterate items matching the given prefix, reverse ordered by the storage -/// keys. -pub fn rev_iter_prefix_bytes<'a>( - storage: &'a impl StorageRead<'a>, - prefix: &crate::types::storage::Key, -) -> Result)>> + 'a> { - let iter = storage.rev_iter_prefix(prefix)?; - let iter = itertools::unfold(iter, |iter| { - match storage.iter_next(iter) { - Ok(Some((key, val))) => { - let key = match storage::Key::parse(key).into_storage_result() { - Ok(key) => key, - Err(err) => { - // Propagate key encoding errors into Iterator's Item - return Some(Err(err)); - } - }; - Some(Ok((key, val))) - } - Ok(None) => None, - Err(err) => { - // Propagate `iter_next` errors into Iterator's Item - Some(Err(err)) - } - } - }); - Ok(iter) -} - -/// Iterate Borsh encoded items matching the given prefix, reverse ordered by -/// the storage keys. -pub fn rev_iter_prefix<'a, T>( - storage: &'a impl StorageRead<'a>, - prefix: &crate::types::storage::Key, -) -> Result> + 'a> -where - T: BorshDeserialize, -{ - let iter = storage.rev_iter_prefix(prefix)?; - let iter = itertools::unfold(iter, |iter| { - match storage.iter_next(iter) { - Ok(Some((key, val))) => { - let key = match storage::Key::parse(key).into_storage_result() { - Ok(key) => key, - Err(err) => { - // Propagate key encoding errors into Iterator's Item - return Some(Err(err)); - } - }; - let val = match T::try_from_slice(&val).into_storage_result() { - Ok(val) => val, - Err(err) => { - // Propagate val encoding errors into Iterator's Item - return Some(Err(err)); - } - }; - Some(Ok((key, val))) - } - Ok(None) => None, - Err(err) => { - // Propagate `iter_next` errors into Iterator's Item - Some(Err(err)) - } - } - }); - Ok(iter) -} diff --git a/core/src/ledger/vp_env.rs b/core/src/ledger/vp_env.rs index 49bd5d515c..4b7edc02ce 100644 --- a/core/src/ledger/vp_env.rs +++ b/core/src/ledger/vp_env.rs @@ -70,13 +70,6 @@ pub trait VpEnv<'view> { prefix: &Key, ) -> Result; - /// Storage prefix iterator, reverse ordered by storage keys. It will try to - /// get an iterator from the storage. - fn rev_iter_prefix( - &self, - prefix: &Key, - ) -> Result; - /// Evaluate a validity predicate with given data. The address, changed /// storage keys and verifiers will have the same values as the input to /// caller's validity predicate. diff --git a/shared/src/ledger/native_vp/mod.rs b/shared/src/ledger/native_vp/mod.rs index 8943c4f8d3..d8f1dbe6e5 100644 --- a/shared/src/ledger/native_vp/mod.rs +++ b/shared/src/ledger/native_vp/mod.rs @@ -203,13 +203,6 @@ where .into_storage_result() } - fn rev_iter_prefix( - &self, - prefix: &crate::types::storage::Key, - ) -> storage_api::Result { - self.ctx.rev_iter_prefix(prefix).into_storage_result() - } - fn iter_next( &self, iter: &mut Self::PrefixIter, @@ -291,13 +284,6 @@ where .into_storage_result() } - fn rev_iter_prefix( - &self, - prefix: &crate::types::storage::Key, - ) -> storage_api::Result { - self.ctx.rev_iter_prefix(prefix).into_storage_result() - } - fn iter_next( &self, iter: &mut Self::PrefixIter, @@ -450,18 +436,6 @@ where .into_storage_result() } - fn rev_iter_prefix( - &self, - prefix: &Key, - ) -> Result { - vp_host_fns::rev_iter_prefix( - &mut self.gas_meter.borrow_mut(), - self.storage, - prefix, - ) - .into_storage_result() - } - fn eval( &self, vp_code: Vec, diff --git a/shared/src/ledger/vp_host_fns.rs b/shared/src/ledger/vp_host_fns.rs index 8fc013075a..c678744ccf 100644 --- a/shared/src/ledger/vp_host_fns.rs +++ b/shared/src/ledger/vp_host_fns.rs @@ -311,22 +311,6 @@ where Ok(iter) } -/// Storage prefix iterator, reverse ordered by storage keys. It will try to get -/// an iterator from the storage. -pub fn rev_iter_prefix<'a, DB, H>( - gas_meter: &mut VpGasMeter, - storage: &'a Storage, - prefix: &Key, -) -> EnvResult<>::PrefixIter> -where - DB: storage::DB + for<'iter> storage::DBIter<'iter>, - H: StorageHasher, -{ - let (iter, gas) = storage.rev_iter_prefix(prefix); - add_gas(gas_meter, gas)?; - Ok(iter) -} - /// Storage prefix iterator for prior state (before tx execution). It will try /// to read from the storage. pub fn iter_pre_next( diff --git a/shared/src/vm/host_env.rs b/shared/src/vm/host_env.rs index 90e6e4405f..9e61651b5e 100644 --- a/shared/src/vm/host_env.rs +++ b/shared/src/vm/host_env.rs @@ -706,38 +706,6 @@ where Ok(iterators.insert(iter).id()) } -/// Storage prefix iterator function exposed to the wasm VM Tx environment. -/// It will try to get an iterator from the storage and return the corresponding -/// ID of the iterator, reverse ordered by storage keys. -pub fn tx_rev_iter_prefix( - env: &TxVmEnv, - prefix_ptr: u64, - prefix_len: u64, -) -> TxResult -where - MEM: VmMemory, - DB: storage::DB + for<'iter> storage::DBIter<'iter>, - H: StorageHasher, - CA: WasmCacheAccess, -{ - let (prefix, gas) = env - .memory - .read_string(prefix_ptr, prefix_len as _) - .map_err(|e| TxRuntimeError::MemoryError(Box::new(e)))?; - tx_add_gas(env, gas)?; - - tracing::debug!("tx_rev_iter_prefix {}, prefix {}", prefix, prefix_ptr); - - let prefix = - Key::parse(prefix).map_err(TxRuntimeError::StorageDataError)?; - - let storage = unsafe { env.ctx.storage.get() }; - let iterators = unsafe { env.ctx.iterators.get() }; - let (iter, gas) = storage.rev_iter_prefix(&prefix); - tx_add_gas(env, gas)?; - Ok(iterators.insert(iter).id()) -} - /// Storage prefix iterator next function exposed to the wasm VM Tx environment. /// It will try to read from the write log first and if no entry found then from /// the storage. @@ -1272,38 +1240,6 @@ where Ok(iterators.insert(iter).id()) } -/// Storage prefix iterator function exposed to the wasm VM VP environment. -/// It will try to get an iterator from the storage and return the corresponding -/// ID of the iterator, reverse ordered by storage keys. -pub fn vp_rev_iter_prefix( - env: &VpVmEnv, - prefix_ptr: u64, - prefix_len: u64, -) -> vp_host_fns::EnvResult -where - MEM: VmMemory, - DB: storage::DB + for<'iter> storage::DBIter<'iter>, - H: StorageHasher, - EVAL: VpEvaluator, - CA: WasmCacheAccess, -{ - let (prefix, gas) = env - .memory - .read_string(prefix_ptr, prefix_len as _) - .map_err(|e| vp_host_fns::RuntimeError::MemoryError(Box::new(e)))?; - let gas_meter = unsafe { env.ctx.gas_meter.get() }; - vp_host_fns::add_gas(gas_meter, gas)?; - - let prefix = Key::parse(prefix) - .map_err(vp_host_fns::RuntimeError::StorageDataError)?; - tracing::debug!("vp_rev_iter_prefix {}", prefix); - - let storage = unsafe { env.ctx.storage.get() }; - let iter = vp_host_fns::rev_iter_prefix(gas_meter, storage, &prefix)?; - let iterators = unsafe { env.ctx.iterators.get() }; - Ok(iterators.insert(iter).id()) -} - /// Storage prefix iterator for prior state (before tx execution) function /// exposed to the wasm VM VP environment. It will try to read from the storage. /// diff --git a/shared/src/vm/wasm/host_env.rs b/shared/src/vm/wasm/host_env.rs index e4e173f47c..b9eeffecfc 100644 --- a/shared/src/vm/wasm/host_env.rs +++ b/shared/src/vm/wasm/host_env.rs @@ -67,7 +67,6 @@ where "namada_tx_write_temp" => Function::new_native_with_env(wasm_store, env.clone(), host_env::tx_write_temp), "namada_tx_delete" => Function::new_native_with_env(wasm_store, env.clone(), host_env::tx_delete), "namada_tx_iter_prefix" => Function::new_native_with_env(wasm_store, env.clone(), host_env::tx_iter_prefix), - "namada_tx_rev_iter_prefix" => Function::new_native_with_env(wasm_store, env.clone(), host_env::tx_rev_iter_prefix), "namada_tx_iter_next" => Function::new_native_with_env(wasm_store, env.clone(), host_env::tx_iter_next), "namada_tx_insert_verifier" => Function::new_native_with_env(wasm_store, env.clone(), host_env::tx_insert_verifier), "namada_tx_update_validity_predicate" => Function::new_native_with_env(wasm_store, env.clone(), host_env::tx_update_validity_predicate), @@ -110,7 +109,6 @@ where "namada_vp_has_key_pre" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_has_key_pre), "namada_vp_has_key_post" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_has_key_post), "namada_vp_iter_prefix" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_iter_prefix), - "namada_vp_rev_iter_prefix" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_rev_iter_prefix), "namada_vp_iter_pre_next" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_iter_pre_next), "namada_vp_iter_post_next" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_iter_post_next), "namada_vp_get_chain_id" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_get_chain_id), diff --git a/tests/src/vm_host_env/mod.rs b/tests/src/vm_host_env/mod.rs index aa8c160339..4ab7b6eca7 100644 --- a/tests/src/vm_host_env/mod.rs +++ b/tests/src/vm_host_env/mod.rs @@ -183,19 +183,6 @@ mod tests { .sorted() .map(|i| (prefix.push(i).unwrap(), *i)); itertools::assert_equal(iter, expected); - - // Try to iterate over their prefix in reverse - let iter = namada_tx_prelude::rev_iter_prefix(tx::ctx(), &prefix) - .unwrap() - .map(Result::unwrap); - - // The order has to be reverse sorted by sub-key value - let expected = sub_keys - .iter() - .sorted() - .rev() - .map(|i| (prefix.push(i).unwrap(), *i)); - itertools::assert_equal(iter, expected); } #[test] @@ -429,19 +416,6 @@ mod tests { (prefix.push(i).unwrap(), val) }); itertools::assert_equal(iter_post, expected_post); - - // Try to iterate over their prefix in reverse - let iter_pre = namada_vp_prelude::rev_iter_prefix(&ctx_pre, &prefix) - .unwrap() - .map(|item| item.unwrap()); - - // The order in has to be reverse sorted by sub-key value - let expected_pre = sub_keys - .iter() - .sorted() - .rev() - .map(|i| (prefix.push(i).unwrap(), *i)); - itertools::assert_equal(iter_pre, expected_pre); } #[test] diff --git a/tests/src/vm_host_env/tx.rs b/tests/src/vm_host_env/tx.rs index 05542438d6..0f7040941d 100644 --- a/tests/src/vm_host_env/tx.rs +++ b/tests/src/vm_host_env/tx.rs @@ -400,7 +400,6 @@ mod native_tx_host_env { )); native_host_fn!(tx_delete(key_ptr: u64, key_len: u64)); native_host_fn!(tx_iter_prefix(prefix_ptr: u64, prefix_len: u64) -> u64); - native_host_fn!(tx_rev_iter_prefix(prefix_ptr: u64, prefix_len: u64) -> u64); native_host_fn!(tx_iter_next(iter_id: u64) -> i64); native_host_fn!(tx_insert_verifier(addr_ptr: u64, addr_len: u64)); native_host_fn!(tx_update_validity_predicate( diff --git a/tests/src/vm_host_env/vp.rs b/tests/src/vm_host_env/vp.rs index 50cbc7b6ef..a88176d182 100644 --- a/tests/src/vm_host_env/vp.rs +++ b/tests/src/vm_host_env/vp.rs @@ -332,7 +332,6 @@ mod native_vp_host_env { native_host_fn!(vp_has_key_pre(key_ptr: u64, key_len: u64) -> i64); native_host_fn!(vp_has_key_post(key_ptr: u64, key_len: u64) -> i64); native_host_fn!(vp_iter_prefix(prefix_ptr: u64, prefix_len: u64) -> u64); - native_host_fn!(vp_rev_iter_prefix(prefix_ptr: u64, prefix_len: u64) -> u64); native_host_fn!(vp_iter_pre_next(iter_id: u64) -> i64); native_host_fn!(vp_iter_post_next(iter_id: u64) -> i64); native_host_fn!(vp_get_chain_id(result_ptr: u64)); diff --git a/tx_prelude/src/lib.rs b/tx_prelude/src/lib.rs index d0d4511577..73a90b6d03 100644 --- a/tx_prelude/src/lib.rs +++ b/tx_prelude/src/lib.rs @@ -21,9 +21,8 @@ pub use namada_core::ledger::parameters::storage as parameters_storage; pub use namada_core::ledger::slash_fund::storage as slash_fund_storage; pub use namada_core::ledger::storage::types::encode; pub use namada_core::ledger::storage_api::{ - self, iter_prefix, iter_prefix_bytes, rev_iter_prefix, - rev_iter_prefix_bytes, Error, OptionExt, ResultExt, StorageRead, - StorageWrite, + self, iter_prefix, iter_prefix_bytes, Error, OptionExt, ResultExt, + StorageRead, StorageWrite, }; pub use namada_core::ledger::tx_env::TxEnv; pub use namada_core::proto::{Signed, SignedTxData}; @@ -190,17 +189,6 @@ impl StorageRead<'_> for Ctx { Ok(KeyValIterator(iter_id, PhantomData)) } - fn rev_iter_prefix( - &self, - prefix: &storage::Key, - ) -> Result { - let prefix = prefix.to_string(); - let iter_id = unsafe { - namada_tx_rev_iter_prefix(prefix.as_ptr() as _, prefix.len() as _) - }; - Ok(KeyValIterator(iter_id, PhantomData)) - } - fn iter_next( &self, iter: &mut Self::PrefixIter, diff --git a/vm_env/src/lib.rs b/vm_env/src/lib.rs index 795ae912dc..e328a8748c 100644 --- a/vm_env/src/lib.rs +++ b/vm_env/src/lib.rs @@ -51,13 +51,6 @@ pub mod tx { // keys. pub fn namada_tx_iter_prefix(prefix_ptr: u64, prefix_len: u64) -> u64; - // Get an ID of a data iterator with key prefix, reverse ordered by - // storage keys. - pub fn namada_tx_rev_iter_prefix( - prefix_ptr: u64, - prefix_len: u64, - ) -> u64; - // Returns the size of the value (can be 0), or -1 if there's no next // value. If a value is found, it will be placed in the read // cache, because we cannot allocate a buffer for it before we know @@ -150,13 +143,6 @@ pub mod vp { // keys. pub fn namada_vp_iter_prefix(prefix_ptr: u64, prefix_len: u64) -> u64; - // Get an ID of a data iterator with key prefix, reverse ordered by - // storage keys. - pub fn namada_vp_rev_iter_prefix( - prefix_ptr: u64, - prefix_len: u64, - ) -> u64; - // Read variable-length prior state when we don't know the size // up-front, returns the size of the value (can be 0), or -1 if // the key is not present. If a value is found, it will be placed in the diff --git a/vp_prelude/src/lib.rs b/vp_prelude/src/lib.rs index 6ff90f56df..f4911516d5 100644 --- a/vp_prelude/src/lib.rs +++ b/vp_prelude/src/lib.rs @@ -20,8 +20,8 @@ pub use borsh::{BorshDeserialize, BorshSerialize}; pub use namada_core::ledger::governance::storage as gov_storage; pub use namada_core::ledger::parameters; pub use namada_core::ledger::storage_api::{ - self, iter_prefix, iter_prefix_bytes, rev_iter_prefix, - rev_iter_prefix_bytes, Error, OptionExt, ResultExt, StorageRead, + self, iter_prefix, iter_prefix_bytes, Error, OptionExt, ResultExt, + StorageRead, }; pub use namada_core::ledger::vp_env::VpEnv; pub use namada_core::proto::{Signed, SignedTxData}; @@ -258,14 +258,6 @@ impl<'view> VpEnv<'view> for Ctx { iter_prefix_impl(prefix) } - fn rev_iter_prefix( - &self, - prefix: &storage::Key, - ) -> Result { - // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl - rev_iter_prefix_impl(prefix) - } - fn eval( &self, vp_code: Vec, @@ -354,13 +346,6 @@ impl StorageRead<'_> for CtxPreStorageRead<'_> { iter_prefix_impl(prefix) } - fn rev_iter_prefix( - &self, - prefix: &storage::Key, - ) -> Result { - rev_iter_prefix_impl(prefix) - } - fn get_chain_id(&self) -> Result { get_chain_id() } @@ -424,13 +409,6 @@ impl StorageRead<'_> for CtxPostStorageRead<'_> { iter_prefix_impl(prefix) } - fn rev_iter_prefix( - &self, - prefix: &storage::Key, - ) -> storage_api::Result { - rev_iter_prefix_impl(prefix) - } - fn get_chain_id(&self) -> Result { get_chain_id() } @@ -466,16 +444,6 @@ fn iter_prefix_impl( Ok(KeyValIterator(iter_id, PhantomData)) } -fn rev_iter_prefix_impl( - prefix: &storage::Key, -) -> Result)>, Error> { - let prefix = prefix.to_string(); - let iter_id = unsafe { - namada_vp_rev_iter_prefix(prefix.as_ptr() as _, prefix.len() as _) - }; - Ok(KeyValIterator(iter_id, PhantomData)) -} - fn get_chain_id() -> Result { let result = Vec::with_capacity(CHAIN_ID_LENGTH); unsafe { From 982088ebe4e9765b01a820a0dd536bba58c08ba5 Mon Sep 17 00:00:00 2001 From: Bengt Date: Fri, 16 Dec 2022 17:23:58 +0000 Subject: [PATCH 031/166] fixed second compile error --- documentation/docs/src/quick-start.md | 2 +- documentation/docs/src/user-guide/install.md | 100 ------------------ .../src/user-guide/overview-of-binaries.md | 2 +- 3 files changed, 2 insertions(+), 102 deletions(-) delete mode 100644 documentation/docs/src/user-guide/install.md diff --git a/documentation/docs/src/quick-start.md b/documentation/docs/src/quick-start.md index dade2125e4..4f2620e1e9 100644 --- a/documentation/docs/src/quick-start.md +++ b/documentation/docs/src/quick-start.md @@ -14,7 +14,7 @@ This guide is for those interested in operating a Namada validator node and assu ## Installing Namada -See [the installation guide](user-guide/install.md) for details on installing the Namada binaries. Commands in this guide will assume you have the Namada binaries (`namada`, `namadan`, `namadaw`, `namadac`) on your $PATH. +See [the installation guide](user-guide/install/README.md) for details on installing the Namada binaries. Commands in this guide will assume you have the Namada binaries (`namada`, `namadan`, `namadaw`, `namadac`) on your $PATH. A simple way to add these binaries to one's path is to run ```shell diff --git a/documentation/docs/src/user-guide/install.md b/documentation/docs/src/user-guide/install.md deleted file mode 100644 index 027343390e..0000000000 --- a/documentation/docs/src/user-guide/install.md +++ /dev/null @@ -1,100 +0,0 @@ -# Install Namada - -```admonish warning -At the moment, Namada only supports Linux and macOS. -``` - -## Hardware Requirements - -This section covers the minimum and recommended hardware requirements for engaging with Namada as a validator node. - -### Minimal Hardware Requirements - -| Hardware | Minimal Specifications | -| -------- | -------- | -| CPU | x86_64 or arm64 processor with at least 4 physical cores | -| RAM | 16GB DDR4 | -| Storage | at least 60GB SSD (NVMe SSD is recommended. HDD will be enough for localnet only) | - -There are different ways to install Namada: - -- [Install Namada](#install-namada) - - [Hardware Requirements](#hardware-requirements) - - [Minimal Hardware Requirements](#minimal-hardware-requirements) - - [From Source](#from-source) - - [From Binaries](#from-binaries) - - [From Docker](#from-docker) - -## From Source - -If you'd like to install Namada from source you will have to install some dependencies first: [Rust](https://www.rust-lang.org/tools/install), [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git), Clang, OpenSSL and LLVM. - -First, [install Rust](https://www.rust-lang.org/tools/install) by following the instructions from the official page. - -At the end of the installation, make sure that Cargo's bin directory ($HOME/.cargo/bin) is available on your PATH environment variable. You can either restart your shell or run `source $HOME/.cargo/env` to continue. - -If you already have Rust installed, make sure you're using the latest version by running: - -```shell -rustup update -``` - -Then, install the remaining dependencies. - -**Ubuntu:** running the following command should install everything needed: - -```shell -sudo apt-get install -y make git-core libssl-dev pkg-config libclang-12-dev build-essential -``` - -**Mac:** installing the Xcode command line tools should provide you with almost everything you need: - -```shell -xcode-select --install -``` - -Now, that you have all dependencies installed you can clone the source code from the [Namada repository](https://github.com/anoma/namada) and build it with: - -```admonish warning -During internal and private testnets, checkout the latest testnet branch using `git checkout $NAMADA_TESTNET_BRANCH`. -``` - -```shell -git clone https://github.com/anoma/namada.git -cd namada -make install -``` - -## From Binaries - -```admonish warning -Prebuilt binaries might not be available for a specific release or architecture, in this case you have to [build from source](#from-source). -``` - -If you'd like to install Namada from binaries you will have to install some dependencies first: [Tendermint](https://docs.tendermint.com/master/introduction/install.html) `0.34.x` and GLIBC `v2.29` or higher. - -Let's install Tendermint. - -You can either follow the instructions on the [Tendermint guide](https://docs.tendermint.com/master/introduction/install.html) or download the `get_tendermint.sh` script from the [Namada repository](https://github.com/anoma/namada/blob/master/scripts/install/get_tendermint.sh) and execute it (will ask you for `root` access): - -```shell -curl -LO https://raw.githubusercontent.com/namada/namada/main/scripts/install/get_tendermint.sh -chmod +x get_tendermint.sh -./get_tendermint.sh -``` - -Finally, you should have GLIBC `v2.29` or higher. - -**MacOS**: the system-provided glibc should be recent enough. - -**Ubuntu 20.04**: this is installed by default and you don't have to do anything more. - -**Ubuntu 18.04**: glibc has `v2.27` by default which is lower than the required version to run Namada. We recommend to directly [install from source](#from-source) or upgrade to Ubuntu 19.04, instead of updating glibc to the required version, since the latter way can be a messy and tedious task. In case, updating glibc would interest you this [website](http://www.linuxfromscratch.org/lfs/view/9.0-systemd/chapter05/glibc.html) gives you the steps to build the package from source. - -Now, that you have all dependencies installed you can download the latest binary release from our [releases page](https://github.com/anoma/namada/releases) by choosing the appropriate architecture. - -[fixme]: <> (update docker config as soon as Namada is transferred fully to Namada) - -## From Docker - -You can find the Namada docker image [here](https://github.com/anoma/namada/pkgs/container/namada) \ No newline at end of file diff --git a/documentation/docs/src/user-guide/overview-of-binaries.md b/documentation/docs/src/user-guide/overview-of-binaries.md index f3de942b6d..21686064d9 100644 --- a/documentation/docs/src/user-guide/overview-of-binaries.md +++ b/documentation/docs/src/user-guide/overview-of-binaries.md @@ -1,6 +1,6 @@ # Overview of binaries -This guide assumes that the Namada binaries are [installed](./install.md) and available on path. These are: +This guide assumes that the Namada binaries are [installed](./install/README.md) and available on path. These are: - `namada`: The main binary that can be used to interact with all the components of Namada - `namadan`: The ledger node From 934a62b62a99aae45b036ac6e38a90f8e936a9a0 Mon Sep 17 00:00:00 2001 From: brentstone Date: Fri, 16 Dec 2022 12:27:28 -0500 Subject: [PATCH 032/166] fix transfer args --- tests/src/e2e/ledger_tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/e2e/ledger_tests.rs b/tests/src/e2e/ledger_tests.rs index dc129818c3..6394e79c3d 100644 --- a/tests/src/e2e/ledger_tests.rs +++ b/tests/src/e2e/ledger_tests.rs @@ -323,11 +323,11 @@ fn ledger_txs_and_queries() -> Result<()> { NAM, "--amount", "10.1", - "--fee-amount", + "--gas-amount", "0", "--gas-limit", "0", - "--fee-token", + "--gas-token", NAM, "--ledger-address", &validator_one_rpc, From 0d4688daea2564e6ea23882276e88db1391e81fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 16 Dec 2022 18:33:15 +0100 Subject: [PATCH 033/166] wasm_for_tests: make --- wasm_for_tests/tx_memory_limit.wasm | Bin 133398 -> 133419 bytes wasm_for_tests/tx_mint_tokens.wasm | Bin 352858 -> 356170 bytes wasm_for_tests/tx_no_op.wasm | Bin 25554 -> 25554 bytes wasm_for_tests/tx_proposal_code.wasm | Bin 201332 -> 205677 bytes wasm_for_tests/tx_read_storage_key.wasm | Bin 152564 -> 152457 bytes wasm_for_tests/tx_write_storage_key.wasm | Bin 226795 -> 228613 bytes wasm_for_tests/vp_always_false.wasm | Bin 156489 -> 156524 bytes wasm_for_tests/vp_always_true.wasm | Bin 156489 -> 156524 bytes wasm_for_tests/vp_eval.wasm | Bin 157426 -> 157461 bytes wasm_for_tests/vp_memory_limit.wasm | Bin 158937 -> 158972 bytes wasm_for_tests/vp_read_storage_key.wasm | Bin 170817 -> 168172 bytes 11 files changed, 0 insertions(+), 0 deletions(-) diff --git a/wasm_for_tests/tx_memory_limit.wasm b/wasm_for_tests/tx_memory_limit.wasm index 9c4ea2abccbcef666288b7ccb0a12e07dd9d4c27..09fcaea999799c8f256d0c2ba28b73dd249e8409 100755 GIT binary patch delta 2071 zcmahKYiv|i`h4f!xxLdnk1IkSb6e)jFoh}YlqtfLKA=5qr-jm1LQ?;*HigxVo#G2i zq8K_5Up1OY`Lb133kAwUCBClNm1v}Hc73zEs9A}cpzES2YB0w5_@RF1QX2i`{qcS0 zd!Fxk?)Yx=@!jUGl_kEs`q%&;8DRsEhmirs2K0P>><^{dfHpFAb1duEIy*G(2hhRd zrmh2n05=!|0IiURg9Tgz;J^xiB;fOzA(DX33yG~h%>ZA)*t=19YV5l;$(Sf!l3r0C zZfIyzprh$8z9eds{D!~OBKTIh^T;tmZQuhv&P*o%3lS} z^Z0Bu1r~l3-R_Qy7h#@P9VUFzpCe_tNN7WL84kwZf^uwHa2>%z3-Saj5_dwm`&c3g zrOG73Z2_%N$8`a+D#ObNP2u^9|AB-5TDTd?uyN6lD2uTGw*-?rK<>JWa-PqAL%A<6 z8U~n;jg=Pwv3hZJm8t5$;)Vi#so$K{TLcj$^6Z_|)lUfs(~(?i!o)ikUkN6@y|^Oc zwWs|jk+s*!jE&Rdgo_&ngnLfD@=kqstEbC^2qIkyS=I$Ab}58-$F2) z`q)ausC3fKC78gUqHFMcb+LPOO&34}k1i3R2qmFQAuo(mMiKn)lD$xaThonJP1vGR zA2W5x?y?&|WwQ*+eHP9g6URMP0Z`{42 zhX&`v6*to0tgF9);EDQ(H!b{EvxD128TN~E{JcI3A7i>9wc+euYNAd#mgS^rS9py} zHn6Z@@|{bfa8CM31ahtfTaUABP$RLOlc#9MlZ<5;ZJ(Nm*NC2ZahQAwpKFMQPb(*? zhNNC-SKucN55gIDr17kZ`kIyLvYA^vd%8u=7%*v(_ERhGgM-+#YF5pQGeByO(hDGc z(&0ZIz?_W0Iowagy9cmWMvONOPyhkEK^7T*S4Y1(!ZUbTs{=affx8s}Kj1{GV|=;)k}3aSzj6kz#_yZ}1ec&w20^eo4ZAD&fVrj?W$`BH8ZneUmCdJ~oM=wuo`pC2=u6-R{sloFtXg z`>>`p!XNSwyn(T-!>2vMc-||ym*x}1zZ^%i>zrf9=sE?|gF~A_&n1&b74s;5la0-r zx+s$QZrTr6yJbs|F$?#sxz+9KY~onek+r-RQ~~VD<+`L(A zx^4K{Tf~-YH(rB#dKU6?A$+N)2rD;i(ij_b@82-QG2A}~zrMQUj#&TSV*T*#W4{37 C>>nxs delta 2133 zcmah~Yiv|S6rMBp?%lh+yWNYSuidsgyKU+A1zR3l+CtmulkzBuihqb$P!zT(0ZSqp zTaZU$P=Ov(t&+C1pazWuub>8%Y7iuW#AxFyQItmviBU8n2^#gxEg=4KlY3^)bI$qB znb}wS%>F)e*W8)Br-yZVdex70LND}mGS;ap7J56i9(OSm>+ZbnX7{>ii>bA>YTN|S z!Qwt$2L^s_Fb1IMJPouo9!U3c4S)ml0%^hH@de@LPcyvW+5JTXUfX@OJzi88o-uQF zb+D#(4pik%&d8jV6$oaB{5g5?(z5c3sf|s|bqz9Y7p{V1u*ZpW3OS4kEdhIQxwe3_ zdHA|^Dl$Ac#-=e=%b4KOOv&eoFJY|8<#!EYzn+8(ct+n&4$czK35f35H^$zLWMC^K;<9)F57Cx$3QaK48=l&#Tez3?#Ns`mbo0e-qKw{uO+D z)H&m?2U;;bJ>S?mM8OMidis9tV!*;l;mP<@x@`%n#*S$c+SZ{JY~!p0?+hNH#qrw} zhGJ_oFTpe{%BqKivoh-wfJ#i}tbj^qASX@N+5zyDycrn^3A;6Cf~^pB9xaSRj&ezITRuzqlJ9hE~aC=)*rt%FBET9u_kcF{Qq)MQ;$qWXp?N zso_5m5x%hGQWHMBqjWL&aI~~2WLi`J)UYgCW~StEGNX!xN0@l7v?DKOCV4`bE@E-& zwMR|fAr+9@ai^m!4D1jxsY(?ohcWvojfFZWaW`S|j*L70xM ziCW+EphbwkWNP?SqIqi65MH^7r^*?V$9fkA$jgwMc`D`=&>rA~&Su^vjJAMIS$X>^ zGouQ{s3G0)WWq=(>l@ynjIgTmP=-ch30+ZYvC=inQ-L}DUD>3jv3a`Wl~WX?6rTyN z(Ctcoe}CrhyP7;6b=q_$J?3_%=cEXmXzpq76`{Po9%$@lP7O(gia z3gV@pWS(Z1;MJPv;2URW?L}3>hPjE{>!-N>bc($0z@$aiAI#kWL%68!rkR_kpUn2t z<(CSn0GSQcoei>%7z?XL*%7)FI{r}~!oyRR5I9%s*Z=QD!6zH`@WZ3Hvngckrz)h4 zy)qM?#bq)K+wf5t=D&~NV=`o17$NO#O3ObR!Fxz@Qc3(uV!W@mK3v<9eZq9Mz1N8 z`;>4W>aEd?;R%&w^XM+Xg7xbIjNaNG=e1ex>!}F+4b`=8{15+O`(4f(t#i1kQ`aq> zNvvso1Y`5>=4?K0o`0INg}8XZ61BXv;C^eg5a^xUG{&p}%v#vO$0s?<7XC#4CX<|w zjzNFl(!$d5bem-}#&YNj(Wmxd`a0Hji{)$9h!q>VS3WG(uUvi~&RMzw9&q+9?c(^` Q-KATS%ic;ZgDVIA0kS|e1poj5 diff --git a/wasm_for_tests/tx_mint_tokens.wasm b/wasm_for_tests/tx_mint_tokens.wasm index 72e1e8f075a1bc7c0f7061848deb59e2bbb37dd9..e3bd3e5724de626414d994fe376b8bd934b16aec 100755 GIT binary patch delta 69043 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 z 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 Oll{3RHc#iajsO4|rb*TS delta 248 zcmca~obl3e#tF(wb#)90O!f5)35@lObqTEXAi!A9%*(^V%E-pZ#LmDx(KVfolZ%^` zonzuAZ6*efiT7=}H#8n#a6ADd1lT64Gp3{PXEHjAKLAT9G4nDgFexxOa%3s6DliGK zPX5ejzy^_*{m##ybK-+jE;=n zMMb;}4BV6BINc#uf$Rrby@9h5g>S+YwpoSUhKYlPL4lE*g~4(18n%kbQ@CzU4&~O` JJe}J*0sxSCMNt3% diff --git a/wasm_for_tests/tx_proposal_code.wasm b/wasm_for_tests/tx_proposal_code.wasm index 584ebfdcb192dc64c52f445596312cd0127c8d51..2124f281201c5e2012436d61d4b7c06b3065587f 100755 GIT binary patch delta 46300 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 j<=2U1getw_-Tgs%KI-Yv!d7gUe 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 delta 14135 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 af9l3tvIX*^mUCct9?HJnS=^mR82<-6Rf;75 diff --git a/wasm_for_tests/tx_write_storage_key.wasm b/wasm_for_tests/tx_write_storage_key.wasm index 2831315a06674278bd7e2bc8a224b3fa4ffc7634..684c3d378bbe8eb05fa74135f740e064dfceba51 100755 GIT binary patch delta 45535 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 Y>EwPoxoTA1n-($t-O=J7(xRdKe@#wpoB#j- delta 44185 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 z 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 P)kks*@8%ZZoB6*05zbo| delta 1320 zcma)6TWpj?6rMBl@4x?cyX_|QPLj0uLI#Do~oRD&iMjSuzA5+8`hI1lH{ zcdm2JoSEgTu4`9all4I(O$*W~hvsRPf;1dSF_scXGGa3$)&|bZZtD5sgvA}e1#>X~ z0bpeDY>$(34#0skCjiM!)0G3X971qyCbSSNgJ70nt_~-dQ(ui&hJ#PHJK|dt zc{#b>>U@7$`MQcgio1fZLA8UK2yQeeRm33R;7?i>Uo`7zmx8Y0iy~mBI zWC1Sm9Jgcv?)3{BqT_g%M>$L22Jt>I^@FG~H809)cDN_rz0B-cBHnGdH}{2y@U7hD z!b=&IUwD}0lH1mhq>Z-|Bi?HBfliHh*HCFOb!yc+LbL(k=EB;131s$ciMEzvD8wzB zxltV}Tm;-!T&2>*A99#bb)`QFVr4R{BjC=p13J)^wOnoV7Se@xD>}f1kw7_E*cT`wdMJ=^`mGSJmX=xybU4JkCD6CN zWslF4PJ4n6RWfFOl8$?rTblN(e8}&V(B|P12nM^84Izv1!8{D)5+G);0+-vL3 z`AnN>6_e(W_WwH`XgBng+u@YJ%1^#&jxO*a4o)nusf6z^S@T<= zbW}0s2fOHiU3AcI*eqeBC39eZEmE8A*O~&CT`b7btf~8Z*MQ;B>i~D2B=Z@c5LC$fT7+2 zqI11zXiz0P13;j;FG+N|?*iDWVb^QmWN}He8pp*{7#dFZ(?G^?Pk#-0%=X{Z9tQ@x z2rLd{8DOce_oYqBvV9~7HF#{~9&E+;L@kSd8Wo+V}7GFnU7;)6oZy zRL>th+QI3UAHvJiJ?b0W#4UqKa2w3V=kPGbXXbSwf6jDkmYhAW|ARkf2_;nLS)V=( hzBs3q>a)4s^hc?xH^X@tUwG{3$%PM2F2Joze*t`8QY8QY diff --git a/wasm_for_tests/vp_eval.wasm b/wasm_for_tests/vp_eval.wasm index 8711cfca76723154a25f603751343bff408550e6..3bf4ac8028c7b69e88e88bf82be1bab63575a551 100755 GIT binary patch delta 1211 zcmY*YYiL|W6rM9P_m!KQEHQNRsP^tg>0**5q$Nw!r0(R=&0}da%_f#g+;rPUH;5(} zO+j;g5dBq58Ej(GmX@NHf+1yStOy!Kq=8!M&yr%bP=X5iQN$mD;+aiFIzP^tbHDSQ znfdNH_kVCcyy48W>@fnpNQP?%K?VYt$`FzQ^t9SYY@2xnAXWZ zro-)x@jcvpD#7+Ox9sii={wLrF!*f2KXL{hg%!C7X|$aF$kshq{^D$r8??w1#3wNt ziZTJoN@=kq4Z7viY#E)hd9A5^yr9i+R~A=@m_ZXt%jx2m9*X}iZVO+`Ls8}tpZZkT zIUhHn0XZ0|H#aeLBD9UsAf*-`xx|bVKtSc8@J?{$&15N@QWwJ4@Qr~SEw2Sv&6R&a zVMX%+B^(~DiI`v^pep1(_CHTFrhk_~N4K;9A9%=Zq zoCa9Ts3jx{qU=>sHWB55?Dt589NQ^TLSxqphS8o^{gvI-4^+RYmUbI?)vq)?iK^de z68OtgDk@62_Kh7Q)ac5S&L!&~kZ!4a$)f*B@=nt>+1xd>#lc<@T1U5#w9eoC?yuD^ zug_WPOxIP=wFZ0AoM9uYZ+quB+ZcUZ4)?dK^Zk{1^sDrGzBxWU_yLDD86V1`T^I_W zO;tW00}R?TeQ0Mh7okHXhTj1TI#GM*l&gp12tYPVF*ufOK*~qiHBFf~dH{pfqb1yM zBDU|S+b^E8pjEy(R)_Ypu>ojRe0-flhfEA_Rrc%0@>Pqms+ySGj+5D`&K}>On0Dfg zBMu08f4UlkdhETu;JKrM_Tv0R1y5G0k@qj#dRQuEl<5U2Yy{{TANL4xW%vA~GUuA9 zynU);b8d78;2hP=9)BoanjLUB@xkS&qx@!mQ9o#GA+6oDg^%@UzI-~ZPx=0IL|;z+ jdPajParQ8Sgt~A(St{vriM)QL?A_Ak&r6r#r=@=Zo5M&e delta 1198 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 R&9v{CiRtqb)6n~?e*;vuZe;)f delta 2355 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 From c25a85225cc19a16056ef16589074c6b39c1d362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 16 Dec 2022 18:34:37 +0100 Subject: [PATCH 034/166] changelog: add #912 --- .changelog/unreleased/bugs/912-remove-prefix-iter.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/unreleased/bugs/912-remove-prefix-iter.md diff --git a/.changelog/unreleased/bugs/912-remove-prefix-iter.md b/.changelog/unreleased/bugs/912-remove-prefix-iter.md new file mode 100644 index 0000000000..20e553a8a7 --- /dev/null +++ b/.changelog/unreleased/bugs/912-remove-prefix-iter.md @@ -0,0 +1,3 @@ +- Removed 'rev_iter_prefix' from storage API as its implementation + depends on RocksDB and it doesn't work as expected. + ([#912](https://github.com/anoma/namada/pull/912)) From 65339b16eae7099d67828f5511b6ef82ed2776f3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 17 Dec 2022 10:59:54 +0000 Subject: [PATCH 035/166] [ci] wasm checksums update --- wasm/checksums.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/wasm/checksums.json b/wasm/checksums.json index b13508300c..5bd0a33931 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,20 +1,20 @@ { - "tx_bond.wasm": "tx_bond.be9c75f96b3b4880b7934d42ee218582b6304f6326a4588d1e6ac1ea4cc61c49.wasm", + "tx_bond.wasm": "tx_bond.852a22bb75acb8bbedd7ca1511af6e10b5a1f191ac80f5a6c7b5228bb79c6aed.wasm", "tx_change_validator_commission.wasm": "tx_change_validator_commission.cd861e0e82f4934be6d8382d6fff98286b4fadbc20ab826b9e817f6666021273.wasm", - "tx_ibc.wasm": "tx_ibc.13daeb0c88abba264d3052129eda0713bcf1a71f6f69bf37ec2494d0d9119f1f.wasm", - "tx_init_account.wasm": "tx_init_account.e21cfd7e96802f8e841613fb89f1571451401d002a159c5e9586855ac1374df5.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.b9a77bc9e416f33f1e715f25696ae41582e1b379422f7a643549884e0c73e9de.wasm", - "tx_init_validator.wasm": "tx_init_validator.1e9732873861c625f239e74245f8c504a57359c06614ba40387a71811ca4a097.wasm", + "tx_ibc.wasm": "tx_ibc.eb7d0f6c7cba4fcc402f32ed6a09bf70827521c5539b6393e2078f3931e8fccd.wasm", + "tx_init_account.wasm": "tx_init_account.87ece7f13b327f7d15c5b6e7083b510debb1c3205bafe9e36457c8585beeb49c.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.c39152be5435cf3f7588ddcde82b801e98902079a152ae3df30bac69833e3ebb.wasm", + "tx_init_validator.wasm": "tx_init_validator.56d563e4b9001790d9089ff91c6c98cde95032fb57d97122e58e8b5e363fc13f.wasm", "tx_reveal_pk.wasm": "tx_reveal_pk.47bc922a8be5571620a647ae442a1af7d03d05d29bef95f0b32cdfe00b11fee9.wasm", - "tx_transfer.wasm": "tx_transfer.bbd1ef5d9461c78f0288986de046baad77e10671addc5edaf3c68ea1ae4ecc99.wasm", + "tx_transfer.wasm": "tx_transfer.c75399e44b86e22084937b69b2f6c9b9ae112706ac9f8c472d3646fc36cfaa06.wasm", "tx_unbond.wasm": "tx_unbond.c0a690d0ad43a94294a6405bae3327f638a657446c74dc61dbb3a4d2ce488b5e.wasm", "tx_update_vp.wasm": "tx_update_vp.ee2e9b882c4accadf4626e87d801c9ac8ea8c61ccea677e0532fc6c1ee7db6a2.wasm", "tx_vote_proposal.wasm": "tx_vote_proposal.263fd9f4cb40f283756f394d86bdea3417e9ecd0568d6582c07a5b6bd14287d6.wasm", - "tx_withdraw.wasm": "tx_withdraw.6ce8faf6a32340178ddeaeb91a9b40e7f0433334e5c1f357964bf8e11d0077f1.wasm", - "vp_implicit.wasm": "vp_implicit.17f5c2af947ccfadce22d0fffecde1a1b4bc4ca3acd5dd8b459c3dce4afcb4e8.wasm", + "tx_withdraw.wasm": "tx_withdraw.db97f19c3217167374f9163fc4d3738117be23041d75068e97b269e6f9810ec8.wasm", + "vp_implicit.wasm": "vp_implicit.0b6b00b4663aa2c747d51bb0fda2da0454615bcdac345011131e3372ca2598a9.wasm", "vp_masp.wasm": "vp_masp.5620cb6e555161641337d308851c760fbab4f9d3693cfd378703aa55e285249d.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.362584b063cc4aaf8b72af0ed8af8d05a179ebefec596b6ab65e0ca255ec3c80.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.e5df211c9016a8d5ffbba980859470e0c7abbbdf900263830585fb49fa75623d.wasm", "vp_token.wasm": "vp_token.a289723dd182fe0206e6c4cf1f426a6100787b20e2653d2fad6031e8106157f3.wasm", - "vp_user.wasm": "vp_user.b83b2d0616bb2244c8a92021665a0be749282a53fe1c493e98c330a6ed983833.wasm", - "vp_validator.wasm": "vp_validator.59e3e7729e14eeacc17d76b736d1760d59a1a6e9d6acbc9a870e1835438f524a.wasm" + "vp_user.wasm": "vp_user.91b6389650a83702c66e220893211b94cdce784d1e18ca8433c69964fc0967ea.wasm", + "vp_validator.wasm": "vp_validator.5175c7aeb34657b9fbe4211031c628e6e834037c26f4cc290bfb50f301d41138.wasm" } \ No newline at end of file From 5db7cb1eed5583e1ff52e8cea19eeac5bd3780db Mon Sep 17 00:00:00 2001 From: Bengt Date: Sun, 18 Dec 2022 02:26:45 +0000 Subject: [PATCH 036/166] fixed hardware recommendations --- .../docs/src/user-guide/install/hardware.md | 6 ++-- shared/src/proto/generated/google.protobuf.rs | 0 shared/src/proto/generated/types.rs | 28 +++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 shared/src/proto/generated/google.protobuf.rs create mode 100644 shared/src/proto/generated/types.rs diff --git a/documentation/docs/src/user-guide/install/hardware.md b/documentation/docs/src/user-guide/install/hardware.md index 176c82be46..b0d3799630 100644 --- a/documentation/docs/src/user-guide/install/hardware.md +++ b/documentation/docs/src/user-guide/install/hardware.md @@ -6,6 +6,6 @@ This section covers the minimum and recommended hardware requirements for engagi | Hardware | Minimal Specifications | | -------- | -------- | -| CPU | x86_64 or arm64 processor with at least 4 physical cores | -| RAM | 16GB DDR4 | -| Storage | at least 60GB SSD (NVMe SSD is recommended. HDD will be enough for localnet only) | \ No newline at end of file +| CPU | x86_64 or arm64 processor with at least 4 physical cores (must support AVX/SSE instruction set) | +| RAM | 8GB DDR4 | +| Storage | at least 500GB SSD (NVMe SSD is recommended. HDD will also work.) | \ No newline at end of file diff --git a/shared/src/proto/generated/google.protobuf.rs b/shared/src/proto/generated/google.protobuf.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared/src/proto/generated/types.rs b/shared/src/proto/generated/types.rs new file mode 100644 index 0000000000..948fc278bc --- /dev/null +++ b/shared/src/proto/generated/types.rs @@ -0,0 +1,28 @@ +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Tx { + #[prost(bytes="vec", tag="1")] + pub code: ::prost::alloc::vec::Vec, + /// TODO this optional is useless because it's default on proto3 + #[prost(bytes="vec", optional, tag="2")] + pub data: ::core::option::Option<::prost::alloc::vec::Vec>, + #[prost(message, optional, tag="3")] + pub timestamp: ::core::option::Option<::prost_types::Timestamp>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Dkg { + #[prost(string, tag="1")] + pub data: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DkgGossipMessage { + #[prost(oneof="dkg_gossip_message::DkgMessage", tags="1")] + pub dkg_message: ::core::option::Option, +} +/// Nested message and enum types in `DkgGossipMessage`. +pub mod dkg_gossip_message { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum DkgMessage { + #[prost(message, tag="1")] + Dkg(super::Dkg), + } +} From aa61baa9c6a9e27b5ffcb069ece04398c911777c Mon Sep 17 00:00:00 2001 From: bengtlofgren <51077282+bengtlofgren@users.noreply.github.com> Date: Sun, 18 Dec 2022 02:28:14 +0000 Subject: [PATCH 037/166] Delete types.rs --- shared/src/proto/generated/types.rs | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 shared/src/proto/generated/types.rs diff --git a/shared/src/proto/generated/types.rs b/shared/src/proto/generated/types.rs deleted file mode 100644 index 948fc278bc..0000000000 --- a/shared/src/proto/generated/types.rs +++ /dev/null @@ -1,28 +0,0 @@ -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct Tx { - #[prost(bytes="vec", tag="1")] - pub code: ::prost::alloc::vec::Vec, - /// TODO this optional is useless because it's default on proto3 - #[prost(bytes="vec", optional, tag="2")] - pub data: ::core::option::Option<::prost::alloc::vec::Vec>, - #[prost(message, optional, tag="3")] - pub timestamp: ::core::option::Option<::prost_types::Timestamp>, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct Dkg { - #[prost(string, tag="1")] - pub data: ::prost::alloc::string::String, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct DkgGossipMessage { - #[prost(oneof="dkg_gossip_message::DkgMessage", tags="1")] - pub dkg_message: ::core::option::Option, -} -/// Nested message and enum types in `DkgGossipMessage`. -pub mod dkg_gossip_message { - #[derive(Clone, PartialEq, ::prost::Oneof)] - pub enum DkgMessage { - #[prost(message, tag="1")] - Dkg(super::Dkg), - } -} From c9125a4e6f8d2bfba82294931a6c6d1909441695 Mon Sep 17 00:00:00 2001 From: bengtlofgren <51077282+bengtlofgren@users.noreply.github.com> Date: Sun, 18 Dec 2022 02:28:27 +0000 Subject: [PATCH 038/166] Delete google.protobuf.rs --- shared/src/proto/generated/google.protobuf.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 shared/src/proto/generated/google.protobuf.rs diff --git a/shared/src/proto/generated/google.protobuf.rs b/shared/src/proto/generated/google.protobuf.rs deleted file mode 100644 index e69de29bb2..0000000000 From 62ff16498ef31ddfad2ec1dd65daa5737b21e993 Mon Sep 17 00:00:00 2001 From: Awa Sun Yin <11296013+awasunyin@users.noreply.github.com> Date: Sun, 18 Dec 2022 14:26:07 +0100 Subject: [PATCH 039/166] Update environment-setup.md Fixed namada version --- documentation/docs/src/testnets/environment-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/src/testnets/environment-setup.md b/documentation/docs/src/testnets/environment-setup.md index 358cf016b1..3e3af28064 100644 --- a/documentation/docs/src/testnets/environment-setup.md +++ b/documentation/docs/src/testnets/environment-setup.md @@ -51,4 +51,4 @@ - Make sure you are using the correct tendermint version - `tendermint version` should output `0.1.4-abciplus` - Make sure you are using the correct Namada version - - `namada --version` should output `Namada v0.11.0` + - `namada --version` should output `Namada v0.12.0` From 2b2256acb6f9d975be3f285a27eaa8da47456bc0 Mon Sep 17 00:00:00 2001 From: Bengt Date: Sun, 18 Dec 2022 16:10:35 +0000 Subject: [PATCH 040/166] fixed broken links --- documentation/docs/src/quick-start.md | 4 ++-- documentation/docs/src/user-guide/overview-of-binaries.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/docs/src/quick-start.md b/documentation/docs/src/quick-start.md index 4f2620e1e9..33cbf970a7 100644 --- a/documentation/docs/src/quick-start.md +++ b/documentation/docs/src/quick-start.md @@ -14,7 +14,7 @@ This guide is for those interested in operating a Namada validator node and assu ## Installing Namada -See [the installation guide](user-guide/install/README.md) for details on installing the Namada binaries. Commands in this guide will assume you have the Namada binaries (`namada`, `namadan`, `namadaw`, `namadac`) on your $PATH. +See [the installation guide](./user-guide/install/) for details on installing the Namada binaries. Commands in this guide will assume you have the Namada binaries (`namada`, `namadan`, `namadaw`, `namadac`) on your $PATH. A simple way to add these binaries to one's path is to run ```shell @@ -23,7 +23,7 @@ cp namada/target/release/namada* /usr/local/bin/ ## Joining a network -See [the testnets page](testnets) for details of how to join a testnet. The rest of this guide will assume you have joined a testnet chain using the `namadac utils join-network` command. +See [the testnets page](./testnets) for details of how to join a testnet. The rest of this guide will assume you have joined a testnet chain using the `namadac utils join-network` command. ## Run a ledger node diff --git a/documentation/docs/src/user-guide/overview-of-binaries.md b/documentation/docs/src/user-guide/overview-of-binaries.md index 21686064d9..5863cd88bd 100644 --- a/documentation/docs/src/user-guide/overview-of-binaries.md +++ b/documentation/docs/src/user-guide/overview-of-binaries.md @@ -1,6 +1,6 @@ # Overview of binaries -This guide assumes that the Namada binaries are [installed](./install/README.md) and available on path. These are: +This guide assumes that the Namada binaries are [installed](./install/) and available on path. These are: - `namada`: The main binary that can be used to interact with all the components of Namada - `namadan`: The ledger node From 445d538835fd22df91d289fc5ffb1763effcce45 Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Mon, 19 Dec 2022 14:08:27 +0100 Subject: [PATCH 041/166] ci: run when merged to main --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 6bd95c514e..26f1e736a5 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -128,10 +128,10 @@ jobs: name: ${{ matrix.make.bucket }}-${{ github.event.pull_request.head.sha || github.sha }} path: ${{ matrix.make.bucket }}.tar - name: Publish docs - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + if: ${{ github.ref == 'refs/heads/main' }} run: aws s3 sync ${{ matrix.make.folder }}/book/html/ s3://${{ matrix.make.bucket }} --region eu-west-1 --delete - name: Invalidate distribution cache - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + if: ${{ github.ref == 'refs/heads/main' }} run: aws cloudfront create-invalidation --distribution-id ${{ matrix.make.distribution_id }} --paths "/*" - name: Print sccache stats if: always() From 99a6c29aac27327b1742faf895f815697233fb72 Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Mon, 19 Dec 2022 14:11:22 +0100 Subject: [PATCH 042/166] ci: use correct tendermint version in e2e test --- .github/workflows/build-and-test-bridge.yml | 4 ++-- .github/workflows/build-and-test.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-and-test-bridge.yml b/.github/workflows/build-and-test-bridge.yml index 6ea02f2a59..1e0827f724 100644 --- a/.github/workflows/build-and-test-bridge.yml +++ b/.github/workflows/build-and-test-bridge.yml @@ -357,14 +357,14 @@ jobs: index: 0 cache_key: namada cache_version: v2 - tendermint_artifact: tendermint-unreleased-ad825dcadbd4b98c3f91ce5a711e4fb36a69c377 + tendermint_artifact: tendermint-unreleased-v0.1.4-abciplus wait_for: namada-release-eth (ubuntu-20.04, 1.7.0, ABCI Release build, namada-e2e-release, v2) - name: e2e suffix: '' index: 1 cache_key: namada cache_version: v2 - tendermint_artifact: tendermint-unreleased-ad825dcadbd4b98c3f91ce5a711e4fb36a69c377 + tendermint_artifact: tendermint-unreleased-v0.1.4-abciplus wait_for: namada-release-eth (ubuntu-20.04, 1.7.0, ABCI Release build, namada-e2e-release, v2) env: diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 3833e263fa..ae3be0fb0b 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -359,14 +359,14 @@ jobs: index: 0 cache_key: namada cache_version: v2 - tendermint_artifact: tendermint-unreleased-ad825dcadbd4b98c3f91ce5a711e4fb36a69c377 + tendermint_artifact: tendermint-unreleased-v0.1.4-abciplus wait_for: namada-release (ubuntu-20.04, 1.7.0, ABCI Release build, namada-e2e-release, v2) - name: e2e suffix: '' index: 1 cache_key: namada cache_version: v2 - tendermint_artifact: tendermint-unreleased-ad825dcadbd4b98c3f91ce5a711e4fb36a69c377 + tendermint_artifact: tendermint-unreleased-v0.1.4-abciplus wait_for: namada-release (ubuntu-20.04, 1.7.0, ABCI Release build, namada-e2e-release, v2) env: From f797b4c7664263afaf06ed7103699f2819f970ee Mon Sep 17 00:00:00 2001 From: Bengt Date: Mon, 19 Dec 2022 15:46:12 +0000 Subject: [PATCH 043/166] correct genesis time --- documentation/docs/src/testnets/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/docs/src/testnets/README.md b/documentation/docs/src/testnets/README.md index dc8b89bcba..d090eecf4f 100644 --- a/documentation/docs/src/testnets/README.md +++ b/documentation/docs/src/testnets/README.md @@ -24,11 +24,11 @@ All public testnets will be listed here: - Namada public testnet 1: - Namada protocol version: `v0.12.0` - Tendermint version: `v0.1.4-abciplus` - - Genesis time: 21st of December 2022 at 17:00 UTC + - Genesis time: 20th of December 2022 at 17:00 UTC - CHAIN_ID: `TBD` ## Block explorer The block explorer is currently in development. The latest version can be found at [namada.world](https://namada.world/) ## Community -For questions or feedback, feel free to post or comment on [Reddit](https://www.reddit.com/r/namada) or [Github](https://github.com/anoma/namada/issues). Don't forget to [follow Namada](https://twitter.com/namadanetwork) on Twitter for testnet relevant updates. \ No newline at end of file +For questions or feedback, feel free to post or comment on [Reddit](https://www.reddit.com/r/namada) or [Github](https://github.com/anoma/namada/issues). Don't forget to [follow Namada](https://twitter.com/namadanetwork) on Twitter for testnet relevant updates.S \ No newline at end of file From ae7ef1ddbf6765ef4c556106c3f72827d7d60f20 Mon Sep 17 00:00:00 2001 From: Bengt Date: Mon, 19 Dec 2022 15:48:17 +0000 Subject: [PATCH 044/166] typo --- documentation/docs/src/testnets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/src/testnets/README.md b/documentation/docs/src/testnets/README.md index d090eecf4f..f7a01da96e 100644 --- a/documentation/docs/src/testnets/README.md +++ b/documentation/docs/src/testnets/README.md @@ -31,4 +31,4 @@ All public testnets will be listed here: The block explorer is currently in development. The latest version can be found at [namada.world](https://namada.world/) ## Community -For questions or feedback, feel free to post or comment on [Reddit](https://www.reddit.com/r/namada) or [Github](https://github.com/anoma/namada/issues). Don't forget to [follow Namada](https://twitter.com/namadanetwork) on Twitter for testnet relevant updates.S \ No newline at end of file +For questions or feedback, feel free to post or comment on [Reddit](https://www.reddit.com/r/namada) or [Github](https://github.com/anoma/namada/issues). Don't forget to [follow Namada](https://twitter.com/namadanetwork) on Twitter for testnet relevant updates. \ No newline at end of file From 72deb2a01f006d7681e6890236801008d2d56721 Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Mon, 19 Dec 2022 16:49:02 +0100 Subject: [PATCH 045/166] ci: update docs only on main --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 26f1e736a5..b859db7748 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -128,10 +128,10 @@ jobs: name: ${{ matrix.make.bucket }}-${{ github.event.pull_request.head.sha || github.sha }} path: ${{ matrix.make.bucket }}.tar - name: Publish docs - if: ${{ github.ref == 'refs/heads/main' }} + if: ${{ github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main' }} run: aws s3 sync ${{ matrix.make.folder }}/book/html/ s3://${{ matrix.make.bucket }} --region eu-west-1 --delete - name: Invalidate distribution cache - if: ${{ github.ref == 'refs/heads/main' }} + if: ${{ github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main' }} run: aws cloudfront create-invalidation --distribution-id ${{ matrix.make.distribution_id }} --paths "/*" - name: Print sccache stats if: always() From 8b76cdc856380d39961738ee5db478251aafebf8 Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Mon, 19 Dec 2022 17:11:08 +0100 Subject: [PATCH 046/166] ci: update docs only on main --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b859db7748..6bd95c514e 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -128,10 +128,10 @@ jobs: name: ${{ matrix.make.bucket }}-${{ github.event.pull_request.head.sha || github.sha }} path: ${{ matrix.make.bucket }}.tar - name: Publish docs - if: ${{ github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} run: aws s3 sync ${{ matrix.make.folder }}/book/html/ s3://${{ matrix.make.bucket }} --region eu-west-1 --delete - name: Invalidate distribution cache - if: ${{ github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} run: aws cloudfront create-invalidation --distribution-id ${{ matrix.make.distribution_id }} --paths "/*" - name: Print sccache stats if: always() From 5d9f3d70744a877b477335ccba77f62dbeae6f73 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Mon, 19 Dec 2022 14:53:10 +0000 Subject: [PATCH 047/166] Add StorageKeys derive macro --- Cargo.lock | 1 + macros/Cargo.toml | 1 + macros/src/lib.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++-- wasm/Cargo.lock | 1 + 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a0a9ae50b..60883727ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3843,6 +3843,7 @@ dependencies = [ name = "namada_macros" version = "0.12.0" dependencies = [ + "proc-macro2", "quote", "syn", ] diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 4bb96bbe49..c6b5dfca4d 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -10,5 +10,6 @@ version = "0.12.0" proc-macro = true [dependencies] +proc-macro2 = "1.0" quote = "1.0" syn = "1.0" diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 38a9882b40..03b80d8396 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -7,8 +7,10 @@ #![deny(rustdoc::private_intra_doc_links)] use proc_macro::TokenStream; -use quote::quote; -use syn::{parse_macro_input, ItemFn}; +use proc_macro2::{Span as Span2, TokenStream as TokenStream2}; +use quote::{quote, ToTokens}; +use syn::punctuated::Punctuated; +use syn::{parse_macro_input, ItemFn, ItemStruct}; /// Generate WASM binding for a transaction main entrypoint function. /// @@ -149,3 +151,89 @@ pub fn validity_predicate( }; TokenStream::from(gen) } + +#[proc_macro_derive(StorageKeys)] +// TODO: use this crate for errors: https://crates.io/crates/proc-macro-error +pub fn derive_storage_keys(item: TokenStream) -> TokenStream { + let struct_def = parse_macro_input!(item as ItemStruct); + + // type check the struct - all fields must be of type `&'static str` + let fields = match &struct_def.fields { + syn::Fields::Named(fields) => &fields.named, + _ => panic!( + "Only named struct fields are accepted in StorageKeys derives" + ), + }; + + let mut idents = vec![]; + + for field in fields { + let field_type = { + let mut toks = TokenStream2::new(); + field.ty.to_tokens(&mut toks); + toks.to_string() + }; + if field_type != "&'static str" { + panic!( + "Expected `&'static str` field type in StorageKeys derive, \ + but got {field_type} instead" + ); + } + idents.push(field.ident.clone().expect("Expected a named field")); + } + + idents.sort(); + + let ident_list = create_ponctuated(&idents, |ident| ident.clone()); + let values_list = create_ponctuated(&idents, |ident| { + let storage_key = { + let mut toks = TokenStream2::new(); + ident.to_tokens(&mut toks); + toks.to_string() + }; + syn::FieldValue { + attrs: vec![], + member: syn::Member::Named(ident.clone()), + colon_token: Some(syn::token::Colon { + spans: [Span2::call_site()], + }), + expr: syn::Expr::Lit(syn::ExprLit { + attrs: vec![], + lit: syn::Lit::Str(syn::LitStr::new( + storage_key.as_str(), + Span2::call_site(), + )), + }), + } + }); + + quote! { + impl #struct_def.ident { + const ALL: &[&'static str] = { + let #struct_def.ident { + #ident_list + } = Self::VALUES; + + &[ #ident_list ] + }; + + const VALUES: #struct_def.ident = Self { + #values_list + }; + } + } + .into() +} + +fn create_ponctuated( + idents: &[syn::Ident], + mut map: F, +) -> Punctuated +where + F: FnMut(&syn::Ident) -> M, +{ + idents.iter().fold(Punctuated::new(), |mut accum, ident| { + accum.push(map(ident)); + accum + }) +} diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index bd82ea3be8..a3f84ae2e1 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -2543,6 +2543,7 @@ dependencies = [ name = "namada_macros" version = "0.12.0" dependencies = [ + "proc-macro2", "quote", "syn", ] From 4ad37a161b4909cb16b40ddebefcbc341091e2fc Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Mon, 19 Dec 2022 15:08:38 +0000 Subject: [PATCH 048/166] Fix gen of identifier in StorageKeys proc-macro --- macros/src/lib.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 03b80d8396..6e65f450fe 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -207,17 +207,19 @@ pub fn derive_storage_keys(item: TokenStream) -> TokenStream { } }); + let struct_def_ident = &struct_def.ident; + quote! { - impl #struct_def.ident { + impl #struct_def_ident { const ALL: &[&'static str] = { - let #struct_def.ident { + let #struct_def_ident { #ident_list } = Self::VALUES; &[ #ident_list ] }; - const VALUES: #struct_def.ident = Self { + const VALUES: #struct_def_ident = Self { #values_list }; } From 028924e6bd168921f62bd2b7c3e8d451206613c7 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Mon, 19 Dec 2022 15:10:48 +0000 Subject: [PATCH 049/166] Fix static str type check --- macros/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 6e65f450fe..f0c64f95a8 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -173,7 +173,7 @@ pub fn derive_storage_keys(item: TokenStream) -> TokenStream { field.ty.to_tokens(&mut toks); toks.to_string() }; - if field_type != "&'static str" { + if field_type != "& 'static str" { panic!( "Expected `&'static str` field type in StorageKeys derive, \ but got {field_type} instead" From b4f94265de0ef3ad54ded4301b6644facd67b427 Mon Sep 17 00:00:00 2001 From: Memas Deligeorgakis Date: Mon, 19 Dec 2022 22:28:29 +0100 Subject: [PATCH 050/166] Replaced non-breaking space with space to fix faulty formatting --- documentation/specs/src/base-ledger/multisignature.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/specs/src/base-ledger/multisignature.md b/documentation/specs/src/base-ledger/multisignature.md index 7be36c156a..e169841ed4 100644 --- a/documentation/specs/src/base-ledger/multisignature.md +++ b/documentation/specs/src/base-ledger/multisignature.md @@ -45,7 +45,7 @@ To verify the correctness of the signatures, this VP will proceed with a two-ste Step 1 allows us to short-circuit the validation process and avoid unnecessary processing and storage access. Each signature will be validated **only** against the public key found in the list at the specified index. Step 2 will halt as soon as it retrieves enough valid signatures to match the threshold, meaning that the remaining signatures will not be verified. -## Addresses +## Addresses The vp introduced in the previous section is available for `established` addresses. To generate a multisig account we need to modify the `InitAccount` struct to support multiple public keys and a threshold, as follows: From 4b50ddd0052a4ed5e8d58b9a3eb7d5430e6779d3 Mon Sep 17 00:00:00 2001 From: Memas Deligeorgakis Date: Mon, 19 Dec 2022 22:52:01 +0100 Subject: [PATCH 051/166] Changed the first header of pages to H1 in 2 occasions in Namada Specs --- documentation/specs/src/base-ledger/default-account.md | 2 +- documentation/specs/src/base-ledger/fungible-token.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/specs/src/base-ledger/default-account.md b/documentation/specs/src/base-ledger/default-account.md index fc40d1d241..ed74374e36 100644 --- a/documentation/specs/src/base-ledger/default-account.md +++ b/documentation/specs/src/base-ledger/default-account.md @@ -1,3 +1,3 @@ -## Default account +# Default account The default account validity predicate authorises transactions on the basis of a cryptographic signature. \ No newline at end of file diff --git a/documentation/specs/src/base-ledger/fungible-token.md b/documentation/specs/src/base-ledger/fungible-token.md index 3fba3fbde2..b52fe37131 100644 --- a/documentation/specs/src/base-ledger/fungible-token.md +++ b/documentation/specs/src/base-ledger/fungible-token.md @@ -1,3 +1,3 @@ -## Fungible token +# Fungible token The fungible token validity predicate authorises token balance changes on the basis of conservation-of-supply and approval-by-sender. \ No newline at end of file From 6612ed87742c7bd2c29f80d14815c5d767af2589 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Tue, 20 Dec 2022 09:17:58 +0000 Subject: [PATCH 052/166] Update macros/src/lib.rs Co-authored-by: Tomas Zemanovic --- macros/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index f0c64f95a8..3e4c7cc861 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -227,7 +227,7 @@ pub fn derive_storage_keys(item: TokenStream) -> TokenStream { .into() } -fn create_ponctuated( +fn create_punctuated( idents: &[syn::Ident], mut map: F, ) -> Punctuated From 63a4fea75a6cbbde45a414912f413798e681d4d7 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Tue, 20 Dec 2022 09:18:08 +0000 Subject: [PATCH 053/166] Update macros/src/lib.rs Co-authored-by: Tomas Zemanovic --- macros/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 3e4c7cc861..0fe978dd52 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -184,8 +184,8 @@ pub fn derive_storage_keys(item: TokenStream) -> TokenStream { idents.sort(); - let ident_list = create_ponctuated(&idents, |ident| ident.clone()); - let values_list = create_ponctuated(&idents, |ident| { + let ident_list = create_punctuated(&idents, |ident| ident.clone()); + let values_list = create_punctuated(&idents, |ident| { let storage_key = { let mut toks = TokenStream2::new(); ident.to_tokens(&mut toks); From 9ac07db706779d93f83457b4a3e1f828f44d66d7 Mon Sep 17 00:00:00 2001 From: satan Date: Tue, 20 Dec 2022 11:59:33 +0100 Subject: [PATCH 054/166] Added unit test for the new proc macro --- macros/Cargo.toml | 2 +- macros/src/lib.rs | 50 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/macros/Cargo.toml b/macros/Cargo.toml index c6b5dfca4d..3dfbb42b58 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -12,4 +12,4 @@ proc-macro = true [dependencies] proc-macro2 = "1.0" quote = "1.0" -syn = "1.0" +syn = {version="1.0", features = ["full", "extra-traits"]} \ No newline at end of file diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 0fe978dd52..75ba85f96b 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -156,7 +156,10 @@ pub fn validity_predicate( // TODO: use this crate for errors: https://crates.io/crates/proc-macro-error pub fn derive_storage_keys(item: TokenStream) -> TokenStream { let struct_def = parse_macro_input!(item as ItemStruct); + create_storage_keys(struct_def).parse().unwrap() +} +fn create_storage_keys(struct_def: ItemStruct) -> String { // type check the struct - all fields must be of type `&'static str` let fields = match &struct_def.fields { syn::Fields::Named(fields) => &fields.named, @@ -168,11 +171,7 @@ pub fn derive_storage_keys(item: TokenStream) -> TokenStream { let mut idents = vec![]; for field in fields { - let field_type = { - let mut toks = TokenStream2::new(); - field.ty.to_tokens(&mut toks); - toks.to_string() - }; + let field_type = field.ty.to_token_stream().to_string(); if field_type != "& 'static str" { panic!( "Expected `&'static str` field type in StorageKeys derive, \ @@ -223,8 +222,7 @@ pub fn derive_storage_keys(item: TokenStream) -> TokenStream { #values_list }; } - } - .into() + }.to_string() } fn create_punctuated( @@ -239,3 +237,41 @@ where accum }) } + + +#[cfg(test)] +mod test_proc_macros { + use syn::ItemImpl; + use super::*; + + + /// Test that the create storage keys produces + /// the expected code. + #[test] + fn test_create_storage_keys() { + const TEST: &str = r#" + struct Keys { + param1: &'static str, + param2: &'static str, + } + "#; + + const EXPECT: &str = r#" + impl Keys { + const ALL: &[&'static str] = { + let Keys { param1 , param2 } = Self::VALUES; + &[param1, param2] + }; + const VALUES: Keys = Self { + param1: "param1", + param2: "param2" + }; + } + "#; + let struct_def = syn::parse_str(TEST).unwrap(); + let result = create_storage_keys(struct_def); + let result: ItemImpl = syn::parse_str(&result).unwrap(); + let expected = syn::parse_str(EXPECT).unwrap(); + assert_eq!(result, expected); + } +} \ No newline at end of file From 306829f51b8ac02d734aed231aa6b2eadc48066b Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Tue, 20 Dec 2022 11:21:39 +0000 Subject: [PATCH 055/166] Format and inline some code --- macros/src/lib.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 75ba85f96b..a543302d56 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -159,6 +159,7 @@ pub fn derive_storage_keys(item: TokenStream) -> TokenStream { create_storage_keys(struct_def).parse().unwrap() } +#[inline] fn create_storage_keys(struct_def: ItemStruct) -> String { // type check the struct - all fields must be of type `&'static str` let fields = match &struct_def.fields { @@ -175,7 +176,7 @@ fn create_storage_keys(struct_def: ItemStruct) -> String { if field_type != "& 'static str" { panic!( "Expected `&'static str` field type in StorageKeys derive, \ - but got {field_type} instead" + but got `{field_type}` instead" ); } idents.push(field.ident.clone().expect("Expected a named field")); @@ -222,9 +223,11 @@ fn create_storage_keys(struct_def: ItemStruct) -> String { #values_list }; } - }.to_string() + } + .to_string() } +#[inline] fn create_punctuated( idents: &[syn::Ident], mut map: F, @@ -238,12 +241,11 @@ where }) } - #[cfg(test)] mod test_proc_macros { use syn::ItemImpl; - use super::*; + use super::*; /// Test that the create storage keys produces /// the expected code. @@ -274,4 +276,4 @@ mod test_proc_macros { let expected = syn::parse_str(EXPECT).unwrap(); assert_eq!(result, expected); } -} \ No newline at end of file +} From 189e9b6e1145d38dc77c419bc2d2561d8ea4a41e Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Tue, 20 Dec 2022 11:27:17 +0000 Subject: [PATCH 056/166] Some TODO items --- macros/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index a543302d56..d8e271f60a 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -160,6 +160,7 @@ pub fn derive_storage_keys(item: TokenStream) -> TokenStream { } #[inline] +// TODO: emit allow_deadcode in ALL and VALUES fn create_storage_keys(struct_def: ItemStruct) -> String { // type check the struct - all fields must be of type `&'static str` let fields = match &struct_def.fields { @@ -245,11 +246,15 @@ where mod test_proc_macros { use syn::ItemImpl; + // TODO: check if type checking fails for non-static str field + // types, check if the generated `ALL` is sorted, ??? + use super::*; /// Test that the create storage keys produces /// the expected code. #[test] + // TODO: use quote! to get formatted expected code fn test_create_storage_keys() { const TEST: &str = r#" struct Keys { From a74d8e38540ec2e0f827e5282e17d1b23b701665 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Tue, 20 Dec 2022 13:01:59 +0000 Subject: [PATCH 057/166] Use quote!() in macro test --- macros/src/lib.rs | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index d8e271f60a..16f4ebc101 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -153,15 +153,17 @@ pub fn validity_predicate( } #[proc_macro_derive(StorageKeys)] -// TODO: use this crate for errors: https://crates.io/crates/proc-macro-error -pub fn derive_storage_keys(item: TokenStream) -> TokenStream { - let struct_def = parse_macro_input!(item as ItemStruct); - create_storage_keys(struct_def).parse().unwrap() +pub fn derive_storage_keys(struct_def: TokenStream) -> TokenStream { + derive_storage_keys_inner(struct_def.into()).into() } #[inline] +// TODO: use this crate for errors: https://crates.io/crates/proc-macro-error // TODO: emit allow_deadcode in ALL and VALUES -fn create_storage_keys(struct_def: ItemStruct) -> String { +fn derive_storage_keys_inner(struct_def: TokenStream2) -> TokenStream2 { + let struct_def: ItemStruct = syn::parse2(struct_def) + .expect("Expected a struct in the StorageKeys derive"); + // type check the struct - all fields must be of type `&'static str` let fields = match &struct_def.fields { syn::Fields::Named(fields) => &fields.named, @@ -225,7 +227,6 @@ fn create_storage_keys(struct_def: ItemStruct) -> String { }; } } - .to_string() } #[inline] @@ -248,25 +249,26 @@ mod test_proc_macros { // TODO: check if type checking fails for non-static str field // types, check if the generated `ALL` is sorted, ??? - use super::*; /// Test that the create storage keys produces /// the expected code. #[test] - // TODO: use quote! to get formatted expected code - fn test_create_storage_keys() { - const TEST: &str = r#" + fn test_derive_storage_keys() { + let test_struct: TokenStream2 = quote! { struct Keys { param1: &'static str, param2: &'static str, } - "#; + }; + let test_impl: ItemImpl = + syn::parse2(derive_storage_keys_inner(test_struct)) + .expect("Test failed"); - const EXPECT: &str = r#" + let expected_impl: TokenStream2 = quote! { impl Keys { const ALL: &[&'static str] = { - let Keys { param1 , param2 } = Self::VALUES; + let Keys { param1, param2 } = Self::VALUES; &[param1, param2] }; const VALUES: Keys = Self { @@ -274,11 +276,10 @@ mod test_proc_macros { param2: "param2" }; } - "#; - let struct_def = syn::parse_str(TEST).unwrap(); - let result = create_storage_keys(struct_def); - let result: ItemImpl = syn::parse_str(&result).unwrap(); - let expected = syn::parse_str(EXPECT).unwrap(); - assert_eq!(result, expected); + }; + let expected_impl: ItemImpl = + syn::parse2(expected_impl).expect("Test failed"); + + assert_eq!(test_impl, expected_impl); } } From f79f1b08ff341ee12a04238114c1ce98a8ee1cc3 Mon Sep 17 00:00:00 2001 From: Bengt Date: Tue, 20 Dec 2022 13:35:40 +0000 Subject: [PATCH 058/166] changed the docker link (again) --- documentation/docs/src/user-guide/install/from-docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/src/user-guide/install/from-docker.md b/documentation/docs/src/user-guide/install/from-docker.md index d4b2febbc5..745c0d71c8 100644 --- a/documentation/docs/src/user-guide/install/from-docker.md +++ b/documentation/docs/src/user-guide/install/from-docker.md @@ -1,3 +1,3 @@ ## From Docker -Go to [heliaxdev dockerhub account](https://hub.docker.com/r/heliaxdev/namada) and pull the image. \ No newline at end of file +The Namada docker image can be found [here](https://github.com/anoma/namada/pkgs/container/namada) \ No newline at end of file From fe53976459dfce0cd91392336356c0dd4f6deb4b Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Tue, 20 Dec 2022 14:25:54 +0000 Subject: [PATCH 059/166] Add StorageKeys unit tests --- Cargo.lock | 1 + macros/Cargo.toml | 5 ++- macros/src/lib.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 83 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 60883727ba..657c6b6e41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3843,6 +3843,7 @@ dependencies = [ name = "namada_macros" version = "0.12.0" dependencies = [ + "itertools", "proc-macro2", "quote", "syn", diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 3dfbb42b58..32ff437bf6 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -12,4 +12,7 @@ proc-macro = true [dependencies] proc-macro2 = "1.0" quote = "1.0" -syn = {version="1.0", features = ["full", "extra-traits"]} \ No newline at end of file +syn = {version="1.0", features = ["full", "extra-traits"]} + +[dev-dependencies] +itertools = "0.10.1" diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 16f4ebc101..067e2eebb3 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -245,17 +245,91 @@ where #[cfg(test)] mod test_proc_macros { + use itertools::Itertools; use syn::ItemImpl; - // TODO: check if type checking fails for non-static str field - // types, check if the generated `ALL` is sorted, ??? use super::*; + /// Test if the `ALL` slice generated in `StorageKeys` macro + /// derives is sorted in ascending order. + #[test] + fn test_storage_keys_derive_sorted_slice() { + let test_struct = quote! { + struct Keys { + word: &'static str, + is: &'static str, + bird: &'static str, + the: &'static str, + } + }; + let all = { + let test_impl: ItemImpl = + syn::parse2(derive_storage_keys_inner(test_struct)) + .expect("Test failed"); + test_impl + .items + .iter() + .find_map(|i| match i { + syn::ImplItem::Const(e) + if e.ident.to_token_stream().to_string() == "ALL" => + { + match &e.expr { + syn::Expr::Block(e) => { + match e + .block + .stmts + .last() + .expect("Must have slice") + { + syn::Stmt::Expr(syn::Expr::Reference( + e, + )) => match &*e.expr { + syn::Expr::Array(e) => Some(e.clone()), + t => panic!( + "Expected array, but got {t:?}" + ), + }, + t => panic!( + "Expected reference, but got {t:?}" + ), + } + } + t => panic!("Expected block, but got {t:?}"), + } + } + t => panic!("Expected const, but got {t:?}"), + }) + .unwrap() + }; + let string = all + .elems + .into_iter() + .map(|e| e.to_token_stream().to_string()) + .join(" "); + assert_eq!(string, "bird is the word"); + } + + /// Test if we reject structs with non static string fields in + /// `StorageKeys` macro derives. + #[test] + #[should_panic( + expected = "Expected `&'static str` field type in StorageKeys derive" + )] + fn test_typecheck_storage_keys_derive() { + derive_storage_keys_inner(quote! { + struct Keys { + x: &'static str, + y: i32, + z: u64, + } + }); + } + /// Test that the create storage keys produces /// the expected code. #[test] fn test_derive_storage_keys() { - let test_struct: TokenStream2 = quote! { + let test_struct = quote! { struct Keys { param1: &'static str, param2: &'static str, @@ -265,7 +339,7 @@ mod test_proc_macros { syn::parse2(derive_storage_keys_inner(test_struct)) .expect("Test failed"); - let expected_impl: TokenStream2 = quote! { + let expected_impl = quote! { impl Keys { const ALL: &[&'static str] = { let Keys { param1, param2 } = Self::VALUES; From 32d4f492efaccde6661f114607c467ce25bf4d67 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Tue, 20 Dec 2022 15:18:35 +0000 Subject: [PATCH 060/166] Add unit tests for tuple and unit structs as well as enums, on StorageKeys derives --- Cargo.lock | 1 - macros/Cargo.toml | 3 -- macros/src/lib.rs | 118 ++++++++++++++++++++++++++++------------------ 3 files changed, 73 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 657c6b6e41..60883727ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3843,7 +3843,6 @@ dependencies = [ name = "namada_macros" version = "0.12.0" dependencies = [ - "itertools", "proc-macro2", "quote", "syn", diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 32ff437bf6..dbd4f81cab 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -13,6 +13,3 @@ proc-macro = true proc-macro2 = "1.0" quote = "1.0" syn = {version="1.0", features = ["full", "extra-traits"]} - -[dev-dependencies] -itertools = "0.10.1" diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 067e2eebb3..eb026afc2d 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -214,6 +214,7 @@ fn derive_storage_keys_inner(struct_def: TokenStream2) -> TokenStream2 { quote! { impl #struct_def_ident { + #[allow(dead_code)] const ALL: &[&'static str] = { let #struct_def_ident { #ident_list @@ -222,6 +223,7 @@ fn derive_storage_keys_inner(struct_def: TokenStream2) -> TokenStream2 { &[ #ident_list ] }; + #[allow(dead_code)] const VALUES: #struct_def_ident = Self { #values_list }; @@ -245,11 +247,42 @@ where #[cfg(test)] mod test_proc_macros { - use itertools::Itertools; use syn::ItemImpl; use super::*; + /// Test if we reject enums in `StorageKeys` derives. + #[test] + #[should_panic(expected = "Expected a struct in the StorageKeys derive")] + fn test_storage_keys_panics_on_enum() { + derive_storage_keys_inner(quote! { + enum What { + The, + Funk, + } + }); + } + + /// Test if we reject unit structs in `StorageKeys` derives. + #[test] + #[should_panic(expected = "Only named struct fields are accepted in \ + StorageKeys derives")] + fn test_storage_keys_panics_on_unit_structs() { + derive_storage_keys_inner(quote! { + struct WhatTheFunk; + }); + } + + /// Test if we reject tuple structs in `StorageKeys` derives. + #[test] + #[should_panic(expected = "Only named struct fields are accepted in \ + StorageKeys derives")] + fn test_storage_keys_panics_on_tuple_structs() { + derive_storage_keys_inner(quote! { + struct WhatTheFunk(&'static str); + }); + } + /// Test if the `ALL` slice generated in `StorageKeys` macro /// derives is sorted in ascending order. #[test] @@ -262,51 +295,30 @@ mod test_proc_macros { the: &'static str, } }; - let all = { - let test_impl: ItemImpl = - syn::parse2(derive_storage_keys_inner(test_struct)) - .expect("Test failed"); - test_impl - .items - .iter() - .find_map(|i| match i { - syn::ImplItem::Const(e) - if e.ident.to_token_stream().to_string() == "ALL" => - { - match &e.expr { - syn::Expr::Block(e) => { - match e - .block - .stmts - .last() - .expect("Must have slice") - { - syn::Stmt::Expr(syn::Expr::Reference( - e, - )) => match &*e.expr { - syn::Expr::Array(e) => Some(e.clone()), - t => panic!( - "Expected array, but got {t:?}" - ), - }, - t => panic!( - "Expected reference, but got {t:?}" - ), - } - } - t => panic!("Expected block, but got {t:?}"), - } - } - t => panic!("Expected const, but got {t:?}"), - }) - .unwrap() + let test_impl: ItemImpl = + syn::parse2(derive_storage_keys_inner(test_struct)) + .expect("Test failed"); + + let expected_impl = quote! { + impl Keys { + #[allow(dead_code)] + const ALL: &[&'static str] = { + let Keys { bird, is, the, word } = Self::VALUES; + &[bird, is, the, word] + }; + #[allow(dead_code)] + const VALUES: Keys = Self { + bird: "bird", + is: "is", + the: "the", + word: "word" + }; + } }; - let string = all - .elems - .into_iter() - .map(|e| e.to_token_stream().to_string()) - .join(" "); - assert_eq!(string, "bird is the word"); + let expected_impl: ItemImpl = + syn::parse2(expected_impl).expect("Test failed"); + + assert_eq!(test_impl, expected_impl); } /// Test if we reject structs with non static string fields in @@ -325,6 +337,20 @@ mod test_proc_macros { }); } + /// Test if we reject structs with non static lifetimes. + #[test] + #[should_panic( + expected = "Expected `&'static str` field type in StorageKeys derive" + )] + fn test_storage_keys_derive_with_non_static_str() { + derive_storage_keys_inner(quote! { + struct Keys<'a> { + x: &'static str, + y: &'a str, + } + }); + } + /// Test that the create storage keys produces /// the expected code. #[test] @@ -341,10 +367,12 @@ mod test_proc_macros { let expected_impl = quote! { impl Keys { + #[allow(dead_code)] const ALL: &[&'static str] = { let Keys { param1, param2 } = Self::VALUES; &[param1, param2] }; + #[allow(dead_code)] const VALUES: Keys = Self { param1: "param1", param2: "param2" From 05eb1330d0cd652a2648aed0002d7b50991310aa Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Tue, 20 Dec 2022 15:21:08 +0000 Subject: [PATCH 061/166] Update macros/src/lib.rs Co-authored-by: Jacob Turner --- macros/src/lib.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index eb026afc2d..7e248d1edf 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -189,11 +189,7 @@ fn derive_storage_keys_inner(struct_def: TokenStream2) -> TokenStream2 { let ident_list = create_punctuated(&idents, |ident| ident.clone()); let values_list = create_punctuated(&idents, |ident| { - let storage_key = { - let mut toks = TokenStream2::new(); - ident.to_tokens(&mut toks); - toks.to_string() - }; + let storage_key = ident.to_token_stream().to_string(); syn::FieldValue { attrs: vec![], member: syn::Member::Named(ident.clone()), From 56599b15360617833287ef36d1219fa1807a10a3 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Tue, 20 Dec 2022 15:30:42 +0000 Subject: [PATCH 062/166] Remove allow dead code TODO --- macros/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 7e248d1edf..b1e4079169 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -159,7 +159,6 @@ pub fn derive_storage_keys(struct_def: TokenStream) -> TokenStream { #[inline] // TODO: use this crate for errors: https://crates.io/crates/proc-macro-error -// TODO: emit allow_deadcode in ALL and VALUES fn derive_storage_keys_inner(struct_def: TokenStream2) -> TokenStream2 { let struct_def: ItemStruct = syn::parse2(struct_def) .expect("Expected a struct in the StorageKeys derive"); From ad0d2bcd40b93df3bc1a620c9b91798f7c781896 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Tue, 20 Dec 2022 15:58:28 +0000 Subject: [PATCH 063/166] Strip out #[allow(dead_code)] from VALUES --- macros/src/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index b1e4079169..50f14258d7 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -218,7 +218,6 @@ fn derive_storage_keys_inner(struct_def: TokenStream2) -> TokenStream2 { &[ #ident_list ] }; - #[allow(dead_code)] const VALUES: #struct_def_ident = Self { #values_list }; @@ -301,7 +300,6 @@ mod test_proc_macros { let Keys { bird, is, the, word } = Self::VALUES; &[bird, is, the, word] }; - #[allow(dead_code)] const VALUES: Keys = Self { bird: "bird", is: "is", @@ -367,7 +365,6 @@ mod test_proc_macros { let Keys { param1, param2 } = Self::VALUES; &[param1, param2] }; - #[allow(dead_code)] const VALUES: Keys = Self { param1: "param1", param2: "param2" From e7a16ba7b62cbf5118dcd41725a58a6e9a6ecf38 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Wed, 21 Dec 2022 01:24:38 -0500 Subject: [PATCH 064/166] make-package.sh: don't attempt to include matchmaker The matchmaker has been removed, but the packaging script still attempts to include it. This does not break the script, because the name of the nonexistent matchmaker is the empty string, but is still incorrect. --- scripts/make-package.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/make-package.sh b/scripts/make-package.sh index 8ae06589bb..77b3ab2fd0 100755 --- a/scripts/make-package.sh +++ b/scripts/make-package.sh @@ -11,8 +11,7 @@ BIN="namada namadac namadan namadaw" mkdir -p ${PACKAGE_NAME} && \ cd target/release && \ -MM_TOKEN_EXCH=$(find . -maxdepth 1 -name 'libmm_token_exch.so' -or -name 'libmm_token_exch.dll' -or -name 'libmm_token_exch.dylib') && \ -ln ${BIN} ${MM_TOKEN_EXCH} ../../${PACKAGE_NAME} && \ +ln ${BIN} ../../${PACKAGE_NAME} && \ cd ../.. && \ tar -c -z -f ${PACKAGE_NAME}.tar.gz ${PACKAGE_NAME} && \ rm -rf ${PACKAGE_NAME} From eddc2d0e2e2cc5db1fa689e84faab3dad903ddcf Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Wed, 21 Dec 2022 01:48:38 -0500 Subject: [PATCH 065/166] changelog: add #943 --- .../unreleased/miscellaneous/943-no-matchmaker-in-package.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/miscellaneous/943-no-matchmaker-in-package.md diff --git a/.changelog/unreleased/miscellaneous/943-no-matchmaker-in-package.md b/.changelog/unreleased/miscellaneous/943-no-matchmaker-in-package.md new file mode 100644 index 0000000000..13758711e4 --- /dev/null +++ b/.changelog/unreleased/miscellaneous/943-no-matchmaker-in-package.md @@ -0,0 +1,2 @@ +- Don't attempt to include matchmaker DLLs, which no longer exist, in release + packages. ([#943](https://github.com/anoma/namada/pull/943)) \ No newline at end of file From aeadf4324edfebac0446d0be3c5c138c897deff0 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Wed, 21 Dec 2022 02:45:22 -0500 Subject: [PATCH 066/166] release: add configuration for cargo-about cargo-about is a tool from Embark that walks cargo dependencies for all third party licenses. Include its configuration file and a template to generate a third party license file. --- about.hbs | 22 ++++++++++++++++++++++ about.toml | 17 +++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 about.hbs create mode 100644 about.toml diff --git a/about.hbs b/about.hbs new file mode 100644 index 0000000000..8dc9490c5d --- /dev/null +++ b/about.hbs @@ -0,0 +1,22 @@ +Third Party Licenses + +Overview of licenses: + +{{#each overview}} +{{{name}}} ({{count}}) +{{/each}} + +All license text: + +{{#each licenses}} +{{{name}}} + +Used by: + +{{#each used_by}} +{{crate.name}} {{crate.version}} +<{{#if crate.repository}}{{crate.repository}}{{else}}https://crates.io/crates/{{crate.name}}{{/if}}> +{{/each}} + +{{{text}}} +{{/each}} diff --git a/about.toml b/about.toml new file mode 100644 index 0000000000..d080250749 --- /dev/null +++ b/about.toml @@ -0,0 +1,17 @@ +accepted = [ + "MIT", + "0BSD", + "ISC", + "Unlicense", + "BSD-2-Clause", + "BSD-3-Clause", + "CC0-1.0", + "MPL-2.0", + "GPL-3.0", + "OSL-3.0", + "OpenSSL", + "Unicode-DFS-2016", + "Apache-2.0 WITH LLVM-exception", + "Apache-2.0", + "NOASSERTION", +] From dd16a346fa7941cab9cf5ef96075a36e6564f897 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Wed, 21 Dec 2022 02:46:42 -0500 Subject: [PATCH 067/166] make-package.sh: include license information in tarball Generate LICENSE.thirdparty using cargo-about, and include it and the Namada LICENSE file in release tarballs. --- scripts/make-package.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/make-package.sh b/scripts/make-package.sh index 8ae06589bb..63a68fe491 100755 --- a/scripts/make-package.sh +++ b/scripts/make-package.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash # Make a release archive from built Namada binaries and dylib(s) +# depends on cargo-about 0.5.2 set -e @@ -14,5 +15,7 @@ cd target/release && \ MM_TOKEN_EXCH=$(find . -maxdepth 1 -name 'libmm_token_exch.so' -or -name 'libmm_token_exch.dll' -or -name 'libmm_token_exch.dylib') && \ ln ${BIN} ${MM_TOKEN_EXCH} ../../${PACKAGE_NAME} && \ cd ../.. && \ +ln LICENSE ${PACKAGE_NAME} && \ +cargo about generate about.hbs > ${PACKAGE_NAME}/LICENSE.thirdparty && \ tar -c -z -f ${PACKAGE_NAME}.tar.gz ${PACKAGE_NAME} && \ rm -rf ${PACKAGE_NAME} From db53d5def6d46bffe496b7483c40cd05a6c2aa4e Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Wed, 21 Dec 2022 02:47:35 -0500 Subject: [PATCH 068/166] ci: install cargo-about on release step make package now invokes cargo-about to generate LICENSE.thirdparty. Install it in the release CI so this can run. --- .github/workflows/release.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 114ca0455d..9de90b80a2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,6 +72,9 @@ jobs: ~/.cargo/git key: ${{ runner.os }}-namada-release-${{ matrix.namada_cache_version }}-${{ hashFiles('**/Cargo.lock') }} restore-keys: ${{ runner.os }}-namada-release-${{ matrix.namada_cache_version }} + - name: Install cargo-about + run: | + cargo install --version 0.5.2 cargo-about - name: Start sccache server run: sccache --start-server - name: ${{ matrix.make.name }} From a6892e480ebe25ec72bee14fc7cd480d12ad6986 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Wed, 21 Dec 2022 02:51:36 -0500 Subject: [PATCH 069/166] changelog: add #945 --- .../unreleased/miscellaneous/945-release-include-license.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/miscellaneous/945-release-include-license.md diff --git a/.changelog/unreleased/miscellaneous/945-release-include-license.md b/.changelog/unreleased/miscellaneous/945-release-include-license.md new file mode 100644 index 0000000000..55d0b60f60 --- /dev/null +++ b/.changelog/unreleased/miscellaneous/945-release-include-license.md @@ -0,0 +1,2 @@ +- Include license information in release binary tarballs. + ([#945](https://github.com/anoma/namada/pull/945)) \ No newline at end of file From 335fa442cb8d1839804c31d9d1281cdd1b60ff92 Mon Sep 17 00:00:00 2001 From: Oliver Simon Date: Wed, 21 Dec 2022 18:46:26 +0900 Subject: [PATCH 070/166] Update link to install section --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06fe8b9621..816c88bf5a 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ After installation, the main `namada` executable will be available on path. To find how to use it, check out the [User Guide section of the docs](https://docs.namada.net/user-guide/index.html). For more detailed instructions and more install options, see the [Install -section](https://docs.namada.net/user-guide/install.html) of the User +section](https://docs.namada.net/user-guide/install/index.html) of the User Guide. ## ⚙️ Development From 47cba02fc7e22edc97a07669644ba2cb921c9f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 9 Dec 2022 12:21:33 +0100 Subject: [PATCH 071/166] test/core: run less cases on `update_epoch_after_its_duration` test --- core/src/ledger/storage/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/ledger/storage/mod.rs b/core/src/ledger/storage/mod.rs index 8285e58bab..5d0befbaca 100644 --- a/core/src/ledger/storage/mod.rs +++ b/core/src/ledger/storage/mod.rs @@ -1211,6 +1211,7 @@ pub mod testing { mod tests { use chrono::{TimeZone, Utc}; use proptest::prelude::*; + use proptest::test_runner::Config; use rust_decimal_macros::dec; use super::testing::*; @@ -1259,6 +1260,10 @@ mod tests { } proptest! { + #![proptest_config(Config { + cases: 10, + .. Config::default() + })] /// Test that: /// 1. When the minimum blocks have been created since the epoch /// start height and minimum time passed since the epoch start time, From c806cefb84db74338526176316c6b628a24c89d9 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Wed, 21 Dec 2022 08:31:47 -0500 Subject: [PATCH 072/166] changelog: add #876 --- .changelog/unreleased/testing/876-faster-epoch-test.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/testing/876-faster-epoch-test.md diff --git a/.changelog/unreleased/testing/876-faster-epoch-test.md b/.changelog/unreleased/testing/876-faster-epoch-test.md new file mode 100644 index 0000000000..f387dee313 --- /dev/null +++ b/.changelog/unreleased/testing/876-faster-epoch-test.md @@ -0,0 +1,2 @@ +- Run fewer cases on update_epoch_after_its_duration, for a faster test suite. + ([#876](https://github.com/anoma/namada/pull/876)) \ No newline at end of file From 423cd289cc3ef2f4a1a90a55bed090b3990c08a5 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Wed, 21 Dec 2022 08:33:41 -0500 Subject: [PATCH 073/166] changelog: add #911 --- .../unreleased/testing/911-fix-ledger-txs-and-queries-args.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/unreleased/testing/911-fix-ledger-txs-and-queries-args.md diff --git a/.changelog/unreleased/testing/911-fix-ledger-txs-and-queries-args.md b/.changelog/unreleased/testing/911-fix-ledger-txs-and-queries-args.md new file mode 100644 index 0000000000..eb5acbfcc3 --- /dev/null +++ b/.changelog/unreleased/testing/911-fix-ledger-txs-and-queries-args.md @@ -0,0 +1,3 @@ +- Use the correct options (--gas-amount, --gas- + token) in the ledger_txs_and_queries E2E test. + ([#911](https://github.com/anoma/namada/pull/911)) \ No newline at end of file From 73c686d7043ad917d98d6c20ed5a39fa1d270510 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Wed, 21 Dec 2022 09:08:34 -0500 Subject: [PATCH 074/166] wasm: update checksums.json --- wasm/checksums.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/wasm/checksums.json b/wasm/checksums.json index b13508300c..1d0b3d93c7 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,20 +1,20 @@ { - "tx_bond.wasm": "tx_bond.be9c75f96b3b4880b7934d42ee218582b6304f6326a4588d1e6ac1ea4cc61c49.wasm", + "tx_bond.wasm": "tx_bond.59f751c77d75d96679ec6df7376d896e3cbf9598846ea09e2caef8114de97932.wasm", "tx_change_validator_commission.wasm": "tx_change_validator_commission.cd861e0e82f4934be6d8382d6fff98286b4fadbc20ab826b9e817f6666021273.wasm", - "tx_ibc.wasm": "tx_ibc.13daeb0c88abba264d3052129eda0713bcf1a71f6f69bf37ec2494d0d9119f1f.wasm", + "tx_ibc.wasm": "tx_ibc.f261d127df2cb05489ad2655fcc6d0d8e7378789226ee27f0251ae90adfc1b0a.wasm", "tx_init_account.wasm": "tx_init_account.e21cfd7e96802f8e841613fb89f1571451401d002a159c5e9586855ac1374df5.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.b9a77bc9e416f33f1e715f25696ae41582e1b379422f7a643549884e0c73e9de.wasm", - "tx_init_validator.wasm": "tx_init_validator.1e9732873861c625f239e74245f8c504a57359c06614ba40387a71811ca4a097.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.211265350906ad7aef3aca30d6ef463d065b738707accd0acaa19992977bfabe.wasm", + "tx_init_validator.wasm": "tx_init_validator.eac9858c4f96bbefd120e3ebe0489e1700a83e8a22d778d5aa2b14ab0627f172.wasm", "tx_reveal_pk.wasm": "tx_reveal_pk.47bc922a8be5571620a647ae442a1af7d03d05d29bef95f0b32cdfe00b11fee9.wasm", - "tx_transfer.wasm": "tx_transfer.bbd1ef5d9461c78f0288986de046baad77e10671addc5edaf3c68ea1ae4ecc99.wasm", - "tx_unbond.wasm": "tx_unbond.c0a690d0ad43a94294a6405bae3327f638a657446c74dc61dbb3a4d2ce488b5e.wasm", + "tx_transfer.wasm": "tx_transfer.5b95e6f1f6b2d4b0ec6f07ac1ec66089374ece2e4a6c5bdb32297985670a2ab0.wasm", + "tx_unbond.wasm": "tx_unbond.a33d113d04786c6638f5181b1bd65413b6b199e0c37985f444bea56430fc3f4c.wasm", "tx_update_vp.wasm": "tx_update_vp.ee2e9b882c4accadf4626e87d801c9ac8ea8c61ccea677e0532fc6c1ee7db6a2.wasm", "tx_vote_proposal.wasm": "tx_vote_proposal.263fd9f4cb40f283756f394d86bdea3417e9ecd0568d6582c07a5b6bd14287d6.wasm", - "tx_withdraw.wasm": "tx_withdraw.6ce8faf6a32340178ddeaeb91a9b40e7f0433334e5c1f357964bf8e11d0077f1.wasm", - "vp_implicit.wasm": "vp_implicit.17f5c2af947ccfadce22d0fffecde1a1b4bc4ca3acd5dd8b459c3dce4afcb4e8.wasm", - "vp_masp.wasm": "vp_masp.5620cb6e555161641337d308851c760fbab4f9d3693cfd378703aa55e285249d.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.362584b063cc4aaf8b72af0ed8af8d05a179ebefec596b6ab65e0ca255ec3c80.wasm", - "vp_token.wasm": "vp_token.a289723dd182fe0206e6c4cf1f426a6100787b20e2653d2fad6031e8106157f3.wasm", - "vp_user.wasm": "vp_user.b83b2d0616bb2244c8a92021665a0be749282a53fe1c493e98c330a6ed983833.wasm", - "vp_validator.wasm": "vp_validator.59e3e7729e14eeacc17d76b736d1760d59a1a6e9d6acbc9a870e1835438f524a.wasm" + "tx_withdraw.wasm": "tx_withdraw.b9b8623217202de2cb2c3941f740f6acd8558eaa05406efc60ee471c212aa513.wasm", + "vp_implicit.wasm": "vp_implicit.6c221c5210973b8d39dae73378cb8291ffebb9fb99e790f89290a1b51eb6a690.wasm", + "vp_masp.wasm": "vp_masp.16516aeafa4c2c814cf3a4289b7f924d2551966f98b9ce136fbae361aba2a73c.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.e893d1f02ec8b3668a58ab69f9dd676ccb18d0cc96d3b5c9c789714552ea715e.wasm", + "vp_token.wasm": "vp_token.bfeddd3c5954174e95064f753cb743d84659f05910cbcb31a6d8b23769b59638.wasm", + "vp_user.wasm": "vp_user.40087a1e14bdafb4429427f47c5c7a0a247433d4f72927f2ec5906119192c900.wasm", + "vp_validator.wasm": "vp_validator.3f219ebb7f3f058f6681fe3d461d6296ab1d21d92ae1578ad421b272789f451e.wasm" } \ No newline at end of file From 1b8b55d196701502f7e8cbbfb14591a98e02f1a8 Mon Sep 17 00:00:00 2001 From: Unkowit Date: Wed, 16 Nov 2022 10:10:00 +0000 Subject: [PATCH 075/166] quick fix to cubic slash --- .../specs/src/economics/proof-of-stake/cubic-slashing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md index efd447cb18..fa3e8b312a 100644 --- a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md +++ b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md @@ -11,7 +11,7 @@ At the end of each epoch, in order to process any slashes scheduled for processi 1. Iterate over all slashes for infractions committed within a range of (-1, +1) epochs worth of block heights (this may need to be a protocol parameter) of the infraction in question. 2. Calculate the slash rate according to the following formula: -$$ \sum_{i \in \text{validators}} \max \{ 0.01, \big(\frac{i_{voting-power}}{\sum_{i \in \text{validators}}i_{voting-power}}\big)^2\} $$ +$$ \max \{ 0.01, 9*\big(\sum_{i \in \text{faulty-validators}}\frac{i_{voting-power}}{\sum_{j \in \text{all-validators}}j_{voting-power}}\big)^2\} $$ Or, in pseudocode: From 30def8d7392e81b2f26578d80b4a6b1e8eeaa8ab Mon Sep 17 00:00:00 2001 From: brentstone Date: Wed, 16 Nov 2022 22:00:25 -0500 Subject: [PATCH 076/166] Cubic slashing: fix and improve plot --- .../src/economics/images/cubic_slash.png | Bin 17388 -> 335863 bytes .../proof-of-stake/cubic-slashing.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/specs/src/economics/images/cubic_slash.png b/documentation/specs/src/economics/images/cubic_slash.png index fc848ff298e7590c0ee0622db2051953999824ba..10b441500a29289521660964ff777ef02d793261 100644 GIT binary patch literal 335863 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 |NwD2K0lzXD_RlR0p#S>i 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 =elGRyA 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

9i5f! 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 onn}In$3K_>pAUAtO*L&H*}XgVu$FFV?o(_@6v) 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 diff --git a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md index fa3e8b312a..97703815de 100644 --- a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md +++ b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md @@ -52,9 +52,9 @@ class PoS: As a function, it can be drawn as: -![cubic_slash](../images/cubic_slash.png) > Note: The voting power of a slash is the voting power of the validator **when they violated the protocol**, not the voting power now or at the time of any of the other infractions. This does mean that these voting powers may not sum to 1, but this method should still be close to the incentives we want, and can't really be changed without making the system easier to game. +[](../images/cubic_slash.png) 3. Set the slash rate on the now "finalised" slash in storage. 4. Update the validators' stored voting power appropriately. From 38721b04d55754ddd2f37d38b8fe80fdc3166b9f Mon Sep 17 00:00:00 2001 From: brentstone Date: Wed, 16 Nov 2022 22:03:04 -0500 Subject: [PATCH 077/166] Cubic slashing: clarify slash iteration procedure and equation --- .../specs/src/economics/proof-of-stake/cubic-slashing.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md index 97703815de..988d86a23c 100644 --- a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md +++ b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md @@ -7,11 +7,12 @@ When a slash is detected: 2. Jail the validator in question (this will apply at the end of the current epoch). While the validator is jailed, it should be removed from the validator set (also being effective from the end of the current epoch). Note that this is the only instance in our proof-of-stake model when the validator set is updated without waiting for the pipeline offset. 3. Prevent the delegators to this validator from altering their delegations in any way until the enqueued slash is processed. -At the end of each epoch, in order to process any slashes scheduled for processing at the end of that epoch: -1. Iterate over all slashes for infractions committed within a range of (-1, +1) epochs worth of block heights (this may need to be a protocol parameter) of the infraction in question. -2. Calculate the slash rate according to the following formula: +At the end of each epoch, for each slash enqueued to be processed for the end of the epoch: +1. Collect the other known infractions committed within a range of (-1, +1) epochs around the infraction in question. +2. Sum the fractional voting powers (relative to the total PoS voting power) of the misbehaving validator for each of the collected nearby infractions. +3. The final slash rate for the slash in question is then dependent on this sum. Using $r_\text{nom}$ as the nominal slash rate and $\text{vp}$ to indicate voting power, the slash rate is expressed as: -$$ \max \{ 0.01, 9*\big(\sum_{i \in \text{faulty-validators}}\frac{i_{voting-power}}{\sum_{j \in \text{all-validators}}j_{voting-power}}\big)^2\} $$ +$$ \max \{~r_{\text{nom}}~, ~9*\big(\sum_{i \in \text{infractions}}\frac{\text{vp}_i}{\text{vp}_{\text{tot}}}\big)^2~\}. $$ Or, in pseudocode: From f7a8f461940b5f246072b9690eea1c7a68c4ca54 Mon Sep 17 00:00:00 2001 From: brentstone Date: Wed, 16 Nov 2022 22:05:47 -0500 Subject: [PATCH 078/166] Cubic slashing: add new improved pseudocode blurb (Rust-style) --- .../proof-of-stake/cubic-slashing.md | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md index 988d86a23c..73656ea0aa 100644 --- a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md +++ b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md @@ -16,7 +16,7 @@ $$ \max \{~r_{\text{nom}}~, ~9*\big(\sum_{i \in \text{infractions}}\frac{\text{ Or, in pseudocode: -```haskell = + + As a function, it can be drawn as: +```rust +// Infraction type, where inner field is the slash rate for the type +enum Infraction { + DuplicateVote(f64), + LightClientAttack(f64) +} + +// Generic validator with an address and voting power +struct Validator { + address: Vec, + voting_power: u64, +} + +// Generic slash object with the misbehaving validator, infraction type, and some unique identifier +struct Slash { + validator: Validator, + infraction_type: Infraction, + id: u64, +} + +// Calculate a vector of final slash rates for each slash in the current epoch +fn calculate_slash_rates( + current_epoch: u64, + nominal_slash_rate: f64, + slashes: Map>, + total_voting_power: u64 +) -> Vec { + let slashes_this_epoch = slashes.get(current_epoch); + let slashes_prev_epoch = slashes.get(current_epoch - 1); + let slashes_next_epoch = slashes.get(current_epoch + 1); + + let associated_slashes = slashes_prev_epoch.extend(slashes_this_epoch).extend(slashes_next_epoch); + let final_rates: Vec; + + for slash in &slashes_this_epoch { + let vp_frac_sum: f64 = 0; + for assoc_slash in &associated_slashes { + if assoc_slash.id == slash.id { continue; } + vp_frac_sum += assoc_slash.validator.voting_power / total_voting_power; + } + let rate = max( slash.infraction_type.0 , 9 * vp_frac_sum * vp_frac_sum ); + final_rates.push(rate) + } + final_rates +} +``` > Note: The voting power of a slash is the voting power of the validator **when they violated the protocol**, not the voting power now or at the time of any of the other infractions. This does mean that these voting powers may not sum to 1, but this method should still be close to the incentives we want, and can't really be changed without making the system easier to game. From fed8b9e766a094875b965fd88b478b77b63731a2 Mon Sep 17 00:00:00 2001 From: brentstone Date: Wed, 16 Nov 2022 22:06:40 -0500 Subject: [PATCH 079/166] Cubic slashing: general writing improvements --- .../economics/proof-of-stake/cubic-slashing.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md index 73656ea0aa..99ea282324 100644 --- a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md +++ b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md @@ -1,10 +1,10 @@ # Cubic slashing -Namada implements cubic slashing, meaning that the amount of a slash is proportional to the cube of the voting power committing infractions within a particular interval. This is designed to make it riskier to operate larger or similarly configured validators, and thus encourage network resilience. +Namada implements a slashing scheme that is called cubic slashing: the amount of a slash is proportional to the cube of the voting power committing infractions within a particular interval. This is designed to make it riskier to operate larger or similarly configured validators, and thus the scheme encourages network resilience. When a slash is detected: -1. Using the height of the infraction, calculate the epoch just after which stake bonded at the time of infraction could have been fully unbonded. Enqueue the slash for processing at the end of that epoch (so that it will be processed before unbonding could have completed, and hopefully long enough for any other misbehaviour from around the same height as this misbehaviour to also be detected). -2. Jail the validator in question (this will apply at the end of the current epoch). While the validator is jailed, it should be removed from the validator set (also being effective from the end of the current epoch). Note that this is the only instance in our proof-of-stake model when the validator set is updated without waiting for the pipeline offset. +1. Using the height of the infraction, calculate the epoch at the unbonding length relative to the current epoch. This is the final epoch before the stake that was used to commit the infraction can be fully unbonded and withdrawn. The slash is enqueued to be processed in this final epoch to allow for sufficient time to detect any other validator misbehaviors while still processing the slash before the infraction stake could be unbonded and withdrawn. +2. Jail the misbehaving validator, effective at the beginning of the next epoch. While the validator is jailed, it is removed from the validator set. Note that this is the only instance in our proof-of-stake model wherein the validator set is updated without waiting for the pipeline offset. 3. Prevent the delegators to this validator from altering their delegations in any way until the enqueued slash is processed. At the end of each epoch, for each slash enqueued to be processed for the end of the epoch: @@ -52,7 +52,6 @@ class PoS: return slash_rate ``` --> -As a function, it can be drawn as: ```rust // Infraction type, where inner field is the slash rate for the type enum Infraction { @@ -100,15 +99,17 @@ fn calculate_slash_rates( } ``` +As a function, it can be drawn as: -> Note: The voting power of a slash is the voting power of the validator **when they violated the protocol**, not the voting power now or at the time of any of the other infractions. This does mean that these voting powers may not sum to 1, but this method should still be close to the incentives we want, and can't really be changed without making the system easier to game. [](../images/cubic_slash.png) 3. Set the slash rate on the now "finalised" slash in storage. -4. Update the validators' stored voting power appropriately. +4. Update the misbehaving validators' stored voting powers appropriately. 5. Delegations to the validator can now be redelegated / start unbonding / etc. -Validator can later submit a transaction to unjail themselves after a configurable period. When the transaction is applied and accepted, the validator updates its state to "candidate" and is added back to the validator set starting at the epoch at pipeline offset (into `consensus`, `below_capacity` or `below_threshold` set, depending on its voting power). +> Note: The voting power associated with a slash is the voting power of the validator **when they violated the protocol**. This does mean that these voting powers may not sum to 1, but this method should still be close to the desired incentives and cannot really be changed without making the system easier to game. + +A jailed validator can later submit a transaction to unjail themselves after a configurable period. When the transaction is applied and accepted, the validator updates its state to "candidate" and is added back to the appropriate validator set (depending on its new voting power) starting at the pipeline offset relative to the epoch in which the unjailing transaction was submitted. At present, funds slashed are sent to the governance treasury. @@ -118,8 +119,6 @@ Slashes should lead to punishment for delegators who were contributing voting po This can be implemented as a negative inflation rate for a particular block. -Instant redelegation is not supported. Redelegations must wait the unbonding period. - \ No newline at end of file From 9ecfe7c543b175bf1dff56046123cdac24d97652 Mon Sep 17 00:00:00 2001 From: brentstone Date: Thu, 17 Nov 2022 13:35:53 -0500 Subject: [PATCH 080/166] Reward distribution: general improvements --- .../economics/proof-of-stake/reward-distribution.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/documentation/specs/src/economics/proof-of-stake/reward-distribution.md b/documentation/specs/src/economics/proof-of-stake/reward-distribution.md index 674d125e93..808b52c640 100644 --- a/documentation/specs/src/economics/proof-of-stake/reward-distribution.md +++ b/documentation/specs/src/economics/proof-of-stake/reward-distribution.md @@ -148,10 +148,10 @@ in order to calculate the new rewards given out to the delegator during withdraw The commission rate $c_V(e)$ is the same for all delegations to a validator $V$ in a given epoch $e$, including for self-bonds. The validator can change the commission rate at any point, subject to a maximum rate of change per epoch, which is a constant specified when the validator is created and immutable once validator creation has been accepted. -While rewards are given out at the end of every epoch, voting power is only updated after the pipeline offset. According to the [proof-of-stake system](bonding-mechanism.md#epoched-data), at the current epoch `e`, the validator sets an only be updated for epoch `e + pipeline_offset`, and it should remain unchanged from epoch `e` to `e + pipeline_offset - 1`. Updating voting power in the current epoch would violate this rule. +While rewards are given out at the end of every epoch, voting power is only updated after the pipeline offset. According to the [proof-of-stake system](bonding-mechanism.md#epoched-data), at the current epoch `e`, the validator sets can only be updated for epoch `e + pipeline_offset`, and it should remain unchanged from epoch `e` to `e + pipeline_offset - 1`. Updating voting power in the current epoch would violate this rule. -## Distribution to validators +## Distribution of block rewards to validators A validator can earn a portion of the block rewards in three different ways: @@ -198,9 +198,4 @@ The values of the parameters $r_p$ and $r_s$ are set in the proof-of-stake stora These rewards must be determined for every single block, but the inflationary token rewards are only minted at the end of an epoch. Thus, the rewards products are only updated at the end of an epoch as well. -In order to maintain a record of the block rewards over the course of an epoch, a reward fraction accumulator is implemented as a `Map` and held in the storage key `#{PoS}/validator_set/consensus/rewards_accumulator`. When finalizing each block, the accumulator value for each consensus validator is incremented with the fraction of that block's reward owed to the validator. At the end of the epoch when the rewards products are updated, the accumulator value is divided by the number of blocks in that epoch, which yields the fraction of the newly minted inflation tokens owed to the validator. The next entry of the rewards products for each validator can then be created. The map is then reset to be empty in preparation for the next epoch and consensus validator set. - - -TODO describe / figure out: - -- how leftover reward tokens from round-off / truncation are handled +In order to maintain a record of the block rewards over the course of an epoch, a reward fraction accumulator is implemented as a `Map` and held in the storage key `#{PoS}/validator_set/consensus/rewards_accumulator`. When finalizing each block, the accumulator value for each consensus validator is incremented with the fraction of that block's reward owed to the validator. At the end of the epoch when the rewards products are updated, the accumulator value is divided by the number of blocks in that epoch, which yields the fraction of the newly minted inflation tokens owed to the validator. The next entry of the rewards products for each validator can then be created. The map is then reset to be empty in preparation for the next epoch and consensus validator set. \ No newline at end of file From a2edb350272edb5551f860debc90a6a31674e923 Mon Sep 17 00:00:00 2001 From: brentstone Date: Fri, 18 Nov 2022 11:28:26 -0500 Subject: [PATCH 081/166] General housekeeping --- .../specs/src/economics/proof-of-stake/cubic-slashing.md | 2 +- .../src/economics/proof-of-stake/reward-distribution.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md index 99ea282324..db8db4bf10 100644 --- a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md +++ b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md @@ -8,7 +8,7 @@ When a slash is detected: 3. Prevent the delegators to this validator from altering their delegations in any way until the enqueued slash is processed. At the end of each epoch, for each slash enqueued to be processed for the end of the epoch: -1. Collect the other known infractions committed within a range of (-1, +1) epochs around the infraction in question. +1. Collect all known infractions committed within a range of (-1, +1) epochs around the infraction in question. 2. Sum the fractional voting powers (relative to the total PoS voting power) of the misbehaving validator for each of the collected nearby infractions. 3. The final slash rate for the slash in question is then dependent on this sum. Using $r_\text{nom}$ as the nominal slash rate and $\text{vp}$ to indicate voting power, the slash rate is expressed as: diff --git a/documentation/specs/src/economics/proof-of-stake/reward-distribution.md b/documentation/specs/src/economics/proof-of-stake/reward-distribution.md index 808b52c640..3bafc08e25 100644 --- a/documentation/specs/src/economics/proof-of-stake/reward-distribution.md +++ b/documentation/specs/src/economics/proof-of-stake/reward-distribution.md @@ -1,8 +1,8 @@ # Reward distribution -Namada uses the automatically-compounding variant of [F1 fee distribution](https://drops.dagstuhl.de/opus/volltexte/2020/11974/pdf/OASIcs-Tokenomics-2019-10.pdf). +Namada uses the automatically-compounding variant of the [F1 fee distribution](https://drops.dagstuhl.de/opus/volltexte/2020/11974/pdf/OASIcs-Tokenomics-2019-10.pdf). -Rewards are given to validators for proposing blocks, for voting on finalizing blocks, and for being in the [consensus validator set](bonding-mechanism.md#validator-sets): the funds for these rewards can come from **minting** (creating new tokens). The amount that is minted depends on how many staking tokens are locked (staked) and some maximum annual inflation rate. The rewards mechanism is implemented as a [PD controller](../inflation-system.md#detailed-inflation-calculation-model) that dynamically adjusts the inflation rate to achieve a target staking token ratio. When the total fraction of tokens staked is very low, the return rate per validator needs to increase, but as the total fraction of stake rises, validators will receive fewer rewards. Once the desired staking fraction is achieved, the amount minted will just be the desired annual inflation. +Rewards are given to validators for proposing blocks, for voting on finalizing blocks, and for being in the [consensus validator set](bonding-mechanism.md#validator-sets). The funds for these rewards come from **minting** (creating new tokens). The amount that is minted depends on how many staking tokens are locked (staked) and some maximum annual inflation rate. The rewards mechanism is implemented as a [PD controller](../inflation-system.md#detailed-inflation-calculation-model) that dynamically adjusts the inflation rate to achieve a target staked token ratio. When the total fraction of tokens staked is very low, the return rate per validator needs to increase, but as the total fraction of stake rises, validators will receive fewer rewards. Once the desired staking fraction is achieved, the amount minted will just be the desired annual inflation. Each delegation to a validator is initiated at an agreed-upon commission rate charged by the validator. Validators pay out rewards to delegators based on this mutually-determined commission rate. The minted rewards are auto-bonded and only transferred when the funds are unbonded. Once the protocol determines the total amount of tokens to mint at the end of the epoch, the minted tokens are effectively divided among the relevant validators and delegators according to their proportional stake. In practice, the reward products, which are the fractional increases in staked tokens claimed, are stored for the validators and delegators, and the reward tokens are only transferred to the validator’s or delegator’s account upon withdrawal. This is described in the following sections. The general system is similar to what Cosmos does. @@ -165,7 +165,7 @@ $$ R_p + R_s + R_b = 1, $$ where $R_p$ is the proposer reward fraction, $R_s$ is the reward fraction for the set of signers, and $R_b$ is the reward fraction for the whole active validator set. -The reward for proposing a block is dependent on the combined voting power of all validators whose signatures are included in the block. This is to incentivize the block proposer to maximize the inclusion of signatures, as blocks with more signatures are (JUSTIFY THIS POINT HERE). +The reward for proposing a block is dependent on the combined voting power of all validators whose signatures are included in the block. This is to incentivize the block proposer to maximize the inclusion of signatures, as blocks with more signatures have better security guarantees and allow for more efficient light clients. The block proposer reward is parameterized as From de1d56bdd04c3d7766411c5f8481de3e28e4f546 Mon Sep 17 00:00:00 2001 From: brentstone Date: Sun, 20 Nov 2022 19:19:40 -0800 Subject: [PATCH 082/166] update pseudocode --- .../proof-of-stake/cubic-slashing.md | 55 ++++++++++--------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md index db8db4bf10..891815cfc0 100644 --- a/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md +++ b/documentation/specs/src/economics/proof-of-stake/cubic-slashing.md @@ -8,7 +8,7 @@ When a slash is detected: 3. Prevent the delegators to this validator from altering their delegations in any way until the enqueued slash is processed. At the end of each epoch, for each slash enqueued to be processed for the end of the epoch: -1. Collect all known infractions committed within a range of (-1, +1) epochs around the infraction in question. +1. Collect all known infractions committed within a range of [-`window_width`, +`window_width`] epochs around the infraction in question. By default, `window_width` = 1. 2. Sum the fractional voting powers (relative to the total PoS voting power) of the misbehaving validator for each of the collected nearby infractions. 3. The final slash rate for the slash in question is then dependent on this sum. Using $r_\text{nom}$ as the nominal slash rate and $\text{vp}$ to indicate voting power, the slash rate is expressed as: @@ -55,8 +55,8 @@ class PoS: ```rust // Infraction type, where inner field is the slash rate for the type enum Infraction { - DuplicateVote(f64), - LightClientAttack(f64) + DuplicateVote(Decimal), + LightClientAttack(Decimal) } // Generic validator with an address and voting power @@ -65,41 +65,44 @@ struct Validator { voting_power: u64, } -// Generic slash object with the misbehaving validator, infraction type, and some unique identifier +// Generic slash object with the misbehaving validator and infraction type struct Slash { validator: Validator, infraction_type: Infraction, - id: u64, } -// Calculate a vector of final slash rates for each slash in the current epoch -fn calculate_slash_rates( +// Calculate the cubic slash rate for a slash in the current epoch +fn calculate_cubic_slash_rate( current_epoch: u64, - nominal_slash_rate: f64, + nominal_slash_rate: Decimal, + cubic_window_width: u64, slashes: Map>, total_voting_power: u64 -) -> Vec { - let slashes_this_epoch = slashes.get(current_epoch); - let slashes_prev_epoch = slashes.get(current_epoch - 1); - let slashes_next_epoch = slashes.get(current_epoch + 1); - - let associated_slashes = slashes_prev_epoch.extend(slashes_this_epoch).extend(slashes_next_epoch); - let final_rates: Vec; - - for slash in &slashes_this_epoch { - let vp_frac_sum: f64 = 0; - for assoc_slash in &associated_slashes { - if assoc_slash.id == slash.id { continue; } - vp_frac_sum += assoc_slash.validator.voting_power / total_voting_power; - } - let rate = max( slash.infraction_type.0 , 9 * vp_frac_sum * vp_frac_sum ); - final_rates.push(rate) +) -> Decimal { + let mut vp_frac_sum = Decimal::ZERO; + + let start_epoch = current_epoch - cubic_window_width; + let end_epoch = current_epoch + cubic_window_width; + + for epoch in start_epoch..=end_epoch { + let cur_slashes = slashes.get(epoch); + let vp_frac_this_epoch = cur_slashes.iter.fold(0, |sum, Slash{validator, _}| + { sum + validator.voting_power / total_voting_power} + ); + vp_frac_sum += vp_frac_this_epoch; } - final_rates + let rate = cmp::min( + Decimal::ONE, + cmp::max( + slash.infraction_type.0, + 9 * vp_frac_sum * vp_frac_sum, + ), + ); + rate } ``` -As a function, it can be drawn as: +As a function, it can be drawn as (assuming $r_{\text{min}} = 1\%$): [](../images/cubic_slash.png) From 23b205aaef200e285c31daa91a694429c712f875 Mon Sep 17 00:00:00 2001 From: Bengt Date: Thu, 22 Dec 2022 10:29:33 +0000 Subject: [PATCH 083/166] added chain id and fixed install docs --- .../testnets/run-your-genesis-validator.md | 2 +- .../docs/src/testnets/running-a-full-node.md | 2 +- .../docs/src/user-guide/install/README.md | 94 +------------------ 3 files changed, 7 insertions(+), 91 deletions(-) diff --git a/documentation/docs/src/testnets/run-your-genesis-validator.md b/documentation/docs/src/testnets/run-your-genesis-validator.md index ccf0c1d314..9edda25eb6 100644 --- a/documentation/docs/src/testnets/run-your-genesis-validator.md +++ b/documentation/docs/src/testnets/run-your-genesis-validator.md @@ -31,7 +31,7 @@ With the new update, the folder will be located in the `.namada` folder rather t - Wait for the genesis file to be ready, `CHAIN_ID`. - Join the network with the `CHAIN_ID` ``` bash - export CHAIN_ID="TBD" + export CHAIN_ID="public-testnet-1.0.05ab4adb9db" namada client utils join-network \ --chain-id $CHAIN_ID --genesis-validator $ALIAS ``` diff --git a/documentation/docs/src/testnets/running-a-full-node.md b/documentation/docs/src/testnets/running-a-full-node.md index b8948f922a..1ce05838ad 100644 --- a/documentation/docs/src/testnets/running-a-full-node.md +++ b/documentation/docs/src/testnets/running-a-full-node.md @@ -2,7 +2,7 @@ - Wait for the genesis file to be ready, you will receive a `$CHAIN_ID`. - Join the network with the `CHAIN_ID` ```bash - export CHAIN_ID="TBD" + export CHAIN_ID="public-testnet-1.0.05ab4adb9db" namada client utils join-network --chain-id $CHAIN_ID ``` - Start your node and sync diff --git a/documentation/docs/src/user-guide/install/README.md b/documentation/docs/src/user-guide/install/README.md index 52b2ff4b87..95e39ec339 100644 --- a/documentation/docs/src/user-guide/install/README.md +++ b/documentation/docs/src/user-guide/install/README.md @@ -4,94 +4,10 @@ At the moment, Namada only supports Linux and macOS. ``` -## Hardware Requirements +Namada can be installed through the following methods: -This section covers the minimum and recommended hardware requirements for engaging with Namada as a validator node. +1. [From source](./from-source.md) +2. [From binaries](./from-binary.md) +3. [From a docker image](./from-docker.md) -### Minimal Hardware Requirements - -| Hardware | Minimal Specifications | -| -------- | -------- | -| CPU | x86_64 or arm64 processor with at least 4 physical cores | -| RAM | 16GB DDR4 | -| Storage | at least 60GB SSD (NVMe SSD is recommended. HDD will be enough for localnet only) | - -There are different ways to install Namada: - -- [From Source](#from-source) -- [From Binaries](#from-binaries) -- [From Docker](#from-docker) - -## From Source - -If you'd like to install Namada from source you will have to install some dependencies first: [Rust](https://www.rust-lang.org/tools/install), [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git), Clang, OpenSSL and LLVM. - -First, [install Rust](https://www.rust-lang.org/tools/install) by following the instructions from the official page. - -At the end of the installation, make sure that Cargo's bin directory ($HOME/.cargo/bin) is available on your PATH environment variable. You can either restart your shell or run `source $HOME/.cargo/env` to continue. - -If you already have Rust installed, make sure you're using the latest version by running: - -```shell -rustup update -``` - -Then, install the remaining dependencies. - -**Ubuntu:** running the following command should install everything needed: - -```shell -sudo apt-get install -y make git-core libssl-dev pkg-config libclang-12-dev build-essential -``` - -**Mac:** installing the Xcode command line tools should provide you with almost everything you need: - -```shell -xcode-select --install -``` - -Now, that you have all dependencies installed you can clone the source code from the [Namada repository](https://github.com/anoma/namada) and build it with: - -```admonish warning -During internal and private testnets, checkout the latest testnet branch using `git checkout $NAMADA_TESTNET_BRANCH`. -``` - -```shell -git clone https://github.com/anoma/namada.git -cd namada -make install -``` - -## From Binaries - -```admonish warning -Prebuilt binaries might not be available for a specific release or architecture, in this case you have to [build from source](#from-source). -``` - -If you'd like to install Namada from binaries you will have to install some dependencies first: [Tendermint](https://docs.tendermint.com/master/introduction/install.html) `0.34.x` and GLIBC `v2.29` or higher. - -Let's install Tendermint. - -You can either follow the instructions on the [Tendermint guide](https://docs.tendermint.com/master/introduction/install.html) or download the `get_tendermint.sh` script from the [Namada repository](https://github.com/anoma/namada/blob/master/scripts/install/get_tendermint.sh) and execute it (will ask you for `root` access): - -```shell -curl -LO https://raw.githubusercontent.com/namada/namada/main/scripts/install/get_tendermint.sh -chmod +x get_tendermint.sh -./get_tendermint.sh -``` - -Finally, you should have GLIBC `v2.29` or higher. - -**MacOS**: the system-provided glibc should be recent enough. - -**Ubuntu 20.04**: this is installed by default and you don't have to do anything more. - -**Ubuntu 18.04**: glibc has `v2.27` by default which is lower than the required version to run Namada. We recommend to directly [install from source](#from-source) or upgrade to Ubuntu 19.04, instead of updating glibc to the required version, since the latter way can be a messy and tedious task. In case, updating glibc would interest you this [website](http://www.linuxfromscratch.org/lfs/view/9.0-systemd/chapter05/glibc.html) gives you the steps to build the package from source. - -Now, that you have all dependencies installed you can download the latest binary release from our [releases page](https://github.com/anoma/namada/releases) by choosing the appropriate architecture. - -[fixme]: <> (update docker config as soon as Namada is transferred fully to Namada) - -## From Docker - -You can find the Namada docker image [here](https://github.com/anoma/namada/pkgs/container/namada) +The hardware requirements for installing and running a Namada full node can be found [here](./hardware.md) \ No newline at end of file From 08d9eb3e5fdbf32f322e3c60f8a3d0e91738f72d Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Thu, 22 Dec 2022 14:31:06 +0000 Subject: [PATCH 084/166] Hot fix PrepareProposal --- .../lib/node/ledger/shell/prepare_proposal.rs | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/prepare_proposal.rs b/apps/src/lib/node/ledger/shell/prepare_proposal.rs index 9338ecc482..379dcba209 100644 --- a/apps/src/lib/node/ledger/shell/prepare_proposal.rs +++ b/apps/src/lib/node/ledger/shell/prepare_proposal.rs @@ -13,6 +13,13 @@ use crate::facade::tendermint_proto::abci::{tx_record::TxAction, TxRecord}; use crate::node::ledger::shell::{process_tx, ShellMode}; use crate::node::ledger::shims::abcipp_shim_types::shim::TxBytes; +// TODO: remove this hard-coded value; Tendermint, and thus +// Namada uses 20 MiB max block sizes by default; 16 MiB leaves +// plenty of room for header data, evidence and protobuf serialization +// overhead +const MAX_PROPOSAL_SIZE: usize = 16 << 20; +const HALF_MAX_PROPOSAL_SIZE: usize = MAX_PROPOSAL_SIZE / 2; + impl Shell where D: DB + for<'iter> DBIter<'iter> + Sync + 'static, @@ -38,12 +45,20 @@ where // TODO: Craft the Ethereum state update tx // filter in half of the new txs from Tendermint, only keeping // wrappers - let number_of_new_txs = 1 + req.txs.len() / 2; + let mut total_proposal_size = 0; #[cfg(feature = "abcipp")] let mut txs: Vec = req .txs .into_iter() - .take(number_of_new_txs) + .take_while(|tx_bytes| { + let new_size = total_proposal_size + tx_bytes.len(); + if new_size > HALF_MAX_PROPOSAL_SIZE { + false + } else { + total_proposal_size = new_size; + true + } + }) .map(|tx_bytes| { if let Ok(Ok(TxType::Wrapper(_))) = Tx::try_from(tx_bytes.as_slice()).map(process_tx) @@ -58,7 +73,15 @@ where let mut txs: Vec = req .txs .into_iter() - .take(number_of_new_txs) + .take_while(|tx_bytes| { + let new_size = total_proposal_size + tx_bytes.len(); + if new_size > HALF_MAX_PROPOSAL_SIZE { + false + } else { + total_proposal_size = new_size; + true + } + }) .filter_map(|tx_bytes| { if let Ok(Ok(TxType::Wrapper(_))) = Tx::try_from(tx_bytes.as_slice()).map(process_tx) From 0733ddce57f9d3b412eb5a2b16c18ad09e14ae1b Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Thu, 22 Dec 2022 14:39:40 +0000 Subject: [PATCH 085/166] Prioritize wrapper txs during proposal construction --- .../lib/node/ledger/shell/prepare_proposal.rs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/prepare_proposal.rs b/apps/src/lib/node/ledger/shell/prepare_proposal.rs index 379dcba209..e0c2bf5f6a 100644 --- a/apps/src/lib/node/ledger/shell/prepare_proposal.rs +++ b/apps/src/lib/node/ledger/shell/prepare_proposal.rs @@ -50,15 +50,6 @@ where let mut txs: Vec = req .txs .into_iter() - .take_while(|tx_bytes| { - let new_size = total_proposal_size + tx_bytes.len(); - if new_size > HALF_MAX_PROPOSAL_SIZE { - false - } else { - total_proposal_size = new_size; - true - } - }) .map(|tx_bytes| { if let Ok(Ok(TxType::Wrapper(_))) = Tx::try_from(tx_bytes.as_slice()).map(process_tx) @@ -68,11 +59,6 @@ where record::remove(tx_bytes) } }) - .collect(); - #[cfg(not(feature = "abcipp"))] - let mut txs: Vec = req - .txs - .into_iter() .take_while(|tx_bytes| { let new_size = total_proposal_size + tx_bytes.len(); if new_size > HALF_MAX_PROPOSAL_SIZE { @@ -82,6 +68,11 @@ where true } }) + .collect(); + #[cfg(not(feature = "abcipp"))] + let mut txs: Vec = req + .txs + .into_iter() .filter_map(|tx_bytes| { if let Ok(Ok(TxType::Wrapper(_))) = Tx::try_from(tx_bytes.as_slice()).map(process_tx) @@ -91,6 +82,15 @@ where None } }) + .take_while(|tx_bytes| { + let new_size = total_proposal_size + tx_bytes.len(); + if new_size > HALF_MAX_PROPOSAL_SIZE { + false + } else { + total_proposal_size = new_size; + true + } + }) .collect(); // decrypt the wrapper txs included in the previous block From 8820d7ac9087ec34b1936ece4b840824120fd120 Mon Sep 17 00:00:00 2001 From: Bengt Date: Thu, 22 Dec 2022 16:23:12 +0000 Subject: [PATCH 086/166] missed a chain-id addition --- documentation/docs/src/testnets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/src/testnets/README.md b/documentation/docs/src/testnets/README.md index f7a01da96e..220fd4ed72 100644 --- a/documentation/docs/src/testnets/README.md +++ b/documentation/docs/src/testnets/README.md @@ -25,7 +25,7 @@ All public testnets will be listed here: - Namada protocol version: `v0.12.0` - Tendermint version: `v0.1.4-abciplus` - Genesis time: 20th of December 2022 at 17:00 UTC - - CHAIN_ID: `TBD` + - CHAIN_ID: `public-testnet-1.0.05ab4adb9db` ## Block explorer The block explorer is currently in development. The latest version can be found at [namada.world](https://namada.world/) From 2a77752741c55811a2bc9ce8758a98cabdf23962 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Thu, 22 Dec 2022 11:10:37 -0500 Subject: [PATCH 087/166] prepare_proposal: use TxRecord struct on ABCI++ build --- apps/src/lib/node/ledger/shell/prepare_proposal.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/prepare_proposal.rs b/apps/src/lib/node/ledger/shell/prepare_proposal.rs index e0c2bf5f6a..a585695043 100644 --- a/apps/src/lib/node/ledger/shell/prepare_proposal.rs +++ b/apps/src/lib/node/ledger/shell/prepare_proposal.rs @@ -59,9 +59,11 @@ where record::remove(tx_bytes) } }) - .take_while(|tx_bytes| { - let new_size = total_proposal_size + tx_bytes.len(); - if new_size > HALF_MAX_PROPOSAL_SIZE { + .take_while(|tx_record| { + let new_size = total_proposal_size + tx_record.tx.len(); + if new_size > HALF_MAX_PROPOSAL_SIZE + || tx_record.action != TxAction::Unmodified as i32 + { false } else { total_proposal_size = new_size; From 7d822f36c132effb29f29588363d0d035d92fbc1 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Thu, 22 Dec 2022 11:19:24 -0500 Subject: [PATCH 088/166] prepare_proposal: update comment to reflect hotfix --- apps/src/lib/node/ledger/shell/prepare_proposal.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/prepare_proposal.rs b/apps/src/lib/node/ledger/shell/prepare_proposal.rs index a585695043..8f56f9a86a 100644 --- a/apps/src/lib/node/ledger/shell/prepare_proposal.rs +++ b/apps/src/lib/node/ledger/shell/prepare_proposal.rs @@ -27,9 +27,10 @@ where { /// Begin a new block. /// - /// We include half of the new wrapper txs given to us from the mempool - /// by tendermint. The rest of the block is filled with decryptions - /// of the wrapper txs from the previously committed block. + /// We fill half the block space with new wrapper txs given to us + /// from the mempool by tendermint. The rest of the block is filled + /// with decryptions of the wrapper txs from the previously + /// committed block. /// /// INVARIANT: Any changes applied in this method must be reverted if /// the proposal is rejected (unless we can simply overwrite From 0410c6bda12a53261e545f1917c8eb50dae9b5d5 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Thu, 22 Dec 2022 11:02:09 -0500 Subject: [PATCH 089/166] changelog: add #952 --- .changelog/unreleased/bug-fixes/952-hotfix-prepare-proposal.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/bug-fixes/952-hotfix-prepare-proposal.md diff --git a/.changelog/unreleased/bug-fixes/952-hotfix-prepare-proposal.md b/.changelog/unreleased/bug-fixes/952-hotfix-prepare-proposal.md new file mode 100644 index 0000000000..488fd4fcc1 --- /dev/null +++ b/.changelog/unreleased/bug-fixes/952-hotfix-prepare-proposal.md @@ -0,0 +1,2 @@ +- Limit block space to under Tendermint's limit, and limit transactions included + in a block by their size. ([#952](https://github.com/anoma/namada/pull/952)) \ No newline at end of file From c77123ee866b02e7931053ad7389d93a5a368733 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Wed, 21 Dec 2022 07:44:25 -0500 Subject: [PATCH 090/166] release: cherry-pick release improvements This cherry-picks the merges of branches 'namada/ray/no-matchmaker-in-package' (#943) and 'namada/ray/release-include-license' (#945) into main, as merged in commit 077f0883e12199b841d71838275bcbe35696b8a6. I was an incompetent maintainer here, and if you are reading this, you are paying the price. * namada/ray/no-matchmaker-in-package: changelog: add #943 make-package.sh: don't attempt to include matchmaker * namada/ray/release-include-license: changelog: add #945 ci: install cargo-about on release step make-package.sh: include license information in tarball release: add configuration for cargo-about --- .../943-no-matchmaker-in-package.md | 2 ++ .../945-release-include-license.md | 2 ++ .github/workflows/release.yml | 3 +++ about.hbs | 22 +++++++++++++++++++ about.toml | 17 ++++++++++++++ scripts/make-package.sh | 6 +++-- 6 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 .changelog/unreleased/miscellaneous/943-no-matchmaker-in-package.md create mode 100644 .changelog/unreleased/miscellaneous/945-release-include-license.md create mode 100644 about.hbs create mode 100644 about.toml diff --git a/.changelog/unreleased/miscellaneous/943-no-matchmaker-in-package.md b/.changelog/unreleased/miscellaneous/943-no-matchmaker-in-package.md new file mode 100644 index 0000000000..13758711e4 --- /dev/null +++ b/.changelog/unreleased/miscellaneous/943-no-matchmaker-in-package.md @@ -0,0 +1,2 @@ +- Don't attempt to include matchmaker DLLs, which no longer exist, in release + packages. ([#943](https://github.com/anoma/namada/pull/943)) \ No newline at end of file diff --git a/.changelog/unreleased/miscellaneous/945-release-include-license.md b/.changelog/unreleased/miscellaneous/945-release-include-license.md new file mode 100644 index 0000000000..55d0b60f60 --- /dev/null +++ b/.changelog/unreleased/miscellaneous/945-release-include-license.md @@ -0,0 +1,2 @@ +- Include license information in release binary tarballs. + ([#945](https://github.com/anoma/namada/pull/945)) \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 114ca0455d..9de90b80a2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,6 +72,9 @@ jobs: ~/.cargo/git key: ${{ runner.os }}-namada-release-${{ matrix.namada_cache_version }}-${{ hashFiles('**/Cargo.lock') }} restore-keys: ${{ runner.os }}-namada-release-${{ matrix.namada_cache_version }} + - name: Install cargo-about + run: | + cargo install --version 0.5.2 cargo-about - name: Start sccache server run: sccache --start-server - name: ${{ matrix.make.name }} diff --git a/about.hbs b/about.hbs new file mode 100644 index 0000000000..8dc9490c5d --- /dev/null +++ b/about.hbs @@ -0,0 +1,22 @@ +Third Party Licenses + +Overview of licenses: + +{{#each overview}} +{{{name}}} ({{count}}) +{{/each}} + +All license text: + +{{#each licenses}} +{{{name}}} + +Used by: + +{{#each used_by}} +{{crate.name}} {{crate.version}} +<{{#if crate.repository}}{{crate.repository}}{{else}}https://crates.io/crates/{{crate.name}}{{/if}}> +{{/each}} + +{{{text}}} +{{/each}} diff --git a/about.toml b/about.toml new file mode 100644 index 0000000000..d080250749 --- /dev/null +++ b/about.toml @@ -0,0 +1,17 @@ +accepted = [ + "MIT", + "0BSD", + "ISC", + "Unlicense", + "BSD-2-Clause", + "BSD-3-Clause", + "CC0-1.0", + "MPL-2.0", + "GPL-3.0", + "OSL-3.0", + "OpenSSL", + "Unicode-DFS-2016", + "Apache-2.0 WITH LLVM-exception", + "Apache-2.0", + "NOASSERTION", +] diff --git a/scripts/make-package.sh b/scripts/make-package.sh index 8ae06589bb..90a0429fee 100755 --- a/scripts/make-package.sh +++ b/scripts/make-package.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash # Make a release archive from built Namada binaries and dylib(s) +# depends on cargo-about 0.5.2 set -e @@ -11,8 +12,9 @@ BIN="namada namadac namadan namadaw" mkdir -p ${PACKAGE_NAME} && \ cd target/release && \ -MM_TOKEN_EXCH=$(find . -maxdepth 1 -name 'libmm_token_exch.so' -or -name 'libmm_token_exch.dll' -or -name 'libmm_token_exch.dylib') && \ -ln ${BIN} ${MM_TOKEN_EXCH} ../../${PACKAGE_NAME} && \ +ln ${BIN} ../../${PACKAGE_NAME} && \ cd ../.. && \ +ln LICENSE ${PACKAGE_NAME} && \ +cargo about generate about.hbs > ${PACKAGE_NAME}/LICENSE.thirdparty && \ tar -c -z -f ${PACKAGE_NAME}.tar.gz ${PACKAGE_NAME} && \ rm -rf ${PACKAGE_NAME} From e3c2bd0b463b35d66fcc6d2643fd0e6509e03d99 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Thu, 22 Dec 2022 11:45:06 -0500 Subject: [PATCH 091/166] Namada 0.12.2 --- .../bug-fixes/952-hotfix-prepare-proposal.md | 0 .../943-no-matchmaker-in-package.md | 0 .../945-release-include-license.md | 0 .changelog/v0.12.2/summary.md | 2 ++ CHANGELOG.md | 17 +++++++++ Cargo.lock | 20 +++++------ apps/Cargo.toml | 2 +- core/Cargo.toml | 2 +- encoding_spec/Cargo.toml | 2 +- macros/Cargo.toml | 2 +- proof_of_stake/Cargo.toml | 2 +- shared/Cargo.toml | 2 +- tests/Cargo.toml | 2 +- tx_prelude/Cargo.toml | 2 +- vm_env/Cargo.toml | 2 +- vp_prelude/Cargo.toml | 2 +- wasm/Cargo.lock | 22 ++++++------ wasm/checksums.json | 34 +++++++++--------- wasm/tx_template/Cargo.toml | 2 +- wasm/vp_template/Cargo.toml | 2 +- wasm/wasm_source/Cargo.toml | 2 +- wasm_for_tests/tx_memory_limit.wasm | Bin 133398 -> 133402 bytes wasm_for_tests/tx_mint_tokens.wasm | Bin 352849 -> 352709 bytes wasm_for_tests/tx_proposal_code.wasm | Bin 203872 -> 203733 bytes wasm_for_tests/tx_read_storage_key.wasm | Bin 152560 -> 152416 bytes wasm_for_tests/tx_write_storage_key.wasm | Bin 226642 -> 226647 bytes wasm_for_tests/vp_always_false.wasm | Bin 156489 -> 156489 bytes wasm_for_tests/vp_always_true.wasm | Bin 156489 -> 156489 bytes wasm_for_tests/vp_eval.wasm | Bin 157426 -> 157426 bytes wasm_for_tests/vp_memory_limit.wasm | Bin 158937 -> 158937 bytes wasm_for_tests/vp_read_storage_key.wasm | Bin 168265 -> 170669 bytes wasm_for_tests/wasm_source/Cargo.lock | 18 +++++----- wasm_for_tests/wasm_source/Cargo.toml | 2 +- 33 files changed, 80 insertions(+), 61 deletions(-) rename .changelog/{unreleased => v0.12.2}/bug-fixes/952-hotfix-prepare-proposal.md (100%) rename .changelog/{unreleased => v0.12.2}/miscellaneous/943-no-matchmaker-in-package.md (100%) rename .changelog/{unreleased => v0.12.2}/miscellaneous/945-release-include-license.md (100%) create mode 100644 .changelog/v0.12.2/summary.md diff --git a/.changelog/unreleased/bug-fixes/952-hotfix-prepare-proposal.md b/.changelog/v0.12.2/bug-fixes/952-hotfix-prepare-proposal.md similarity index 100% rename from .changelog/unreleased/bug-fixes/952-hotfix-prepare-proposal.md rename to .changelog/v0.12.2/bug-fixes/952-hotfix-prepare-proposal.md diff --git a/.changelog/unreleased/miscellaneous/943-no-matchmaker-in-package.md b/.changelog/v0.12.2/miscellaneous/943-no-matchmaker-in-package.md similarity index 100% rename from .changelog/unreleased/miscellaneous/943-no-matchmaker-in-package.md rename to .changelog/v0.12.2/miscellaneous/943-no-matchmaker-in-package.md diff --git a/.changelog/unreleased/miscellaneous/945-release-include-license.md b/.changelog/v0.12.2/miscellaneous/945-release-include-license.md similarity index 100% rename from .changelog/unreleased/miscellaneous/945-release-include-license.md rename to .changelog/v0.12.2/miscellaneous/945-release-include-license.md diff --git a/.changelog/v0.12.2/summary.md b/.changelog/v0.12.2/summary.md new file mode 100644 index 0000000000..03de0ee74c --- /dev/null +++ b/.changelog/v0.12.2/summary.md @@ -0,0 +1,2 @@ +Namada 0.12.2 is a hotfix release, limiting transactions included in a +block by size. diff --git a/CHANGELOG.md b/CHANGELOG.md index c43936dd31..e5e37c9b0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # CHANGELOG +## v0.12.2 + +Namada 0.12.2 is a hotfix release, limiting transactions included in a +block by size. + +### BUG FIXES + +- Limit block space to under Tendermint's limit, and limit transactions included + in a block by their size. ([#952](https://github.com/anoma/namada/pull/952)) + +### MISCELLANEOUS + +- Don't attempt to include matchmaker DLLs, which no longer exist, in release + packages. ([#943](https://github.com/anoma/namada/pull/943)) +- Include license information in release binary tarballs. + ([#945](https://github.com/anoma/namada/pull/945)) + ## v0.12.1 Namada 0.12.1 is a hotfix release, fixing a node crash on malformed diff --git a/Cargo.lock b/Cargo.lock index 569ef32e37..6f943b09c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3635,7 +3635,7 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "namada" -version = "0.12.1" +version = "0.12.2" dependencies = [ "assert_matches", "async-trait", @@ -3692,7 +3692,7 @@ dependencies = [ [[package]] name = "namada_apps" -version = "0.12.1" +version = "0.12.2" dependencies = [ "ark-serialize", "ark-std", @@ -3778,7 +3778,7 @@ dependencies = [ [[package]] name = "namada_core" -version = "0.12.1" +version = "0.12.2" dependencies = [ "ark-bls12-381", "ark-ec", @@ -3830,7 +3830,7 @@ dependencies = [ [[package]] name = "namada_encoding_spec" -version = "0.12.1" +version = "0.12.2" dependencies = [ "borsh", "itertools", @@ -3841,7 +3841,7 @@ dependencies = [ [[package]] name = "namada_macros" -version = "0.12.1" +version = "0.12.2" dependencies = [ "quote", "syn", @@ -3849,7 +3849,7 @@ dependencies = [ [[package]] name = "namada_proof_of_stake" -version = "0.12.1" +version = "0.12.2" dependencies = [ "borsh", "derivative", @@ -3863,7 +3863,7 @@ dependencies = [ [[package]] name = "namada_tests" -version = "0.12.1" +version = "0.12.2" dependencies = [ "assert_cmd", "borsh", @@ -3907,7 +3907,7 @@ dependencies = [ [[package]] name = "namada_tx_prelude" -version = "0.12.1" +version = "0.12.2" dependencies = [ "borsh", "masp_primitives", @@ -3922,7 +3922,7 @@ dependencies = [ [[package]] name = "namada_vm_env" -version = "0.12.1" +version = "0.12.2" dependencies = [ "borsh", "hex", @@ -3933,7 +3933,7 @@ dependencies = [ [[package]] name = "namada_vp_prelude" -version = "0.12.1" +version = "0.12.2" dependencies = [ "borsh", "namada_core", diff --git a/apps/Cargo.toml b/apps/Cargo.toml index 7bbe802b58..bd7773e3b3 100644 --- a/apps/Cargo.toml +++ b/apps/Cargo.toml @@ -6,7 +6,7 @@ license = "GPL-3.0" name = "namada_apps" readme = "../README.md" resolver = "2" -version = "0.12.1" +version = "0.12.2" default-run = "namada" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/core/Cargo.toml b/core/Cargo.toml index 5f5381b38f..3df5654132 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_core" resolver = "2" -version = "0.12.1" +version = "0.12.2" [features] default = [] diff --git a/encoding_spec/Cargo.toml b/encoding_spec/Cargo.toml index a493ea3dc9..6f9b17a5dd 100644 --- a/encoding_spec/Cargo.toml +++ b/encoding_spec/Cargo.toml @@ -6,7 +6,7 @@ license = "GPL-3.0" name = "namada_encoding_spec" readme = "../README.md" resolver = "2" -version = "0.12.1" +version = "0.12.2" [features] default = ["abciplus"] diff --git a/macros/Cargo.toml b/macros/Cargo.toml index ab2dea5b9e..dd4170e48f 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_macros" resolver = "2" -version = "0.12.1" +version = "0.12.2" [lib] proc-macro = true diff --git a/proof_of_stake/Cargo.toml b/proof_of_stake/Cargo.toml index a7b1417608..a27f508935 100644 --- a/proof_of_stake/Cargo.toml +++ b/proof_of_stake/Cargo.toml @@ -6,7 +6,7 @@ license = "GPL-3.0" name = "namada_proof_of_stake" readme = "../README.md" resolver = "2" -version = "0.12.1" +version = "0.12.2" [features] default = ["abciplus"] diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 0683648271..25b039963e 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada" resolver = "2" -version = "0.12.1" +version = "0.12.2" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tests/Cargo.toml b/tests/Cargo.toml index fd8c123bb5..b4c4065ec0 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_tests" resolver = "2" -version = "0.12.1" +version = "0.12.2" [features] default = ["abciplus", "wasm-runtime"] diff --git a/tx_prelude/Cargo.toml b/tx_prelude/Cargo.toml index ae0e303939..447867ac7d 100644 --- a/tx_prelude/Cargo.toml +++ b/tx_prelude/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_tx_prelude" resolver = "2" -version = "0.12.1" +version = "0.12.2" [features] default = ["abciplus"] diff --git a/vm_env/Cargo.toml b/vm_env/Cargo.toml index df7f726863..11be9ef2e1 100644 --- a/vm_env/Cargo.toml +++ b/vm_env/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_vm_env" resolver = "2" -version = "0.12.1" +version = "0.12.2" [features] default = ["abciplus"] diff --git a/vp_prelude/Cargo.toml b/vp_prelude/Cargo.toml index 3489f62172..8ea87a3426 100644 --- a/vp_prelude/Cargo.toml +++ b/vp_prelude/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_vp_prelude" resolver = "2" -version = "0.12.1" +version = "0.12.2" [features] default = ["abciplus"] diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index 52b7029972..e048b22942 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -2456,7 +2456,7 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "namada" -version = "0.12.1" +version = "0.12.2" dependencies = [ "async-trait", "bellman", @@ -2500,7 +2500,7 @@ dependencies = [ [[package]] name = "namada_core" -version = "0.12.1" +version = "0.12.2" dependencies = [ "ark-bls12-381", "ark-serialize", @@ -2541,7 +2541,7 @@ dependencies = [ [[package]] name = "namada_macros" -version = "0.12.1" +version = "0.12.2" dependencies = [ "quote", "syn", @@ -2549,7 +2549,7 @@ dependencies = [ [[package]] name = "namada_proof_of_stake" -version = "0.12.1" +version = "0.12.2" dependencies = [ "borsh", "derivative", @@ -2563,7 +2563,7 @@ dependencies = [ [[package]] name = "namada_tests" -version = "0.12.1" +version = "0.12.2" dependencies = [ "chrono", "concat-idents", @@ -2592,7 +2592,7 @@ dependencies = [ [[package]] name = "namada_tx_prelude" -version = "0.12.1" +version = "0.12.2" dependencies = [ "borsh", "masp_primitives", @@ -2607,7 +2607,7 @@ dependencies = [ [[package]] name = "namada_vm_env" -version = "0.12.1" +version = "0.12.2" dependencies = [ "borsh", "hex", @@ -2618,7 +2618,7 @@ dependencies = [ [[package]] name = "namada_vp_prelude" -version = "0.12.1" +version = "0.12.2" dependencies = [ "borsh", "namada_core", @@ -2631,7 +2631,7 @@ dependencies = [ [[package]] name = "namada_wasm" -version = "0.12.1" +version = "0.12.2" dependencies = [ "borsh", "getrandom 0.2.8", @@ -4601,7 +4601,7 @@ dependencies = [ [[package]] name = "tx_template" -version = "0.12.1" +version = "0.12.2" dependencies = [ "borsh", "getrandom 0.2.8", @@ -4738,7 +4738,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "vp_template" -version = "0.12.1" +version = "0.12.2" dependencies = [ "borsh", "getrandom 0.2.8", diff --git a/wasm/checksums.json b/wasm/checksums.json index bf6efb760c..28920cb703 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,20 +1,20 @@ { - "tx_bond.wasm": "tx_bond.c80510dae9aa8785a33301a16747b358da20cb125edae01e330eba2153ca28f4.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.655b344c2d9cc602f9250cf390112ff2c9293537cdc1eb4a52c58ee622ccb538.wasm", - "tx_ibc.wasm": "tx_ibc.de66b4cc33061f503c63964debda8061ab9e0f1294e6c5c510d4b94a409a2edf.wasm", - "tx_init_account.wasm": "tx_init_account.87940d07eac068e03cfe5cd8b491032b3f1814d36060cbc761beb528f1c27b46.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.2464b3de1c3aa4ed25cf592366df3b744ec3d2030ce952ea18f38066d4091693.wasm", - "tx_init_validator.wasm": "tx_init_validator.6a27ed0de01ab555628129ac9f05801d5ac812824633bd36e43b1d67b6360db6.wasm", - "tx_reveal_pk.wasm": "tx_reveal_pk.d22e9b3310bad29fea038b42b4120f12b11ffe0ec4012ddf2d709aed490cac97.wasm", - "tx_transfer.wasm": "tx_transfer.3f6d8d0c103bd631c7cd12b58663e026aa9743f8552b14919a1b5bcd9fd31741.wasm", - "tx_unbond.wasm": "tx_unbond.6b801584c4d01f7b52988e5ecf971050e1575f1e15f818f3e2694604b402ebd8.wasm", + "tx_bond.wasm": "tx_bond.ca30060af7fd7e9a8573c6ee157dccc1e2f3612383716d6bb2ca0b06026f1856.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.7d09576a72068734b8e259df35ce98fabe98db990c337588793a616aa095d24f.wasm", + "tx_ibc.wasm": "tx_ibc.92813d74be4f538b7599236f948498a6f41248f9470cce1410245460f968509b.wasm", + "tx_init_account.wasm": "tx_init_account.9f01fbd633bf6197cec25c1459706e0a9eeb209f02770bebf60b58668f296449.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.61e6a2dcdcbb21e5b75fd222d41bacb8cce8079ee59343c0d6121cf2e979a192.wasm", + "tx_init_validator.wasm": "tx_init_validator.0e467208eedbc236ff899abe2afdd3d4b7ceae5bd2f74a6a884d8de68d77867f.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.05dfde69e33f0833fc25ad653066da73ef04a2b2f7894ba9fa509d2dd759ae8b.wasm", + "tx_transfer.wasm": "tx_transfer.67251510b104fc2485fe15c02bea2adb53d5b48b83fb04c19eeceba99d0b3d8c.wasm", + "tx_unbond.wasm": "tx_unbond.59758396baa9c88432610a3912fa98060f07430fc182736eba7bfb1d53f4b71d.wasm", "tx_update_vp.wasm": "tx_update_vp.ee2e9b882c4accadf4626e87d801c9ac8ea8c61ccea677e0532fc6c1ee7db6a2.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.37269505f1526de9680b619413478a071ed2f92b22924e6fbb3b7127f88da41a.wasm", - "tx_withdraw.wasm": "tx_withdraw.e5affdbd26cdd08aff6dfc37c5b3d92a8784547e28d039b863a6a95d5ac1cc97.wasm", - "vp_implicit.wasm": "vp_implicit.2f0b200b9e0f3db5151e0b86f5e66ae1b7e43e01d8cdc852db1337c744fac4b6.wasm", - "vp_masp.wasm": "vp_masp.da15ab8670750f400fc12616921dc3c959386bdb5d2df4f455f2299847c257ee.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.13f1911794bc69e4d7dcebd30b048740398b5d45f7efee95a07a627b1a46fa47.wasm", - "vp_token.wasm": "vp_token.497a346ebcc1b7e7b844a8aab644a8d43ab9399006a95c7ca411035b8966b05e.wasm", - "vp_user.wasm": "vp_user.59c397bd2356d01cea5379de64882423cf1e2bb361301651573c1e3619d43551.wasm", - "vp_validator.wasm": "vp_validator.0b13e2f48407640ca35414c5b855f3e20f3393f60ff987aaa3b0febbb0d64e51.wasm" + "tx_vote_proposal.wasm": "tx_vote_proposal.7764e840c0208e33c1d36248d90bbac1b46b3895da856f3b43023e4514452f7f.wasm", + "tx_withdraw.wasm": "tx_withdraw.b12de7e85658ccf62cf768b4453cfb0874a69b2a44cc6700bfa6d2051cc76951.wasm", + "vp_implicit.wasm": "vp_implicit.6ed791b49045ec27261e443b136890a82503b3647eca8e1e9c41c5fa9718b963.wasm", + "vp_masp.wasm": "vp_masp.55b19f9f592ed699af841905530e4b753117203afb4444c9add61ea10bda8d10.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.044176fd93e4158f1e0c3a872bcd5a9a5fd6c25cff9b1e0055f9b6ace6a54870.wasm", + "vp_token.wasm": "vp_token.31036edb5bc48f4c9d6915486e61e5c4aadc1e8d8602d658b27f1789b2697e35.wasm", + "vp_user.wasm": "vp_user.675c2a29d5e5383a6d465bd88dd9a4586f4a2821db2f13fd2662963ac3906527.wasm", + "vp_validator.wasm": "vp_validator.cdbd8e31bffe2911e7b4a89f4aad408a8cf7a103b1463acdd932f680f16641d3.wasm" } \ No newline at end of file diff --git a/wasm/tx_template/Cargo.toml b/wasm/tx_template/Cargo.toml index 708225ef63..515a8adfe7 100644 --- a/wasm/tx_template/Cargo.toml +++ b/wasm/tx_template/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "tx_template" resolver = "2" -version = "0.12.1" +version = "0.12.2" [lib] crate-type = ["cdylib"] diff --git a/wasm/vp_template/Cargo.toml b/wasm/vp_template/Cargo.toml index 31cb9374b0..d8f3383d9c 100644 --- a/wasm/vp_template/Cargo.toml +++ b/wasm/vp_template/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "vp_template" resolver = "2" -version = "0.12.1" +version = "0.12.2" [lib] crate-type = ["cdylib"] diff --git a/wasm/wasm_source/Cargo.toml b/wasm/wasm_source/Cargo.toml index 0e57b8aec1..043cea9684 100644 --- a/wasm/wasm_source/Cargo.toml +++ b/wasm/wasm_source/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_wasm" resolver = "2" -version = "0.12.1" +version = "0.12.2" [lib] crate-type = ["cdylib"] diff --git a/wasm_for_tests/tx_memory_limit.wasm b/wasm_for_tests/tx_memory_limit.wasm index 9c4ea2abccbcef666288b7ccb0a12e07dd9d4c27..3a83b28632070bdb8b54f73b809ecabf4bc4c365 100755 GIT binary patch delta 1396 zcmah}YiyHM7(VZ5*LJpDi?YtO+j`nv+Ok`VEm8K3C2`xEjGMbpHVh#1`=LY=hlv^m#2M7akZ9zRDIw1AL*xhX{k~nIzx?xj@BQ+e z^PS-#%ZVY&z}dlbMPMAfyaCP+{nxqwGkXPDsW%DVr=6D zoe7`8Dz$jQgWRTYW&hr1puckgE^IM3&4>3qx84gkhJ{i=F=O zKwy3G3xw|$zd~4AatMU_UP%!0wG@Rr1tcNLjRIu3!VBm#jdx0ag(Cc>tP8vt59|_N zAG2|*VDccyfj*ka$Nr@PQ;Kzs(f-+1gg+%UtrGn&B%5kE# zAsQoEUyix}uHsN_D{cNu?H<~Ed);orPwU+I+PeJT%V#qpgUG|hx+mcVhGUhfTcfnC zk-`en(&7y28wO*{L4ns+U5>QOCKt%{5}ZaqYqA^2?M%xBI*K4;3e)NmbzhObaz&ZE zh#$qgj*M2stkWhRaR%{r>?r)K_Qr2%WAE4;E?DWJ=TjHClE9>uqR(%B3#PDs%UYN| zr;Wl+(;bspRM$>n{ab#^Dx$+S;_nGJ4kVr-0&XX||MvpmOAYVv3sczJ=!Vl6ksdgP zt%QfMQ+oJ=NlZ&OEaC(yKTcwsbek?sQd=ADmM+t0nwYJL@Byw%dSC`C2}khNq=yeo z;%L$huWJhYjU!2q>F&g8D!)FV6@#zwPx5|(_C}BCl;(Bmg-@&n!rR#1=z%xz07X0; zU+Z@d7s$M*;{x6#=jWPpd9DjdidD5wjduI$DBsDsc+SthjUv!bPKLfNM;PH zl5T!X|G*{mHF@~Fu9!a7iPqOVNA}0CziGSY%o%E@0lhkYE+I`1iJaApvv{w`M-N$U zbIPRu+!=haxpzfWA2dUjb*2R9mpnMntRrY@X`&yarR5KLJJkBNG25eUdwN8BSC{D6 n-?MYC=-%1B1CO_s@x>gx*y_Sis>8ro=W9n&A0A1;n`i$4+LWEB delta 1402 zcmah}T}+!*7(VZ5`C4oXosJ^?fS$H6%HL>_eTA~E99S_XK-9z=NmOvlq>vE-jhcwe zu>_qaW$(gg^bofJq%mv>lh9%DfG<6{z^WLlXH0NuPs&pymogSL<gHSCR2EU#z3PGL`qH(u?Mu>8&09mf_d|GDkM)41d&(EAz z2M)#$g1|^gw-BV@4k|hXGIf+%46y%5`sI=VfPfw;jqq(Dm(dH+etwu(tB5YpEwKLIGj$tsamNV%+1$U9?{xDc1BCZQU;!}Wykhf~B)ZKTH%++kFt z4wn#XkiB<|F_=HwK%=T&(w4cz%iBl~aBTiq8 zdH|Mjq_!1&c)hll&e>dds7yHgjCvV@WD!xEZH)K+6W=G{?Yc+d28Lsm?KkOmNh`VL zC#Bt8N*TBe#aK4cb?u%hJ1H~C1ai9sw>7{LE(@96Nx4je2r;HHW2D5{=Ok}lRVF{h zOEF*ebt8$5l9Kxa?ozxJI|<+EgY`ceC)mFyoWEJcjHfDcGk{44d4Ig;7);^ry<2W( zpH6Z+OLt9XP+k|gjqF{^FvpHR#l4t{KShk(iue8R~QxkC}FC%Mp%YN0SOi@OARIn>MRa zVOYm6Nxf>~GX6rwD~55Ss|#CO>PYTW`RTNAJpOJPvzolh;eXA);rV?ke2>fIv@(S| z8@>F5xxga&6Dq%K3d%*3Xrndwkn|7XNaAtzgL72S0Q!9bTtbqbvz#-ObNGA0Paj%N zbGu?b?G=2vd2n;9-))8r$7~VMTO3+oj&W3467)t|TGr_g(Ra5^IdT2zBEFJ^S6V#} kw)GB(j-DRT`Rc%de$jWJV?UO+cf!FVsrHMhc6fXKAKYx3P5=M^ diff --git a/wasm_for_tests/tx_mint_tokens.wasm b/wasm_for_tests/tx_mint_tokens.wasm index c5bdd46d33bd84919b65a81c87c723ecb8a5ea79..88fa6792863d1a7013b6cdae762c2497c128d2a5 100755 GIT binary patch delta 18659 zcmc(G34F{)|Nk7jn{3Vvxk)7AND!gU29b5QRK7|`? z7j5zKfTpjFTtKH!dvV0n#dHxh(>z*0^XYuLlnT0nuAwXGa=MHb(jByfZldv;QhJF- z)Qud{#Q4gq-3G^X@6mhMs7XP!-lOMejkoB8DRb#Ux}Ihnr)%kI`Uagx)3?%Xji`lM z>27+6Zl{OoQF?^#rEk)G^Z-3b-=_QNz@hKZLC5H3dWybFPtp_geY(Z$%tO5=)w)72 z(=X_k^ecLUenvm1F2~KS_(?W%uSKuXQJQNuXd6n@R{I`vp11ZWG1fKSvUoYi(E6tf zkCG@tS`ZS#jD}?6G2jS7nkm>h*;t~+d(G4IE$M!9VX(jX1AXS-t(@s1EAMkDq3g^U zu7g;X*}M{xZo4*COVT{k4UMs4H#Ek*<}Pkh(j2!zf4AbQ%rNspj{sDTbHDpt7j9m@md-8RGjB3tn1OJ|W7;^MUOXqA}*0 z1E4RepKRQp1F*^B5>|=Qz2=}A zC)D!)%2asQl=9gqnuhjwHAJytF+iFz1i=!=OyiAgfWlLpS=0&wPUFj-|p|>BU zMdt86IRLx*V8lh1bA7jHfTj!@NAb8b*h`DYlZ0auy^~mnP~cy*(+^Cz!Dmw zjU-E`JD$cYo@{(O8#7SFFvpyqRzjDUUm4d3oY~`U;X64!jLxy-rGG~~iY5DTmJE{% zF%(g_+a}9x2k`O$Mx!N&CXM@%i+S$aVc7{*tDAm4ga<(*ps7#~U zn*Pc%Ta_uT>1t*u|MP|2k{+}4nHHw;cz@YZ5>7}{_+VEo@7(OxI=abxJZG`Gb*E?C zq|-BQ(g|*IZmwLb@8`y-8&?=rUd0JsC2S5FHxHRpABMMZP6Bt>xou6Au2k$?yC9c7 zw&X3C&cp21v=<#!tgFHjJT2GbCUaCl6R6I4QMh?QK@+LIV+C#LEf5r+IdV}Pt$Je( zIO}5NUdGDJ$|@zsLVOu2OM5kcXl?>_m&M9Hk+gVukyJ((zqW?m5^O+(!(JsXs=^pc*;$_fVm({(c&eyGu z`@6Ej)<{`H*7W+j6+f31Eg@?|Dcfc?7t{(c4_sG|ZZpqWr?}5A*L4W9+lkG69y4Qx zHm%0AV8Ss8v7RJU;`V;^7^hxI$C1+ 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 b(_8R5%>grI7ebbw|V7LDRB(XrO diff --git a/wasm_for_tests/tx_proposal_code.wasm b/wasm_for_tests/tx_proposal_code.wasm index a8e7a81527f8c5135a439d61cb53e7660571ef9c..e0a537c73fbe568f708e4d2c5cb4c12ad3c1e0c7 100755 GIT binary patch delta 24134 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 delta 24365 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 Bw%7mw diff --git a/wasm_for_tests/tx_read_storage_key.wasm b/wasm_for_tests/tx_read_storage_key.wasm index 1b5b368833822bec0478e5d20d7974aaa235a550..a074283780832a12ac1fac2c66fe4d92152a705a 100755 GIT binary patch delta 13196 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 delta 13244 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 diff --git a/wasm_for_tests/tx_write_storage_key.wasm b/wasm_for_tests/tx_write_storage_key.wasm index 471bceb93b60337506a2a63bfd2f5dc4e63fb9b0..1d106df7f9f973c7ca0cc5d1c9ea7e81337529c5 100755 GIT binary patch delta 3950 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 SnSZ(&1$fcwn^Bt7SN{v@VDc{j delta 3851 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 Lyf#5u{@i~6H5$X0 diff --git a/wasm_for_tests/vp_always_false.wasm b/wasm_for_tests/vp_always_false.wasm index f5d1881c27d8b93065907d0e793ed70c5281c2cc..f4355d6ba80032290572eae365fa5b73db620c0a 100755 GIT binary patch delta 167 zcmX?kjPv9%&IxD@(n3*OXp33EDYG%dEYUje_yg7+c+=G*oL4m=M!HkJv^I}hV z=E;?wvXc+_Tw`WtVB9?2w~>$0VX|aQGLWo|sb_T9{5M8}5y(-C3j&graVr>|HY>#+ z00})#m=2V$PP`4`geM0BIjfUbb2Hjc4$s#IlI{6njP{%FN!@jfR)j{IlXFo JdKKfN7XX*QH=F^Cov?X^Zv!8r(`3n*WFT1^Q_twM`EQH{BaovO7X&0L<5n;_ zZ&r#w01|qfFdZmgop>9>2~Q3Na#km==4N!99GmtWGXW&ek@zn^PHgnM{6V*1%{qxxvSEvb@>p$?v@858SsWA?fD8pjM@9iI?#b`G-6wPVdOzftv)aSVXt6olZYB$mVs!>mAVs}E1-c&lfb4Zv`je$S<0en{kriNOVC3du zaGLe#$gh*T&&*)oT;VCtJb8op1h6HpK$hF&Up`(?UY9S|=B2)Dtc>QH*93iGV>F+< zFw&6GY4YXB-;9Qv&qsMOGCEF{j7bKPwK4UKj+_6+Xn=&&;(~x=W!wrz=gms-2S7rP z6Q%>@s}pa7IN`~`K+fvqE-s*vW_kKRBh&IeFgi>Q&({Z%?fGGh4x8`gKW72zKUT7U QmC>O&y=r@U72~590C@y+XaE2J diff --git a/wasm_for_tests/vp_eval.wasm b/wasm_for_tests/vp_eval.wasm index 4aec2531643b31cec121ab865efd0a2f5dde4bd8..a5efe220c2e1c5b8840c52730b643c0f44c7b357 100755 GIT binary patch delta 359 zcmex#mh;nD&IyKd9(re;gopNU1pkDU;0y z+n7lvQkkNVb$7ok3M#stKamhe( zc3eH9<7Vl24MrfxB_Rk%PET0D=(5=%@c>AOF?l*rerED*5T`UX7|1!9n#0NHzS%5a zl@VxWOo2Y5^W>g_4~!0zYYX*(%>(y-?WftWHjCU({c|pqt)hZ zwli6PRDctZg2?l^YXIdZ|FqPfyj{|L@&-5Y$uE6nH=py6W(AsdO^TC2fx(f%jER98 z=qPR;2B%q%j{G{g`^*gX%~nAQOpM%RLB=LM$5_jqYW8N zHh+wEWny%iY#x^kBxlFfGdgXSjt5%kG}$E~2uMy(Si$JL*&*=&NQg0cI#7OQ@@){O zG&LB=IhmTn$>_1!EMJuoXl6`-KBLLxo`MgIj+1K(^?~Ht!Z1e1%`8RFSs0xsJ0!|% z<|uDr1&Z|6C~-0Zebeg5=rH+Ht2U#*i5N2j#U}R)wW(1LpEF3_RYvRjBB}+qBUq3egfIu;R0YM`t z7B&ZWW)X1}HFXV5EprPSTRZ#BJ&e4P%*+goo0m%2%TC_l?>6~Nz=X+jc^f9DSR^x= zP5$eqviXgLJR_soW*)0O%#7BXPuk980aD3MK+0_MUpF71++-dr{mGRcah#kC3Ji`6 zW=ss5KYQ>nPQLCTyZOIoAPb|*<1g8)#R*LLq^lhb7EbY7@a3SicbcTZVB~_&YO=VXfOgf?-PT7 zq*KxgMz_tclMaA{)}%}a%Dbdq2XSQ5gMpla^foS_Vc!e&8BHgv7kyxKoGekS4D3b=x)S7&pEH0HGCem;e9( delta 356 zcmcb4lk?_H&Iwx?xh8H?5N2XvWMpP$1d=R_93Un$)5MpJN*0FBzJ6@}0fA!t0)j^N zENpHf%*Ve;GuSuJk+PSaywTz@qv_;R z?kbyiTFNsrnr^;nwTGF}YV$O^nJhrcz!^xHZa(Gi1C*P5(@KA`n`hkQonEq=*LiX? zZocLf$im{p%P2MZpT7hLBew#p0;7P_WN-iVj82n(`#Uo_ZMF}PW1M{3{2DJOg93vi zgBcS8H!}m{=FC8LRz}Osg<(I~7%eAf#TqiYZk`kC%Eah6`B8i_kaSC^XLQ_rEJ1@2 z$a$X_1SFl3RxrA3ew}mxB(x@FI#Avv^*V?nlO7D@6r{It0S)_JsL$v+S-t23qr+s0 pVtpX#Q5?qTuz7y*a~4LI$*+@SHZQJdVP$k^)~MUAQOCIP9RL_>aH0SJ diff --git a/wasm_for_tests/vp_read_storage_key.wasm b/wasm_for_tests/vp_read_storage_key.wasm index 247eb8a4a4ab8bf1402590e5b73c54b9d496b474..f033de0f8750fe6a367db30cdc6a34075d864f60 100755 GIT binary patch delta 30769 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 delta 29687 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 Date: Thu, 22 Dec 2022 12:25:53 -0500 Subject: [PATCH 092/166] ci: install cargo-about after sccache server up This misordering caused release CI to fail on 0.12.2. --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9de90b80a2..fbda4d26f1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,11 +72,11 @@ jobs: ~/.cargo/git key: ${{ runner.os }}-namada-release-${{ matrix.namada_cache_version }}-${{ hashFiles('**/Cargo.lock') }} restore-keys: ${{ runner.os }}-namada-release-${{ matrix.namada_cache_version }} + - name: Start sccache server + run: sccache --start-server - name: Install cargo-about run: | cargo install --version 0.5.2 cargo-about - - name: Start sccache server - run: sccache --start-server - name: ${{ matrix.make.name }} run: make ${{ matrix.make.command }} - name: Upload binaries package From 9f2ccc15506a33ed131a108a1218668424aa1e2b Mon Sep 17 00:00:00 2001 From: Bengt Date: Thu, 22 Dec 2022 18:26:20 +0000 Subject: [PATCH 093/166] changed to 0.12.2 --- documentation/docs/src/testnets/environment-setup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/docs/src/testnets/environment-setup.md b/documentation/docs/src/testnets/environment-setup.md index 3e3af28064..ced6d8af0b 100644 --- a/documentation/docs/src/testnets/environment-setup.md +++ b/documentation/docs/src/testnets/environment-setup.md @@ -2,7 +2,7 @@ - Export the following variables: ```bash - export NAMADA_TAG=v0.12.0 + export NAMADA_TAG=v0.12.2 export TM_HASH=v0.1.4-abciplus ``` @@ -51,4 +51,4 @@ - Make sure you are using the correct tendermint version - `tendermint version` should output `0.1.4-abciplus` - Make sure you are using the correct Namada version - - `namada --version` should output `Namada v0.12.0` + - `namada --version` should output `Namada v0.12.2` From ef19b3afefa5eb798917348f4be96a45c5f8f10d Mon Sep 17 00:00:00 2001 From: DaveWK <13626476+DaveWK@users.noreply.github.com> Date: Fri, 23 Dec 2022 08:27:15 -0500 Subject: [PATCH 094/166] Add JSON as an option for logging by env var --- Cargo.lock | 13 +++++++++++++ apps/Cargo.toml | 2 +- apps/src/lib/logging.rs | 30 +++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f943b09c2..41f8ccf2ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6963,6 +6963,16 @@ dependencies = [ "tracing-core 0.1.30", ] +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde 1.0.147", + "tracing-core 0.1.30", +] + [[package]] name = "tracing-subscriber" version = "0.2.25" @@ -6984,12 +6994,15 @@ dependencies = [ "nu-ansi-term", "once_cell", "regex", + "serde 1.0.147", + "serde_json", "sharded-slab", "smallvec 1.10.0", "thread_local", "tracing 0.1.37", "tracing-core 0.1.30", "tracing-log", + "tracing-serde", ] [[package]] diff --git a/apps/Cargo.toml b/apps/Cargo.toml index bd7773e3b3..972eb41f53 100644 --- a/apps/Cargo.toml +++ b/apps/Cargo.toml @@ -139,7 +139,7 @@ tower-abci-abcipp = {package = "tower-abci", git = "https://github.com/heliaxdev tower-abci = {version = "0.1.0", optional = true} tracing = "0.1.30" tracing-log = "0.1.2" -tracing-subscriber = {version = "0.3.7", features = ["env-filter"]} +tracing-subscriber = {version = "0.3.7", features = ["env-filter", "json"]} websocket = "0.26.2" winapi = "0.3.9" #libmasp = { git = "https://github.com/anoma/masp", branch = "murisi/masp-incentive" } diff --git a/apps/src/lib/logging.rs b/apps/src/lib/logging.rs index b60bab1f69..d8693acfaa 100644 --- a/apps/src/lib/logging.rs +++ b/apps/src/lib/logging.rs @@ -11,6 +11,8 @@ pub const ENV_KEY: &str = "NAMADA_LOG"; // Env var to enable/disable color log const COLOR_ENV_KEY: &str = "NAMADA_LOG_COLOR"; +// Env var to enable/disable json formatting +const JSON_ENV_KEY: &str = "NAMADA_JSON_FMT"; pub fn init_from_env_or(default: impl Into) -> Result<()> { let filter = filter_from_env_or(default); @@ -30,13 +32,27 @@ pub fn set_subscriber(filter: EnvFilter) -> Result<()> { } else { true }; - - let my_collector = Subscriber::builder() - .with_ansi(with_color) - .with_env_filter(filter) - .finish(); - tracing::subscriber::set_global_default(my_collector) - .wrap_err("Failed to set log subscriber") + let json_format = if let Ok(val) = env::var(JSON_ENV_KEY) { + val.to_ascii_lowercase() != "false" + } else { + true + }; + if json_format { + let my_collector = Subscriber::builder() + .with_ansi(with_color) + .json() + .with_env_filter(filter) + .finish(); + tracing::subscriber::set_global_default(my_collector) + .wrap_err("Failed to set log subscriber") + } else { + let my_collector = Subscriber::builder() + .with_ansi(with_color) + .with_env_filter(filter) + .finish(); + tracing::subscriber::set_global_default(my_collector) + .wrap_err("Failed to set log subscriber") + } } pub fn init_log_tracer() -> Result<()> { From 51844e65cc3cd07ceebee14254d0465f58cd51c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 23 Dec 2022 15:03:31 +0100 Subject: [PATCH 095/166] core/storage/mockDB: remove unused `reverse_order` flag --- core/src/ledger/storage/mockdb.rs | 43 ++++++------------------------- 1 file changed, 8 insertions(+), 35 deletions(-) diff --git a/core/src/ledger/storage/mockdb.rs b/core/src/ledger/storage/mockdb.rs index ac96e12cf5..eb8ae04543 100644 --- a/core/src/ledger/storage/mockdb.rs +++ b/core/src/ledger/storage/mockdb.rs @@ -446,28 +446,14 @@ impl<'iter> DBIter<'iter> for MockDB { let db_prefix = "subspace/".to_owned(); let prefix = format!("{}{}", db_prefix, prefix); let iter = self.0.borrow().clone().into_iter(); - MockPrefixIterator::new( - MockIterator { - prefix, - iter, - reverse_order: false, - }, - db_prefix, - ) + MockPrefixIterator::new(MockIterator { prefix, iter }, db_prefix) } fn iter_results(&'iter self) -> MockPrefixIterator { let db_prefix = "results/".to_owned(); let prefix = "results".to_owned(); let iter = self.0.borrow().clone().into_iter(); - MockPrefixIterator::new( - MockIterator { - prefix, - iter, - reverse_order: false, - }, - db_prefix, - ) + MockPrefixIterator::new(MockIterator { prefix, iter }, db_prefix) } } @@ -477,8 +463,6 @@ pub struct MockIterator { prefix: String, /// The concrete iterator pub iter: btree_map::IntoIter>, - /// Is the iterator in reverse order? - reverse_order: bool, } /// A prefix iterator for the [`MockDB`]. @@ -488,23 +472,12 @@ impl Iterator for MockIterator { type Item = Result; fn next(&mut self) -> Option { - if self.reverse_order { - for (key, val) in (&mut self.iter).rev() { - if key.starts_with(&self.prefix) { - return Some(Ok(( - Box::from(key.as_bytes()), - Box::from(val.as_slice()), - ))); - } - } - } else { - for (key, val) in &mut self.iter { - if key.starts_with(&self.prefix) { - return Some(Ok(( - Box::from(key.as_bytes()), - Box::from(val.as_slice()), - ))); - } + for (key, val) in &mut self.iter { + if key.starts_with(&self.prefix) { + return Some(Ok(( + Box::from(key.as_bytes()), + Box::from(val.as_slice()), + ))); } } None From 5f219bfa04af9336ba32f3bbc9ae381d01b28bbf Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Fri, 23 Dec 2022 16:34:34 +0100 Subject: [PATCH 096/166] Adds fee burning and checks --- .../lib/node/ledger/shell/finalize_block.rs | 80 ++++++++++++++++++- apps/src/lib/node/ledger/shell/mod.rs | 28 ++++++- .../lib/node/ledger/shell/process_proposal.rs | 2 +- 3 files changed, 104 insertions(+), 6 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/finalize_block.rs b/apps/src/lib/node/ledger/shell/finalize_block.rs index d762ee91d8..758be0a403 100644 --- a/apps/src/lib/node/ledger/shell/finalize_block.rs +++ b/apps/src/lib/node/ledger/shell/finalize_block.rs @@ -2,7 +2,10 @@ use namada::ledger::pos::types::into_tm_voting_power; use namada::ledger::protocol; +use namada::ledger::storage::write_log::StorageModification; +use namada::ledger::storage_api::StorageRead; use namada::types::storage::{BlockHash, BlockResults, Header}; +use namada::types::token::Amount; use super::governance::execute_governance_proposals; use super::*; @@ -128,9 +131,80 @@ where } let mut tx_event = match &tx_type { - TxType::Wrapper(_wrapper) => { - self.storage.tx_queue.push(_wrapper.clone()); - Event::new_tx_event(&tx_type, height.0) + TxType::Wrapper(wrapper) => { + let mut tx_event = Event::new_tx_event(&tx_type, height.0); + + // Charge fee + let fee_payer = + if wrapper.pk != address::masp_tx_key().ref_to() { + wrapper.fee_payer() + } else { + address::masp() + }; + + let balance_key = token::balance_key( + &self.storage.native_token, + &fee_payer, + ); + let balance: Amount = + match self.write_log.read(&balance_key).0 { + Some(wal_mod) => { + // Read from WAL + if let StorageModification::Write { value } = + wal_mod + { + Amount::try_from_slice(value).unwrap() + } else { + Amount::default() + } + } + None => { + // Read from storage + let balance = StorageRead::read( + &self.storage, + &balance_key, + ); + // Storage read must not fail, but there might + // be no value, in which + // case default (0) is returned + balance + .expect( + "Storage read in the protocol must \ + not fail", + ) + .unwrap_or_default() + } + }; + + let balance: u64 = balance.into(); + match balance.checked_sub(100) { + Some(v) => { + self.write_log + .write( + &balance_key, + Amount::from(v).try_to_vec().unwrap(), + ) + .unwrap(); + } + None => { + // Burn remaining funds + self.write_log + .write( + &balance_key, + Amount::from(0).try_to_vec().unwrap(), + ) + .unwrap(); + tx_event["log"] = + "Insufficient balance for fee".into(); + tx_event["code"] = ErrorCodes::InvalidTx.into(); + + response.events.push(tx_event); + continue; + } + } + + self.storage.tx_queue.push(wrapper.clone()); + tx_event } TxType::Decrypted(inner) => { // We remove the corresponding wrapper tx from the queue diff --git a/apps/src/lib/node/ledger/shell/mod.rs b/apps/src/lib/node/ledger/shell/mod.rs index 4c461568a9..5f17d35e1d 100644 --- a/apps/src/lib/node/ledger/shell/mod.rs +++ b/apps/src/lib/node/ledger/shell/mod.rs @@ -33,16 +33,17 @@ use namada::ledger::storage::{ }; use namada::ledger::{ibc, pos, protocol}; use namada::proto::{self, Tx}; +use namada::types::address; use namada::types::address::{masp, masp_tx_key, Address}; use namada::types::chain::ChainId; use namada::types::key::*; use namada::types::storage::{BlockHeight, Key, TxIndex}; use namada::types::time::{DateTimeUtc, TimeZone, Utc}; +use namada::types::token::{self, Amount}; use namada::types::transaction::{ hash_tx, process_tx, verify_decrypted_correctly, AffineCurve, DecryptedTx, EllipticCurve, PairingEngine, TxType, WrapperTx, }; -use namada::types::{address, token}; use namada::vm::wasm::{TxCache, VpCache}; use namada::vm::WasmCacheRwAccess; use num_derive::{FromPrimitive, ToPrimitive}; @@ -575,7 +576,30 @@ where ) -> response::CheckTx { let mut response = response::CheckTx::default(); match Tx::try_from(tx_bytes).map_err(Error::TxDecoding) { - Ok(_) => response.log = String::from("Mempool validation passed"), + Ok(tx) => { + // Check balance for fee + if let Ok(TxType::Wrapper(wrapper)) = process_tx(tx) { + let fee_payer = if wrapper.pk != masp_tx_key().ref_to() { + wrapper.fee_payer() + } else { + masp() + }; + // check that the fee payer has sufficient balance + let balance = self + .get_balance(&self.storage.native_token, &fee_payer); + + if Amount::from(100) > balance { + response.code = 1; + response.log = String::from( + "The address given does not have sufficient \ + balance to pay fee", + ); + return response; + } + } + + response.log = String::from("Mempool validation passed"); + } Err(msg) => { response.code = 1; response.log = msg.to_string(); diff --git a/apps/src/lib/node/ledger/shell/process_proposal.rs b/apps/src/lib/node/ledger/shell/process_proposal.rs index 67ca13101e..54ed5fc05b 100644 --- a/apps/src/lib/node/ledger/shell/process_proposal.rs +++ b/apps/src/lib/node/ledger/shell/process_proposal.rs @@ -162,7 +162,7 @@ where let balance = self.get_balance(&tx.fee.token, &fee_payer); - if tx.fee.amount <= balance { + if Amount::from(100) <= balance { TxResult { code: ErrorCodes::Ok.into(), info: "Process proposal accepted this \ From 0b511299339ae400761e3e1a2d29832e169c4f3a Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Fri, 23 Dec 2022 17:32:50 +0100 Subject: [PATCH 097/166] Fixes fee value in tx contruction --- apps/src/lib/client/signing.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/src/lib/client/signing.rs b/apps/src/lib/client/signing.rs index ed7ab484a9..fc67d6a329 100644 --- a/apps/src/lib/client/signing.rs +++ b/apps/src/lib/client/signing.rs @@ -6,6 +6,7 @@ use namada::proto::Tx; use namada::types::address::{Address, ImplicitAddress}; use namada::types::key::*; use namada::types::storage::Epoch; +use namada::types::token::Amount; use namada::types::transaction::{hash_tx, Fee, WrapperTx}; use super::rpc; @@ -174,7 +175,7 @@ pub async fn sign_wrapper( let tx = { WrapperTx::new( Fee { - amount: args.fee_amount, + amount: Amount::from(100), token: ctx.get(&args.fee_token), }, keypair, From b93463636b8d876d610e1d2722042d35bf026498 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Fri, 23 Dec 2022 17:44:55 +0100 Subject: [PATCH 098/166] Fixes process proposal fee token --- apps/src/lib/node/ledger/shell/process_proposal.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/process_proposal.rs b/apps/src/lib/node/ledger/shell/process_proposal.rs index 54ed5fc05b..ebe219d39a 100644 --- a/apps/src/lib/node/ledger/shell/process_proposal.rs +++ b/apps/src/lib/node/ledger/shell/process_proposal.rs @@ -159,8 +159,10 @@ where masp() }; // check that the fee payer has sufficient balance - let balance = - self.get_balance(&tx.fee.token, &fee_payer); + let balance = self.get_balance( + &self.storage.native_token, + &fee_payer, + ); if Amount::from(100) <= balance { TxResult { From 0081be6122a29cd8778f5952a45b747599ec8743 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Sat, 24 Dec 2022 00:21:14 +0100 Subject: [PATCH 099/166] Fixes unit tests --- .../lib/node/ledger/shell/finalize_block.rs | 29 ++++++++++++++++--- .../lib/node/ledger/shell/process_proposal.rs | 9 ++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/finalize_block.rs b/apps/src/lib/node/ledger/shell/finalize_block.rs index 758be0a403..b54f00199a 100644 --- a/apps/src/lib/node/ledger/shell/finalize_block.rs +++ b/apps/src/lib/node/ledger/shell/finalize_block.rs @@ -422,15 +422,26 @@ mod test_finalize_block { let keypair = gen_keypair(); let mut processed_txs = vec![]; let mut valid_wrappers = vec![]; + + // Add unshielded balance for fee paymenty + let balance_key = token::balance_key( + &shell.storage.native_token, + &Address::from(&keypair.ref_to()), + ); + shell + .storage + .write(&balance_key, Amount::from(1000).try_to_vec().unwrap()) + .unwrap(); + // create some wrapper txs - for i in 1..5 { + for i in 1u64..5 { let raw_tx = Tx::new( "wasm_code".as_bytes().to_owned(), Some(format!("transaction data: {}", i).as_bytes().to_owned()), ); let wrapper = WrapperTx::new( Fee { - amount: i.into(), + amount: 100.into(), token: shell.storage.native_token.clone(), }, &keypair, @@ -603,6 +614,16 @@ mod test_finalize_block { let mut processed_txs = vec![]; let mut valid_txs = vec![]; + // Add unshielded balance for fee paymenty + let balance_key = token::balance_key( + &shell.storage.native_token, + &Address::from(&keypair.ref_to()), + ); + shell + .storage + .write(&balance_key, Amount::from(1000).try_to_vec().unwrap()) + .unwrap(); + // create two decrypted txs let mut wasm_path = top_level_directory(); wasm_path.push("wasm_for_tests/tx_no_op.wasm"); @@ -619,7 +640,7 @@ mod test_finalize_block { ); let wrapper_tx = WrapperTx::new( Fee { - amount: 0.into(), + amount: 100.into(), token: shell.storage.native_token.clone(), }, &keypair, @@ -650,7 +671,7 @@ mod test_finalize_block { ); let wrapper_tx = WrapperTx::new( Fee { - amount: 0.into(), + amount: 100.into(), token: shell.storage.native_token.clone(), }, &keypair, diff --git a/apps/src/lib/node/ledger/shell/process_proposal.rs b/apps/src/lib/node/ledger/shell/process_proposal.rs index ebe219d39a..0004db48e5 100644 --- a/apps/src/lib/node/ledger/shell/process_proposal.rs +++ b/apps/src/lib/node/ledger/shell/process_proposal.rs @@ -400,6 +400,15 @@ mod test_process_proposal { ..Default::default() }); let keypair = crate::wallet::defaults::daewon_keypair(); + // reduce address balance to match the 100 token fee + let balance_key = token::balance_key( + &shell.storage.native_token, + &Address::from(&keypair.ref_to()), + ); + shell + .storage + .write(&balance_key, Amount::from(99).try_to_vec().unwrap()) + .unwrap(); let tx = Tx::new( "wasm_code".as_bytes().to_owned(), From 83bed0b85471fc7b1bdfe1f196b42d519cd78d6c Mon Sep 17 00:00:00 2001 From: brentstone Date: Mon, 26 Dec 2022 16:32:00 -0500 Subject: [PATCH 100/166] fix arb rate: prevent same rate and ensure proper bounds --- .../src/tx_change_validator_commission.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/wasm/wasm_source/src/tx_change_validator_commission.rs b/wasm/wasm_source/src/tx_change_validator_commission.rs index f32d83f34e..89feb652ea 100644 --- a/wasm/wasm_source/src/tx_change_validator_commission.rs +++ b/wasm/wasm_source/src/tx_change_validator_commission.rs @@ -18,6 +18,8 @@ fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { #[cfg(test)] mod tests { + use std::cmp; + use namada::ledger::pos::{PosParams, PosVP}; use namada::proto::Tx; use namada::types::storage::Epoch; @@ -160,13 +162,24 @@ mod tests { .prop_map(|num| Decimal::from(num) / Decimal::from(100_000_u64)) } + fn arb_new_rate( + min: Decimal, + max: Decimal, + rate_pre: Decimal, + ) -> impl Strategy { + arb_rate(min, max).prop_filter( + "New rate must not be equal to the previous epoch's rate", + move |v| v != &rate_pre, + ) + } + fn arb_commission_change( rate_pre: Decimal, max_change: Decimal, ) -> impl Strategy { - let min = rate_pre - max_change; - let max = rate_pre + max_change; - (arb_established_address(), arb_rate(min, max)).prop_map( + let min = cmp::max(rate_pre - max_change, Decimal::ZERO); + let max = cmp::min(rate_pre + max_change, Decimal::ONE); + (arb_established_address(), arb_new_rate(min, max, rate_pre)).prop_map( |(validator, new_rate)| transaction::pos::CommissionChange { validator: Address::Established(validator), new_rate, From 1df346c88fd344e113882ad882412b4cb218f765 Mon Sep 17 00:00:00 2001 From: brentstone Date: Mon, 26 Dec 2022 16:32:08 -0500 Subject: [PATCH 101/166] remove dbg statements --- wasm/wasm_source/src/tx_change_validator_commission.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/wasm/wasm_source/src/tx_change_validator_commission.rs b/wasm/wasm_source/src/tx_change_validator_commission.rs index 89feb652ea..3d30f25908 100644 --- a/wasm/wasm_source/src/tx_change_validator_commission.rs +++ b/wasm/wasm_source/src/tx_change_validator_commission.rs @@ -104,9 +104,6 @@ mod tests { .read_validator_commission_rate(&commission_change.validator)? .unwrap(); - dbg!(&commission_rates_pre); - dbg!(&commission_rates_post); - // Before pipeline, the commission rates should not change for epoch in 0..pos_params.pipeline_len { assert_eq!( From 159001ea93f34f2d9681ede7c253f90068fe17bf Mon Sep 17 00:00:00 2001 From: brentstone Date: Mon, 26 Dec 2022 16:34:05 -0500 Subject: [PATCH 102/166] remove `ChangeIsZero` error --- proof_of_stake/src/lib.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/proof_of_stake/src/lib.rs b/proof_of_stake/src/lib.rs index 64c7ffdff8..661533cb16 100644 --- a/proof_of_stake/src/lib.rs +++ b/proof_of_stake/src/lib.rs @@ -563,15 +563,14 @@ pub trait PosActions: PosReadOnly { } }; let params = self.read_pos_params()?; - let rate_at_pipeline = *commission_rates .get_at_offset(current_epoch, DynEpochOffset::PipelineLen, ¶ms) .expect("Could not find a rate in given epoch"); + + // Return early with no further changes if there is no rate change + // instead of returning an error if new_rate == rate_at_pipeline { - return Err(CommissionRateChangeError::ChangeIsZero( - validator.clone(), - ) - .into()); + return Ok(()); } let rate_before_pipeline = *commission_rates @@ -1018,8 +1017,6 @@ pub enum CommissionRateChangeError { NegativeRate(Decimal, Address), #[error("Rate change of {0} is too large for validator {1}")] RateChangeTooLarge(Decimal, Address), - #[error("The rate change is 0 for validator {0}")] - ChangeIsZero(Address), #[error( "There is no maximum rate change written in storage for validator {0}" )] From 8441d33e174a0f951e6154f615a92842382451d2 Mon Sep 17 00:00:00 2001 From: brentstone Date: Mon, 26 Dec 2022 16:45:56 -0500 Subject: [PATCH 103/166] changelog: add #965 --- .../bug-fixes/965-fix-validator-commission-change-test.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md diff --git a/.changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md b/.changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md new file mode 100644 index 0000000000..274b48c5d1 --- /dev/null +++ b/.changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md @@ -0,0 +1,3 @@ +- Fix the commission rate change wasm test, which failed because an arbitrary + value for a new rate was allowed that could be equal to the previous rate. + ([#965](https://github.com/anoma/namada/pull/965)) \ No newline at end of file From db0cac3151c7ffa585eef5733176746e6bc34d5d Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Tue, 27 Dec 2022 17:08:57 +0100 Subject: [PATCH 104/166] changelog: add #962 --- .changelog/unreleased/improvements/962-basic-fee.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/962-basic-fee.md diff --git a/.changelog/unreleased/improvements/962-basic-fee.md b/.changelog/unreleased/improvements/962-basic-fee.md new file mode 100644 index 0000000000..d1fa27df87 --- /dev/null +++ b/.changelog/unreleased/improvements/962-basic-fee.md @@ -0,0 +1,2 @@ +- Added a basic fee implementation for testnet. + ([#962](https://github.com/anoma/namada/pull/962)) \ No newline at end of file From c20b80f8bd96e60954f41d0ae954b21b3714d6d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Tue, 27 Dec 2022 15:41:01 +0100 Subject: [PATCH 105/166] core/storage_api: use GATs to hide lifetime in StorageRead trait --- core/src/ledger/storage/mod.rs | 17 ++-- .../storage_api/collections/lazy_map.rs | 18 ++-- .../storage_api/collections/lazy_vec.rs | 14 ++-- core/src/ledger/storage_api/key.rs | 2 +- core/src/ledger/storage_api/mod.rs | 28 +++---- core/src/ledger/tx_env.rs | 2 +- core/src/ledger/vp_env.rs | 51 ++++-------- shared/src/ledger/ibc/vp/channel.rs | 10 +-- shared/src/ledger/ibc/vp/client.rs | 19 ++--- .../src/ledger/native_vp/governance/utils.rs | 2 +- shared/src/ledger/native_vp/mod.rs | 83 +++++++------------ shared/src/ledger/pos/vp.rs | 4 +- tx_prelude/src/lib.rs | 18 ++-- vp_prelude/src/lib.rs | 52 ++++++------ 14 files changed, 142 insertions(+), 178 deletions(-) diff --git a/core/src/ledger/storage/mod.rs b/core/src/ledger/storage/mod.rs index 4c34a6c2c4..256c1f2a8b 100644 --- a/core/src/ledger/storage/mod.rs +++ b/core/src/ledger/storage/mod.rs @@ -992,12 +992,15 @@ where } } -impl<'iter, D, H> StorageRead<'iter> for Storage +impl StorageRead for Storage where D: DB + for<'iter_> DBIter<'iter_>, H: StorageHasher, { - type PrefixIter = >::PrefixIter; + type PrefixIter<'iter> = >::PrefixIter +where + Self: 'iter + ; fn read_bytes( &self, @@ -1013,16 +1016,16 @@ where self.block.tree.has_key(key).into_storage_result() } - fn iter_prefix( + fn iter_prefix<'iter>( &'iter self, prefix: &crate::types::storage::Key, - ) -> std::result::Result { + ) -> std::result::Result, storage_api::Error> { Ok(self.db.iter_prefix(prefix)) } - fn iter_next( - &self, - iter: &mut Self::PrefixIter, + fn iter_next<'iter>( + &'iter self, + iter: &mut Self::PrefixIter<'iter>, ) -> std::result::Result)>, storage_api::Error> { Ok(iter.next().map(|(key, val, _gas)| (key, val))) diff --git a/core/src/ledger/storage_api/collections/lazy_map.rs b/core/src/ledger/storage_api/collections/lazy_map.rs index 34a0f7d891..81ddd7f42d 100644 --- a/core/src/ledger/storage_api/collections/lazy_map.rs +++ b/core/src/ledger/storage_api/collections/lazy_map.rs @@ -323,7 +323,7 @@ where /// Returns whether the set contains a value. pub fn contains(&self, storage: &S, key: &K) -> Result where - S: for<'iter> StorageRead<'iter>, + S: StorageRead, { storage.has_key(&self.get_data_key(key)) } @@ -363,7 +363,7 @@ where /// map. pub fn iter<'iter>( &'iter self, - storage: &'iter impl StorageRead<'iter>, + storage: &'iter impl StorageRead, ) -> Result< impl Iterator< Item = Result<( @@ -406,7 +406,7 @@ where val: V, ) -> Result> where - S: StorageWrite + for<'iter> StorageRead<'iter>, + S: StorageWrite + StorageRead, { let previous = self.get(storage, &key)?; @@ -420,7 +420,7 @@ where /// was previously in the map. pub fn remove(&self, storage: &mut S, key: &K) -> Result> where - S: StorageWrite + for<'iter> StorageRead<'iter>, + S: StorageWrite + StorageRead, { let value = self.get(storage, key)?; @@ -433,7 +433,7 @@ where /// Returns the value corresponding to the key, if any. pub fn get(&self, storage: &S, key: &K) -> Result> where - S: for<'iter> StorageRead<'iter>, + S: StorageRead, { let data_key = self.get_data_key(key); Self::read_key_val(storage, &data_key) @@ -442,7 +442,7 @@ where /// Returns whether the map contains no elements. pub fn is_empty(&self, storage: &S) -> Result where - S: for<'iter> StorageRead<'iter>, + S: StorageRead, { let mut iter = storage_api::iter_prefix_bytes(storage, &self.get_data_prefix())?; @@ -457,7 +457,7 @@ where #[allow(clippy::len_without_is_empty)] pub fn len(&self, storage: &S) -> Result where - S: for<'iter> StorageRead<'iter>, + S: StorageRead, { let iter = storage_api::iter_prefix_bytes(storage, &self.get_data_prefix())?; @@ -473,7 +473,7 @@ where /// map. pub fn iter<'iter>( &self, - storage: &'iter impl StorageRead<'iter>, + storage: &'iter impl StorageRead, ) -> Result> + 'iter> { let iter = storage_api::iter_prefix(storage, &self.get_data_prefix())?; Ok(iter.map(|key_val_res| { @@ -493,7 +493,7 @@ where storage_key: &storage::Key, ) -> Result> where - S: for<'iter> StorageRead<'iter>, + S: StorageRead, { let res = storage.read(storage_key)?; Ok(res) diff --git a/core/src/ledger/storage_api/collections/lazy_vec.rs b/core/src/ledger/storage_api/collections/lazy_vec.rs index 59eaa225e5..0e0a5ab03b 100644 --- a/core/src/ledger/storage_api/collections/lazy_vec.rs +++ b/core/src/ledger/storage_api/collections/lazy_vec.rs @@ -358,7 +358,7 @@ impl LazyVec { #[allow(clippy::len_without_is_empty)] pub fn len(&self, storage: &S) -> Result where - S: for<'iter> StorageRead<'iter>, + S: StorageRead, { let len = storage.read(&self.get_len_key())?; Ok(len.unwrap_or_default()) @@ -367,7 +367,7 @@ impl LazyVec { /// Returns `true` if the vector contains no elements. pub fn is_empty(&self, storage: &S) -> Result where - S: for<'iter> StorageRead<'iter>, + S: StorageRead, { Ok(self.len(storage)? == 0) } @@ -396,7 +396,7 @@ where /// Appends an element to the back of a collection. pub fn push(&self, storage: &mut S, val: T) -> Result<()> where - S: StorageWrite + for<'iter> StorageRead<'iter>, + S: StorageWrite + StorageRead, { let len = self.len(storage)?; let data_key = self.get_data_key(len); @@ -410,7 +410,7 @@ where /// Note that an empty vector is completely removed from storage. pub fn pop(&self, storage: &mut S) -> Result> where - S: StorageWrite + for<'iter> StorageRead<'iter>, + S: StorageWrite + StorageRead, { let len = self.len(storage)?; if len == 0 { @@ -435,7 +435,7 @@ where /// will fail with `UpdateError::InvalidIndex`. pub fn update(&self, storage: &mut S, index: Index, val: T) -> Result<()> where - S: StorageWrite + for<'iter> StorageRead<'iter>, + S: StorageWrite + StorageRead, { let len = self.len(storage)?; if index >= len { @@ -449,7 +449,7 @@ where /// Read an element at the index or `Ok(None)` if out of bounds. pub fn get(&self, storage: &S, index: Index) -> Result> where - S: for<'iter> StorageRead<'iter>, + S: StorageRead, { storage.read(&self.get_data_key(index)) } @@ -463,7 +463,7 @@ where /// set. pub fn iter<'iter>( &self, - storage: &'iter impl StorageRead<'iter>, + storage: &'iter impl StorageRead, ) -> Result> + 'iter> { let iter = storage_api::iter_prefix(storage, &self.get_data_prefix())?; Ok(iter.map(|key_val_res| { diff --git a/core/src/ledger/storage_api/key.rs b/core/src/ledger/storage_api/key.rs index 06b3c76bad..6e3eba64aa 100644 --- a/core/src/ledger/storage_api/key.rs +++ b/core/src/ledger/storage_api/key.rs @@ -8,7 +8,7 @@ use crate::types::key::*; /// not found. pub fn get(storage: &S, owner: &Address) -> Result> where - S: for<'iter> StorageRead<'iter>, + S: StorageRead, { let key = pk_key(owner); storage.read(&key) diff --git a/core/src/ledger/storage_api/mod.rs b/core/src/ledger/storage_api/mod.rs index dde9eb5ade..c929aec03b 100644 --- a/core/src/ledger/storage_api/mod.rs +++ b/core/src/ledger/storage_api/mod.rs @@ -20,21 +20,17 @@ use crate::types::storage::{self, BlockHash, BlockHeight, Epoch, TxIndex}; /// /// ```rust,ignore /// where -/// S: for<'iter> StorageRead<'iter> +/// S: StorageRead /// ``` /// /// If you want to know why this is needed, see the to-do task below. The /// syntax for this relies on higher-rank lifetimes, see e.g. /// . -/// -/// TODO: once GATs are stabilized, we should be able to remove the `'iter` -/// lifetime param that is currently the only way to make the prefix iterator -/// typecheck in the `>::PrefixIter` associated type used in -/// `impl StorageRead for Storage` (shared/src/ledger/storage/mod.rs). -/// See -pub trait StorageRead<'iter> { +pub trait StorageRead { /// Storage read prefix iterator - type PrefixIter; + type PrefixIter<'iter> + where + Self: 'iter; /// Storage read Borsh encoded value. It will try to read from the storage /// and decode it if found. @@ -63,15 +59,15 @@ pub trait StorageRead<'iter> { /// /// For a more user-friendly iterator API, use [`fn@iter_prefix`] or /// [`fn@iter_prefix_bytes`] instead. - fn iter_prefix( + fn iter_prefix<'iter>( &'iter self, prefix: &storage::Key, - ) -> Result; + ) -> Result>; /// Storage prefix iterator. It will try to read from the storage. - fn iter_next( - &self, - iter: &mut Self::PrefixIter, + fn iter_next<'iter>( + &'iter self, + iter: &mut Self::PrefixIter<'iter>, ) -> Result)>>; /// Getting the chain ID. @@ -121,7 +117,7 @@ pub trait StorageWrite { /// Iterate items matching the given prefix, ordered by the storage keys. pub fn iter_prefix_bytes<'a>( - storage: &'a impl StorageRead<'a>, + storage: &'a impl StorageRead, prefix: &crate::types::storage::Key, ) -> Result)>> + 'a> { let iter = storage.iter_prefix(prefix)?; @@ -150,7 +146,7 @@ pub fn iter_prefix_bytes<'a>( /// Iterate Borsh encoded items matching the given prefix, ordered by the /// storage keys. pub fn iter_prefix<'a, T>( - storage: &'a impl StorageRead<'a>, + storage: &'a impl StorageRead, prefix: &crate::types::storage::Key, ) -> Result> + 'a> where diff --git a/core/src/ledger/tx_env.rs b/core/src/ledger/tx_env.rs index 7672ac6505..6ca47bb9d9 100644 --- a/core/src/ledger/tx_env.rs +++ b/core/src/ledger/tx_env.rs @@ -10,7 +10,7 @@ use crate::types::storage; use crate::types::time::Rfc3339String; /// Transaction host functions -pub trait TxEnv<'iter>: StorageRead<'iter> + StorageWrite { +pub trait TxEnv: StorageRead + StorageWrite { /// Write a temporary value to be encoded with Borsh at the given key to /// storage. fn write_temp( diff --git a/core/src/ledger/vp_env.rs b/core/src/ledger/vp_env.rs index 4b7edc02ce..43bc744635 100644 --- a/core/src/ledger/vp_env.rs +++ b/core/src/ledger/vp_env.rs @@ -10,15 +10,20 @@ use crate::types::key::common; use crate::types::storage::{BlockHash, BlockHeight, Epoch, Key, TxIndex}; /// Validity predicate's environment is available for native VPs and WASM VPs -pub trait VpEnv<'view> { +pub trait VpEnv<'view> +where + Self: 'view, +{ /// Storage read prefix iterator - type PrefixIter; + type PrefixIter<'iter> + where + Self: 'iter; /// Type to read storage state before the transaction execution - type Pre: StorageRead<'view, PrefixIter = Self::PrefixIter>; + type Pre: StorageRead = Self::PrefixIter<'view>>; /// Type to read storage state after the transaction execution - type Post: StorageRead<'view, PrefixIter = Self::PrefixIter>; + type Post: StorageRead = Self::PrefixIter<'view>>; /// Read storage state before the transaction execution fn pre(&'view self) -> Self::Pre; @@ -42,33 +47,32 @@ pub trait VpEnv<'view> { ) -> Result>, storage_api::Error>; /// Getting the chain ID. - fn get_chain_id(&'view self) -> Result; + fn get_chain_id(&self) -> Result; /// Getting the block height. The height is that of the block to which the /// current transaction is being applied. - fn get_block_height(&'view self) - -> Result; + fn get_block_height(&self) -> Result; /// Getting the block hash. The height is that of the block to which the /// current transaction is being applied. - fn get_block_hash(&'view self) -> Result; + fn get_block_hash(&self) -> Result; /// Getting the block epoch. The epoch is that of the block to which the /// current transaction is being applied. - fn get_block_epoch(&'view self) -> Result; + fn get_block_epoch(&self) -> Result; /// Get the shielded transaction index. - fn get_tx_index(&'view self) -> Result; + fn get_tx_index(&self) -> Result; /// Get the address of the native token. - fn get_native_token(&'view self) -> Result; + fn get_native_token(&self) -> Result; /// Storage prefix iterator, ordered by storage keys. It will try to get an /// iterator from the storage. - fn iter_prefix( - &'view self, + fn iter_prefix<'iter>( + &'iter self, prefix: &Key, - ) -> Result; + ) -> Result, storage_api::Error>; /// Evaluate a validity predicate with given data. The address, changed /// storage keys and verifiers will have the same values as the input to @@ -151,23 +155,4 @@ pub trait VpEnv<'view> { ) -> Result { self.post().has_key(key) } - - /// Storage prefix iterator for prior state (before tx execution). It will - /// try to read from the storage. - fn iter_pre_next( - &'view self, - iter: &mut Self::PrefixIter, - ) -> Result)>, storage_api::Error> { - self.pre().iter_next(iter) - } - - /// Storage prefix iterator next for posterior state (after tx execution). - /// It will try to read from the write log first and if no entry found - /// then from the storage. - fn iter_post_next( - &'view self, - iter: &mut Self::PrefixIter, - ) -> Result)>, storage_api::Error> { - self.post().iter_next(iter) - } } diff --git a/shared/src/ledger/ibc/vp/channel.rs b/shared/src/ledger/ibc/vp/channel.rs index 05cbf7ad15..e85a221212 100644 --- a/shared/src/ledger/ibc/vp/channel.rs +++ b/shared/src/ledger/ibc/vp/channel.rs @@ -19,6 +19,7 @@ use namada_core::ledger::ibc::storage::{ }; use namada_core::ledger::parameters; use namada_core::ledger::storage::{self as ledger_storage, StorageHasher}; +use namada_core::ledger::storage_api::StorageRead; use namada_core::types::storage::Key; use sha2::Digest; use thiserror::Error; @@ -734,14 +735,13 @@ where let mut channels = vec![]; let prefix = Key::parse("channelEnds/ports") .expect("Creating a key for the prefix shouldn't fail"); - let mut iter = self - .ctx + let post = self.ctx.post(); + let mut iter = post .iter_prefix(&prefix) .map_err(|_| Ics04Error::implementation_specific())?; loop { - let next = self - .ctx - .iter_post_next(&mut iter) + let next = post + .iter_next(&mut iter) .map_err(|_| Ics04Error::implementation_specific())?; if let Some((key, value)) = next { let channel = ChannelEnd::decode_vec(&value) diff --git a/shared/src/ledger/ibc/vp/client.rs b/shared/src/ledger/ibc/vp/client.rs index 40807673f1..9bc5d20efb 100644 --- a/shared/src/ledger/ibc/vp/client.rs +++ b/shared/src/ledger/ibc/vp/client.rs @@ -6,6 +6,7 @@ use namada_core::ledger::ibc::actions::{ make_create_client_event, make_update_client_event, make_upgrade_client_event, }; +use namada_core::ledger::storage_api::StorageRead; use thiserror::Error; use super::super::storage::{ @@ -478,14 +479,13 @@ where height: Height, ) -> Ics02Result> { let prefix = consensus_state_prefix(client_id); - let mut iter = self - .ctx + let pre = self.ctx.pre(); + let mut iter = pre .iter_prefix(&prefix) .map_err(|_| Ics02Error::implementation_specific())?; let mut lowest_height_value = None; - while let Some((key, value)) = self - .ctx - .iter_pre_next(&mut iter) + while let Some((key, value)) = pre + .iter_next(&mut iter) .map_err(|_| Ics02Error::implementation_specific())? { let key = Key::parse(key) @@ -519,14 +519,13 @@ where height: Height, ) -> Ics02Result> { let prefix = consensus_state_prefix(client_id); - let mut iter = self - .ctx + let pre = self.ctx.pre(); + let mut iter = pre .iter_prefix(&prefix) .map_err(|_| Ics02Error::implementation_specific())?; let mut highest_height_value = None; - while let Some((key, value)) = self - .ctx - .iter_pre_next(&mut iter) + while let Some((key, value)) = pre + .iter_next(&mut iter) .map_err(|_| Ics02Error::implementation_specific())? { let key = Key::parse(key) diff --git a/shared/src/ledger/native_vp/governance/utils.rs b/shared/src/ledger/native_vp/governance/utils.rs index eb96948c49..4fd0a68217 100644 --- a/shared/src/ledger/native_vp/governance/utils.rs +++ b/shared/src/ledger/native_vp/governance/utils.rs @@ -220,7 +220,7 @@ pub fn is_proposal_accepted( tx_data: &[u8], ) -> storage_api::Result where - S: for<'iter> storage_api::StorageRead<'iter>, + S: storage_api::StorageRead, { let proposal_id = u64::try_from_slice(tx_data).ok(); match proposal_id { diff --git a/shared/src/ledger/native_vp/mod.rs b/shared/src/ledger/native_vp/mod.rs index d8f1dbe6e5..0907c1cc38 100644 --- a/shared/src/ledger/native_vp/mod.rs +++ b/shared/src/ledger/native_vp/mod.rs @@ -169,14 +169,14 @@ where } } -impl<'view, 'a, DB, H, CA> StorageRead<'view> +impl<'view, 'a: 'view, DB, H, CA> StorageRead for CtxPreStorageRead<'view, 'a, DB, H, CA> where DB: 'static + storage::DB + for<'iter> storage::DBIter<'iter>, H: 'static + StorageHasher, CA: 'static + WasmCacheAccess, { - type PrefixIter = >::PrefixIter; + type PrefixIter<'iter> = >::PrefixIter where Self: 'iter; fn read_bytes( &self, @@ -203,9 +203,9 @@ where .into_storage_result() } - fn iter_next( - &self, - iter: &mut Self::PrefixIter, + fn iter_next<'iter>( + &'iter self, + iter: &mut Self::PrefixIter<'iter>, ) -> Result)>, storage_api::Error> { vp_host_fns::iter_pre_next::( &mut self.ctx.gas_meter.borrow_mut(), @@ -217,10 +217,10 @@ where // ---- Methods below are implemented in `self.ctx`, because they are // the same in `pre/post` ---- - fn iter_prefix( - &self, + fn iter_prefix<'iter>( + &'iter self, prefix: &crate::types::storage::Key, - ) -> Result { + ) -> Result, storage_api::Error> { self.ctx.iter_prefix(prefix) } @@ -249,14 +249,14 @@ where } } -impl<'view, 'a, DB, H, CA> StorageRead<'view> +impl<'view, 'a: 'view, DB, H, CA> StorageRead for CtxPostStorageRead<'view, 'a, DB, H, CA> where DB: 'static + storage::DB + for<'iter> storage::DBIter<'iter>, H: 'static + StorageHasher, CA: 'static + WasmCacheAccess, { - type PrefixIter = >::PrefixIter; + type PrefixIter<'iter> = >::PrefixIter where Self:'iter; fn read_bytes( &self, @@ -284,9 +284,9 @@ where .into_storage_result() } - fn iter_next( - &self, - iter: &mut Self::PrefixIter, + fn iter_next<'iter>( + &'iter self, + iter: &mut Self::PrefixIter<'iter>, ) -> Result)>, storage_api::Error> { vp_host_fns::iter_post_next::( &mut self.ctx.gas_meter.borrow_mut(), @@ -299,10 +299,10 @@ where // ---- Methods below are implemented in `self.ctx`, because they are // the same in `pre/post` ---- - fn iter_prefix( - &self, + fn iter_prefix<'iter>( + &'iter self, prefix: &crate::types::storage::Key, - ) -> Result { + ) -> Result, storage_api::Error> { self.ctx.iter_prefix(prefix) } @@ -339,7 +339,7 @@ where { type Post = CtxPostStorageRead<'view, 'a, DB, H, CA>; type Pre = CtxPreStorageRead<'view, 'a, DB, H, CA>; - type PrefixIter = >::PrefixIter; + type PrefixIter<'iter> = >::PrefixIter where Self: 'iter; fn pre(&'view self) -> Self::Pre { CtxPreStorageRead { ctx: self } @@ -374,7 +374,7 @@ where .into_storage_result() } - fn get_chain_id(&'view self) -> Result { + fn get_chain_id(&self) -> Result { vp_host_fns::get_chain_id( &mut self.gas_meter.borrow_mut(), self.storage, @@ -382,9 +382,7 @@ where .into_storage_result() } - fn get_block_height( - &'view self, - ) -> Result { + fn get_block_height(&self) -> Result { vp_host_fns::get_block_height( &mut self.gas_meter.borrow_mut(), self.storage, @@ -392,7 +390,7 @@ where .into_storage_result() } - fn get_block_hash(&'view self) -> Result { + fn get_block_hash(&self) -> Result { vp_host_fns::get_block_hash( &mut self.gas_meter.borrow_mut(), self.storage, @@ -400,7 +398,7 @@ where .into_storage_result() } - fn get_block_epoch(&'view self) -> Result { + fn get_block_epoch(&self) -> Result { vp_host_fns::get_block_epoch( &mut self.gas_meter.borrow_mut(), self.storage, @@ -408,7 +406,7 @@ where .into_storage_result() } - fn get_tx_index(&'view self) -> Result { + fn get_tx_index(&self) -> Result { vp_host_fns::get_tx_index( &mut self.gas_meter.borrow_mut(), self.tx_index, @@ -416,7 +414,7 @@ where .into_storage_result() } - fn get_native_token(&'view self) -> Result { + fn get_native_token(&self) -> Result { vp_host_fns::get_native_token( &mut self.gas_meter.borrow_mut(), self.storage, @@ -424,10 +422,10 @@ where .into_storage_result() } - fn iter_prefix( - &'view self, + fn iter_prefix<'iter>( + &'iter self, prefix: &Key, - ) -> Result { + ) -> Result, storage_api::Error> { vp_host_fns::iter_prefix( &mut self.gas_meter.borrow_mut(), self.storage, @@ -513,55 +511,38 @@ where } fn read_pre( - &'view self, + &self, key: &Key, ) -> Result, storage_api::Error> { self.pre().read(key).map_err(Into::into) } fn read_bytes_pre( - &'view self, + &self, key: &Key, ) -> Result>, storage_api::Error> { self.pre().read_bytes(key).map_err(Into::into) } fn read_post( - &'view self, + &self, key: &Key, ) -> Result, storage_api::Error> { self.post().read(key).map_err(Into::into) } fn read_bytes_post( - &'view self, + &self, key: &Key, ) -> Result>, storage_api::Error> { self.post().read_bytes(key).map_err(Into::into) } - fn has_key_pre(&'view self, key: &Key) -> Result { + fn has_key_pre(&self, key: &Key) -> Result { self.pre().has_key(key).map_err(Into::into) } - fn has_key_post( - &'view self, - key: &Key, - ) -> Result { + fn has_key_post(&self, key: &Key) -> Result { self.post().has_key(key).map_err(Into::into) } - - fn iter_pre_next( - &'view self, - iter: &mut Self::PrefixIter, - ) -> Result)>, storage_api::Error> { - self.pre().iter_next(iter).map_err(Into::into) - } - - fn iter_post_next( - &'view self, - iter: &mut Self::PrefixIter, - ) -> Result)>, storage_api::Error> { - self.post().iter_next(iter).map_err(Into::into) - } } diff --git a/shared/src/ledger/pos/vp.rs b/shared/src/ledger/pos/vp.rs index e1b13648d0..2a2e87bdba 100644 --- a/shared/src/ledger/pos/vp.rs +++ b/shared/src/ledger/pos/vp.rs @@ -305,7 +305,7 @@ where } impl_pos_read_only! { - impl<'f, 'a, DB, H, CA> PosReadOnly for CtxPreStorageRead<'f, 'a, DB, H, CA> + impl<'view, 'a: 'view, DB, H, CA> PosReadOnly for CtxPreStorageRead<'view, 'a, DB, H, CA> where DB: ledger_storage::DB + for<'iter> ledger_storage::DBIter<'iter> +'static, H: StorageHasher +'static, @@ -313,7 +313,7 @@ impl_pos_read_only! { } impl_pos_read_only! { - impl<'f, 'a, DB, H, CA> PosReadOnly for CtxPostStorageRead<'f, 'a, DB, H, CA> + impl<'view, 'a: 'view, DB, H, CA> PosReadOnly for CtxPostStorageRead<'view, 'a, DB, H, CA> where DB: ledger_storage::DB + for<'iter> ledger_storage::DBIter<'iter> +'static, H: StorageHasher +'static, diff --git a/tx_prelude/src/lib.rs b/tx_prelude/src/lib.rs index 73a90b6d03..9d66dcb73e 100644 --- a/tx_prelude/src/lib.rs +++ b/tx_prelude/src/lib.rs @@ -111,8 +111,8 @@ pub type TxResult = EnvResult<()>; #[derive(Debug)] pub struct KeyValIterator(pub u64, pub PhantomData); -impl StorageRead<'_> for Ctx { - type PrefixIter = KeyValIterator<(String, Vec)>; +impl StorageRead for Ctx { + type PrefixIter<'iter> = KeyValIterator<(String, Vec)>; fn read_bytes(&self, key: &storage::Key) -> Result>, Error> { let key = key.to_string(); @@ -178,10 +178,10 @@ impl StorageRead<'_> for Ctx { Ok(Address::decode(address_str).expect("Cannot decode native address")) } - fn iter_prefix( - &self, + fn iter_prefix<'iter>( + &'iter self, prefix: &storage::Key, - ) -> Result { + ) -> Result, Error> { let prefix = prefix.to_string(); let iter_id = unsafe { namada_tx_iter_prefix(prefix.as_ptr() as _, prefix.len() as _) @@ -189,9 +189,9 @@ impl StorageRead<'_> for Ctx { Ok(KeyValIterator(iter_id, PhantomData)) } - fn iter_next( - &self, - iter: &mut Self::PrefixIter, + fn iter_next<'iter>( + &'iter self, + iter: &mut Self::PrefixIter<'iter>, ) -> Result)>, Error> { let read_result = unsafe { namada_tx_iter_next(iter.0) }; Ok(read_key_val_bytes_from_buffer( @@ -231,7 +231,7 @@ impl StorageWrite for Ctx { } } -impl TxEnv<'_> for Ctx { +impl TxEnv for Ctx { fn get_block_time(&self) -> Result { let read_result = unsafe { namada_tx_get_block_time() }; let time_value = read_from_buffer(read_result, namada_tx_result_buffer) diff --git a/vp_prelude/src/lib.rs b/vp_prelude/src/lib.rs index f4911516d5..58ee37e756 100644 --- a/vp_prelude/src/lib.rs +++ b/vp_prelude/src/lib.rs @@ -190,7 +190,7 @@ pub struct KeyValIterator(pub u64, pub PhantomData); impl<'view> VpEnv<'view> for Ctx { type Post = CtxPostStorageRead<'view>; type Pre = CtxPreStorageRead<'view>; - type PrefixIter = KeyValIterator<(String, Vec)>; + type PrefixIter<'iter> = KeyValIterator<(String, Vec)>; fn pre(&'view self) -> Self::Pre { CtxPreStorageRead { _ctx: self } @@ -221,39 +221,39 @@ impl<'view> VpEnv<'view> for Ctx { Ok(read_from_buffer(read_result, namada_vp_result_buffer)) } - fn get_chain_id(&'view self) -> Result { + fn get_chain_id(&self) -> Result { // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl get_chain_id() } - fn get_block_height(&'view self) -> Result { + fn get_block_height(&self) -> Result { // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl get_block_height() } - fn get_block_hash(&'view self) -> Result { + fn get_block_hash(&self) -> Result { // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl get_block_hash() } - fn get_block_epoch(&'view self) -> Result { + fn get_block_epoch(&self) -> Result { // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl get_block_epoch() } - fn get_tx_index(&'view self) -> Result { + fn get_tx_index(&self) -> Result { get_tx_index() } - fn get_native_token(&'view self) -> Result { + fn get_native_token(&self) -> Result { // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl get_native_token() } - fn iter_prefix( - &self, + fn iter_prefix<'iter>( + &'iter self, prefix: &storage::Key, - ) -> Result { + ) -> Result, Error> { // Both `CtxPreStorageRead` and `CtxPostStorageRead` have the same impl iter_prefix_impl(prefix) } @@ -309,8 +309,8 @@ impl<'view> VpEnv<'view> for Ctx { } } -impl StorageRead<'_> for CtxPreStorageRead<'_> { - type PrefixIter = KeyValIterator<(String, Vec)>; +impl StorageRead for CtxPreStorageRead<'_> { + type PrefixIter<'iter> = KeyValIterator<(String, Vec)> where Self: 'iter; fn read_bytes(&self, key: &storage::Key) -> Result>, Error> { let key = key.to_string(); @@ -326,9 +326,9 @@ impl StorageRead<'_> for CtxPreStorageRead<'_> { Ok(HostEnvResult::is_success(found)) } - fn iter_next( - &self, - iter: &mut Self::PrefixIter, + fn iter_next<'iter>( + &'iter self, + iter: &mut Self::PrefixIter<'iter>, ) -> Result)>, Error> { let read_result = unsafe { namada_vp_iter_pre_next(iter.0) }; Ok(read_key_val_bytes_from_buffer( @@ -339,10 +339,10 @@ impl StorageRead<'_> for CtxPreStorageRead<'_> { // ---- Methods below share the same implementation in `pre/post` ---- - fn iter_prefix( - &self, + fn iter_prefix<'iter>( + &'iter self, prefix: &storage::Key, - ) -> Result { + ) -> Result, Error> { iter_prefix_impl(prefix) } @@ -371,8 +371,8 @@ impl StorageRead<'_> for CtxPreStorageRead<'_> { } } -impl StorageRead<'_> for CtxPostStorageRead<'_> { - type PrefixIter = KeyValIterator<(String, Vec)>; +impl StorageRead for CtxPostStorageRead<'_> { + type PrefixIter<'iter> = KeyValIterator<(String, Vec)> where Self:'iter; fn read_bytes(&self, key: &storage::Key) -> Result>, Error> { let key = key.to_string(); @@ -389,9 +389,9 @@ impl StorageRead<'_> for CtxPostStorageRead<'_> { Ok(HostEnvResult::is_success(found)) } - fn iter_next( - &self, - iter: &mut Self::PrefixIter, + fn iter_next<'iter>( + &'iter self, + iter: &mut Self::PrefixIter<'iter>, ) -> Result)>, Error> { let read_result = unsafe { namada_vp_iter_post_next(iter.0) }; Ok(read_key_val_bytes_from_buffer( @@ -402,10 +402,10 @@ impl StorageRead<'_> for CtxPostStorageRead<'_> { // ---- Methods below share the same implementation in `pre/post` ---- - fn iter_prefix( - &self, + fn iter_prefix<'iter>( + &'iter self, prefix: &storage::Key, - ) -> Result { + ) -> Result, Error> { iter_prefix_impl(prefix) } From c40fd1b61a66679185e14d00f5e7dfabad0e37de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Tue, 27 Dec 2022 17:14:09 +0100 Subject: [PATCH 106/166] changelog: #966 --- .../unreleased/improvements/966-gats-lifetimes-refactor.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/966-gats-lifetimes-refactor.md diff --git a/.changelog/unreleased/improvements/966-gats-lifetimes-refactor.md b/.changelog/unreleased/improvements/966-gats-lifetimes-refactor.md new file mode 100644 index 0000000000..b3233a072e --- /dev/null +++ b/.changelog/unreleased/improvements/966-gats-lifetimes-refactor.md @@ -0,0 +1,2 @@ +- Hide the explicit lifetime from StorageRead trait. + ([#966](https://github.com/anoma/namada/pull/966)) \ No newline at end of file From dd2d5045158c93a925deadbcfdcd293d8f54927f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Tue, 27 Dec 2022 17:18:48 +0100 Subject: [PATCH 107/166] core/storage: remove redundant `StorageWrite` impl for mut ref --- core/src/ledger/storage/mod.rs | 38 ---------------------------------- 1 file changed, 38 deletions(-) diff --git a/core/src/ledger/storage/mod.rs b/core/src/ledger/storage/mod.rs index 256c1f2a8b..13d0db6c7e 100644 --- a/core/src/ledger/storage/mod.rs +++ b/core/src/ledger/storage/mod.rs @@ -1102,44 +1102,6 @@ where } } -impl StorageWrite for &mut Storage -where - D: DB + for<'iter> DBIter<'iter>, - H: StorageHasher, -{ - fn write( - &mut self, - key: &crate::types::storage::Key, - val: T, - ) -> storage_api::Result<()> { - let val = val.try_to_vec().unwrap(); - self.write_bytes(key, val) - } - - fn write_bytes( - &mut self, - key: &crate::types::storage::Key, - val: impl AsRef<[u8]>, - ) -> storage_api::Result<()> { - let _ = self - .db - .write_subspace_val(self.block.height, key, val) - .into_storage_result()?; - Ok(()) - } - - fn delete( - &mut self, - key: &crate::types::storage::Key, - ) -> storage_api::Result<()> { - let _ = self - .db - .delete_subspace_val(self.block.height, key) - .into_storage_result()?; - Ok(()) - } -} - impl From for Error { fn from(error: MerkleTreeError) -> Self { Self::MerkleTreeError(error) From c6564c28e98857c04d46b3c7d85d1a3e31075aae Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 27 Dec 2022 19:13:55 +0000 Subject: [PATCH 108/166] [ci] wasm checksums update --- wasm/checksums.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/wasm/checksums.json b/wasm/checksums.json index 5bd0a33931..eb4686a990 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,7 +1,7 @@ { - "tx_bond.wasm": "tx_bond.852a22bb75acb8bbedd7ca1511af6e10b5a1f191ac80f5a6c7b5228bb79c6aed.wasm", + "tx_bond.wasm": "tx_bond.14ebbb45aad0e1301df40a5c412679c05078903794b6caaa2b52e24d9bbb7594.wasm", "tx_change_validator_commission.wasm": "tx_change_validator_commission.cd861e0e82f4934be6d8382d6fff98286b4fadbc20ab826b9e817f6666021273.wasm", - "tx_ibc.wasm": "tx_ibc.eb7d0f6c7cba4fcc402f32ed6a09bf70827521c5539b6393e2078f3931e8fccd.wasm", + "tx_ibc.wasm": "tx_ibc.dc7969c3f1a0f1bfb8e1c942e09f9c2678c2217846e607ee39ea0a7022258bdd.wasm", "tx_init_account.wasm": "tx_init_account.87ece7f13b327f7d15c5b6e7083b510debb1c3205bafe9e36457c8585beeb49c.wasm", "tx_init_proposal.wasm": "tx_init_proposal.c39152be5435cf3f7588ddcde82b801e98902079a152ae3df30bac69833e3ebb.wasm", "tx_init_validator.wasm": "tx_init_validator.56d563e4b9001790d9089ff91c6c98cde95032fb57d97122e58e8b5e363fc13f.wasm", @@ -10,11 +10,11 @@ "tx_unbond.wasm": "tx_unbond.c0a690d0ad43a94294a6405bae3327f638a657446c74dc61dbb3a4d2ce488b5e.wasm", "tx_update_vp.wasm": "tx_update_vp.ee2e9b882c4accadf4626e87d801c9ac8ea8c61ccea677e0532fc6c1ee7db6a2.wasm", "tx_vote_proposal.wasm": "tx_vote_proposal.263fd9f4cb40f283756f394d86bdea3417e9ecd0568d6582c07a5b6bd14287d6.wasm", - "tx_withdraw.wasm": "tx_withdraw.db97f19c3217167374f9163fc4d3738117be23041d75068e97b269e6f9810ec8.wasm", - "vp_implicit.wasm": "vp_implicit.0b6b00b4663aa2c747d51bb0fda2da0454615bcdac345011131e3372ca2598a9.wasm", + "tx_withdraw.wasm": "tx_withdraw.8f53ce136e07c4d1a09bebf2d3d0eba77828622a8c95d5bb3a14b6f934f0cf0d.wasm", + "vp_implicit.wasm": "vp_implicit.5b71d2ab5a9fe9bc21f116f978d1c6b8889ea835386605f7ccfc1204fff79867.wasm", "vp_masp.wasm": "vp_masp.5620cb6e555161641337d308851c760fbab4f9d3693cfd378703aa55e285249d.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.e5df211c9016a8d5ffbba980859470e0c7abbbdf900263830585fb49fa75623d.wasm", - "vp_token.wasm": "vp_token.a289723dd182fe0206e6c4cf1f426a6100787b20e2653d2fad6031e8106157f3.wasm", - "vp_user.wasm": "vp_user.91b6389650a83702c66e220893211b94cdce784d1e18ca8433c69964fc0967ea.wasm", - "vp_validator.wasm": "vp_validator.5175c7aeb34657b9fbe4211031c628e6e834037c26f4cc290bfb50f301d41138.wasm" + "vp_testnet_faucet.wasm": "vp_testnet_faucet.55df1439dfc51ce9bbf592e9dd74036138f749be50e09fbcfb879d582b625b35.wasm", + "vp_token.wasm": "vp_token.dfde368a9e52cbda5aec60fa54d73ee0d36abac31fa3342098ebb29100a0f5b5.wasm", + "vp_user.wasm": "vp_user.33e5dd9f09f7d4ab61330a46edc72ca9063eeff224b9b751e3c1e8124282df2c.wasm", + "vp_validator.wasm": "vp_validator.f5ba5c2dfa46ce3b223df7ec2fd879e86a903ad382beda113c0f0f457a479553.wasm" } \ No newline at end of file From aaf0b439cb65fce7a64ba5e70213177fdacacdec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Wed, 28 Dec 2022 18:02:38 +0100 Subject: [PATCH 109/166] add `NAMADA_LOG_FMT` env var with one of: full (default), json or pretty --- apps/src/lib/logging.rs | 65 +++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/apps/src/lib/logging.rs b/apps/src/lib/logging.rs index d8693acfaa..a84d452324 100644 --- a/apps/src/lib/logging.rs +++ b/apps/src/lib/logging.rs @@ -11,8 +11,21 @@ pub const ENV_KEY: &str = "NAMADA_LOG"; // Env var to enable/disable color log const COLOR_ENV_KEY: &str = "NAMADA_LOG_COLOR"; -// Env var to enable/disable json formatting -const JSON_ENV_KEY: &str = "NAMADA_JSON_FMT"; +// Env var to log formatting (one of "full" (default), "json", "pretty") +const FMT_ENV_KEY: &str = "NAMADA_LOG_FMT"; + +#[derive(Clone, Debug)] +enum Fmt { + Full, + Json, + Pretty, +} + +impl Default for Fmt { + fn default() -> Self { + Self::Full + } +} pub fn init_from_env_or(default: impl Into) -> Result<()> { let filter = filter_from_env_or(default); @@ -32,26 +45,34 @@ pub fn set_subscriber(filter: EnvFilter) -> Result<()> { } else { true }; - let json_format = if let Ok(val) = env::var(JSON_ENV_KEY) { - val.to_ascii_lowercase() != "false" - } else { - true - }; - if json_format { - let my_collector = Subscriber::builder() - .with_ansi(with_color) - .json() - .with_env_filter(filter) - .finish(); - tracing::subscriber::set_global_default(my_collector) - .wrap_err("Failed to set log subscriber") - } else { - let my_collector = Subscriber::builder() - .with_ansi(with_color) - .with_env_filter(filter) - .finish(); - tracing::subscriber::set_global_default(my_collector) - .wrap_err("Failed to set log subscriber") + let format = env::var(FMT_ENV_KEY) + .ok() + .and_then(|val| match val.to_ascii_lowercase().as_str() { + "full" => Some(Fmt::Full), + "json" => Some(Fmt::Json), + "pretty" => Some(Fmt::Pretty), + _ => None, + }) + .unwrap_or_default(); + let builder = Subscriber::builder() + .with_ansi(with_color) + .with_env_filter(filter); + match format { + Fmt::Full => { + let my_collector = builder.with_ansi(with_color).finish(); + tracing::subscriber::set_global_default(my_collector) + .wrap_err("Failed to set log subscriber") + } + Fmt::Json => { + let my_collector = builder.json().finish(); + tracing::subscriber::set_global_default(my_collector) + .wrap_err("Failed to set log subscriber") + } + Fmt::Pretty => { + let my_collector = builder.pretty().finish(); + tracing::subscriber::set_global_default(my_collector) + .wrap_err("Failed to set log subscriber") + } } } From 85bdc5f9af89e1bc2a66943bc43a7d95320d57fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Wed, 28 Dec 2022 18:10:17 +0100 Subject: [PATCH 110/166] changelog: add #968 --- .changelog/unreleased/improvements/968-logging-fmt.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/968-logging-fmt.md diff --git a/.changelog/unreleased/improvements/968-logging-fmt.md b/.changelog/unreleased/improvements/968-logging-fmt.md new file mode 100644 index 0000000000..a88b856618 --- /dev/null +++ b/.changelog/unreleased/improvements/968-logging-fmt.md @@ -0,0 +1,2 @@ +- Allow to set the tracing format with NAMADA_LOG_FMT env var to either full + (default), json or pretty. ([#968](https://github.com/anoma/namada/pull/968)) \ No newline at end of file From d5cb262e4495f30a1d6abbefe03a4d1bf24d8ba2 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Fri, 30 Dec 2022 15:19:12 +0100 Subject: [PATCH 111/166] Adds const and default token to basic fee --- apps/src/lib/client/signing.rs | 4 ++-- apps/src/lib/node/ledger/shell/finalize_block.rs | 15 +++++++-------- apps/src/lib/node/ledger/shell/mod.rs | 8 ++++---- .../src/lib/node/ledger/shell/process_proposal.rs | 8 +++----- core/src/types/transaction/wrapper.rs | 2 ++ 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/apps/src/lib/client/signing.rs b/apps/src/lib/client/signing.rs index fc67d6a329..6d61cfa9ce 100644 --- a/apps/src/lib/client/signing.rs +++ b/apps/src/lib/client/signing.rs @@ -7,7 +7,7 @@ use namada::types::address::{Address, ImplicitAddress}; use namada::types::key::*; use namada::types::storage::Epoch; use namada::types::token::Amount; -use namada::types::transaction::{hash_tx, Fee, WrapperTx}; +use namada::types::transaction::{hash_tx, Fee, WrapperTx, MIN_FEE}; use super::rpc; use crate::cli::context::{WalletAddress, WalletKeypair}; @@ -175,7 +175,7 @@ pub async fn sign_wrapper( let tx = { WrapperTx::new( Fee { - amount: Amount::from(100), + amount: Amount::from(MIN_FEE), token: ctx.get(&args.fee_token), }, keypair, diff --git a/apps/src/lib/node/ledger/shell/finalize_block.rs b/apps/src/lib/node/ledger/shell/finalize_block.rs index b54f00199a..0541c287b5 100644 --- a/apps/src/lib/node/ledger/shell/finalize_block.rs +++ b/apps/src/lib/node/ledger/shell/finalize_block.rs @@ -6,6 +6,7 @@ use namada::ledger::storage::write_log::StorageModification; use namada::ledger::storage_api::StorageRead; use namada::types::storage::{BlockHash, BlockResults, Header}; use namada::types::token::Amount; +use namada::types::transaction::MIN_FEE; use super::governance::execute_governance_proposals; use super::*; @@ -142,10 +143,8 @@ where address::masp() }; - let balance_key = token::balance_key( - &self.storage.native_token, - &fee_payer, - ); + let balance_key = + token::balance_key(&wrapper.fee.token, &fee_payer); let balance: Amount = match self.write_log.read(&balance_key).0 { Some(wal_mod) => { @@ -177,7 +176,7 @@ where }; let balance: u64 = balance.into(); - match balance.checked_sub(100) { + match balance.checked_sub(MIN_FEE) { Some(v) => { self.write_log .write( @@ -441,7 +440,7 @@ mod test_finalize_block { ); let wrapper = WrapperTx::new( Fee { - amount: 100.into(), + amount: MIN_FEE.into(), token: shell.storage.native_token.clone(), }, &keypair, @@ -640,7 +639,7 @@ mod test_finalize_block { ); let wrapper_tx = WrapperTx::new( Fee { - amount: 100.into(), + amount: MIN_FEE.into(), token: shell.storage.native_token.clone(), }, &keypair, @@ -671,7 +670,7 @@ mod test_finalize_block { ); let wrapper_tx = WrapperTx::new( Fee { - amount: 100.into(), + amount: MIN_FEE.into(), token: shell.storage.native_token.clone(), }, &keypair, diff --git a/apps/src/lib/node/ledger/shell/mod.rs b/apps/src/lib/node/ledger/shell/mod.rs index 5f17d35e1d..7bfd8bdb5c 100644 --- a/apps/src/lib/node/ledger/shell/mod.rs +++ b/apps/src/lib/node/ledger/shell/mod.rs @@ -42,7 +42,7 @@ use namada::types::time::{DateTimeUtc, TimeZone, Utc}; use namada::types::token::{self, Amount}; use namada::types::transaction::{ hash_tx, process_tx, verify_decrypted_correctly, AffineCurve, DecryptedTx, - EllipticCurve, PairingEngine, TxType, WrapperTx, + EllipticCurve, PairingEngine, TxType, WrapperTx, MIN_FEE, }; use namada::vm::wasm::{TxCache, VpCache}; use namada::vm::WasmCacheRwAccess; @@ -585,10 +585,10 @@ where masp() }; // check that the fee payer has sufficient balance - let balance = self - .get_balance(&self.storage.native_token, &fee_payer); + let balance = + self.get_balance(&wrapper.fee.token, &fee_payer); - if Amount::from(100) > balance { + if Amount::from(MIN_FEE) > balance { response.code = 1; response.log = String::from( "The address given does not have sufficient \ diff --git a/apps/src/lib/node/ledger/shell/process_proposal.rs b/apps/src/lib/node/ledger/shell/process_proposal.rs index 0004db48e5..0c4a1f0a8e 100644 --- a/apps/src/lib/node/ledger/shell/process_proposal.rs +++ b/apps/src/lib/node/ledger/shell/process_proposal.rs @@ -159,12 +159,10 @@ where masp() }; // check that the fee payer has sufficient balance - let balance = self.get_balance( - &self.storage.native_token, - &fee_payer, - ); + let balance = + self.get_balance(&tx.fee.token, &fee_payer); - if Amount::from(100) <= balance { + if Amount::from(MIN_FEE) <= balance { TxResult { code: ErrorCodes::Ok.into(), info: "Process proposal accepted this \ diff --git a/core/src/types/transaction/wrapper.rs b/core/src/types/transaction/wrapper.rs index e0e6dab6be..7d9493960d 100644 --- a/core/src/types/transaction/wrapper.rs +++ b/core/src/types/transaction/wrapper.rs @@ -21,6 +21,8 @@ pub mod wrapper_tx { hash_tx, EncryptionKey, Hash, TxError, TxType, }; + /// Minimum fee amount in micro NAMs + pub const MIN_FEE: u64 = 100; /// TODO: Determine a sane number for this const GAS_LIMIT_RESOLUTION: u64 = 1_000_000; From 37209b83a0a16638cf6ddc526e08064f139ee18b Mon Sep 17 00:00:00 2001 From: Gavin Birch <13985253+gavinly@users.noreply.github.com> Date: Sat, 31 Dec 2022 12:13:53 -0800 Subject: [PATCH 112/166] Update README.md --- documentation/docs/src/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/src/README.md b/documentation/docs/src/README.md index 34f1357d86..ff2269fd44 100644 --- a/documentation/docs/src/README.md +++ b/documentation/docs/src/README.md @@ -4,7 +4,7 @@ Welcome to Namada's docs! ## About Namada -[Namada](https://namada.net/) is a Proof-of-Stake layer 1 protocol for asset-agnostic, interchain privacy. Namada is Namada's first fractal instance and is currently being developed by [Heliax](https://heliax.dev), a public goods lab. +[Namada](https://namada.net/) is a Proof-of-Stake layer 1 protocol for asset-agnostic, interchain privacy. Namada is Anoma's first fractal instance and is currently being developed by [Heliax](https://heliax.dev), a public goods lab. Key innovations include: - ZCash-like transfers for any assets (fungible and non-fungible) From 5fc6690b0c945e0cd986ba5adb7248979388d5d9 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Mon, 2 Jan 2023 18:00:34 +0100 Subject: [PATCH 113/166] Adds start time argument to namada ledger --- apps/src/bin/namada-node/cli.rs | 4 ++-- apps/src/lib/cli.rs | 32 ++++++++++++++++++++++++++++---- apps/src/lib/node/ledger/mod.rs | 18 +++++++++++++++++- core/src/types/time.rs | 10 ++++++++++ 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/apps/src/bin/namada-node/cli.rs b/apps/src/bin/namada-node/cli.rs index 48f67d3273..c2c118d1ce 100644 --- a/apps/src/bin/namada-node/cli.rs +++ b/apps/src/bin/namada-node/cli.rs @@ -11,9 +11,9 @@ pub fn main() -> Result<()> { } match cmd { cmds::NamadaNode::Ledger(sub) => match sub { - cmds::Ledger::Run(_) => { + cmds::Ledger::Run(args) => { let wasm_dir = ctx.wasm_dir(); - ledger::run(ctx.config.ledger, wasm_dir); + ledger::run(ctx.config.ledger, args.0, wasm_dir); } cmds::Ledger::Reset(_) => { ledger::reset(ctx.config.ledger) diff --git a/apps/src/lib/cli.rs b/apps/src/lib/cli.rs index aa240b704b..08d6dfe722 100644 --- a/apps/src/lib/cli.rs +++ b/apps/src/lib/cli.rs @@ -766,7 +766,7 @@ pub mod cmds { let reset = SubCmd::parse(matches).map(Self::Reset); run.or(reset) // The `run` command is the default if no sub-command given - .or(Some(Self::Run(LedgerRun))) + .or(Some(Self::Run(LedgerRun(args::LedgerRun(None))))) }) } @@ -782,17 +782,21 @@ pub mod cmds { } #[derive(Clone, Debug)] - pub struct LedgerRun; + pub struct LedgerRun(pub args::LedgerRun); impl SubCmd for LedgerRun { const CMD: &'static str = "run"; fn parse(matches: &ArgMatches) -> Option { - matches.subcommand_matches(Self::CMD).map(|_matches| Self) + matches + .subcommand_matches(Self::CMD) + .map(|matches| Self(args::LedgerRun::parse(matches))) } fn def() -> App { - App::new(Self::CMD).about("Run Namada ledger node.") + App::new(Self::CMD) + .about("Run Namada ledger node.") + .add_args::() } } @@ -1519,6 +1523,7 @@ pub mod args { use namada::types::key::*; use namada::types::masp::MaspValue; use namada::types::storage::{self, Epoch}; + use namada::types::time::DateTimeUtc; use namada::types::token; use namada::types::transaction::GasLimit; use rust_decimal::Decimal; @@ -1590,6 +1595,7 @@ pub mod args { arg("max-commission-rate-change"); const MODE: ArgOpt = arg_opt("mode"); const NET_ADDRESS: Arg = arg("net-address"); + const NAMADA_START_TIME: ArgOpt = arg_opt("time"); const NO_CONVERSIONS: ArgFlag = flag("no-conversions"); const OWNER: ArgOpt = arg_opt("owner"); const PIN: ArgFlag = flag("pin"); @@ -1686,6 +1692,24 @@ pub mod args { } } + #[derive(Clone, Debug)] + pub struct LedgerRun(pub Option); + + impl Args for LedgerRun { + fn parse(matches: &ArgMatches) -> Self { + let time = NAMADA_START_TIME.parse(matches); + Self(time) + } + + fn def(app: App) -> App { + app.arg( + NAMADA_START_TIME + .def() + .about("The start time of the ledger."), + ) + } + } + /// Transaction associated results arguments #[derive(Clone, Debug)] pub struct QueryResult { diff --git a/apps/src/lib/node/ledger/mod.rs b/apps/src/lib/node/ledger/mod.rs index ca31310b74..f6c1f262fe 100644 --- a/apps/src/lib/node/ledger/mod.rs +++ b/apps/src/lib/node/ledger/mod.rs @@ -15,6 +15,7 @@ use byte_unit::Byte; use futures::future::TryFutureExt; use namada::ledger::governance::storage as gov_storage; use namada::types::storage::Key; +use namada::types::time::Utc; use once_cell::unsync::Lazy; use sysinfo::{RefreshKind, System, SystemExt}; use tokio::task; @@ -22,6 +23,7 @@ use tower::ServiceBuilder; use self::abortable::AbortableSpawner; use self::shims::abcipp_shim::AbciService; +use crate::cli::args::LedgerRun; use crate::config::utils::num_of_threads; use crate::config::TendermintMode; use crate::facade::tendermint_proto::abci::CheckTxType; @@ -156,7 +158,7 @@ impl Shell { } /// Run the ledger with an async runtime -pub fn run(config: config::Ledger, wasm_dir: PathBuf) { +pub fn run(config: config::Ledger, args: LedgerRun, wasm_dir: PathBuf) { let logical_cores = num_cpus::get(); tracing::info!("Available logical cores: {}", logical_cores); @@ -182,6 +184,20 @@ pub fn run(config: config::Ledger, wasm_dir: PathBuf) { .build_global() .unwrap(); + if let Some(t) = args.0 { + // Sleep until start time if not yet reached + if let Ok(sleep_time) = t.0.signed_duration_since(Utc::now()).to_std() { + if !sleep_time.is_zero() { + tracing::info!( + "Waiting ledger start time: {:?}, time left: {:?}", + t, + sleep_time + ); + std::thread::sleep(sleep_time) + } + } + } + // Start tokio runtime with the `run_aux` function tokio::runtime::Builder::new_multi_thread() .worker_threads(tokio_threads) diff --git a/core/src/types/time.rs b/core/src/types/time.rs index a508501d94..7288d88bab 100644 --- a/core/src/types/time.rs +++ b/core/src/types/time.rs @@ -3,8 +3,10 @@ use std::convert::{TryFrom, TryInto}; use std::fmt::Display; use std::ops::{Add, Sub}; +use std::str::FromStr; use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; +use chrono::ParseError; pub use chrono::{DateTime, Duration, TimeZone, Utc}; /// Check if the given `duration` has passed since the given `start. @@ -109,6 +111,14 @@ impl DateTimeUtc { } } +impl FromStr for DateTimeUtc { + type Err = ParseError; + + fn from_str(s: &str) -> Result { + Ok(Self(s.parse::>()?)) + } +} + impl Add for DateTimeUtc { type Output = DateTimeUtc; From 6b174feddda43a41a0df3ea9355cac15cbe1264d Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Tue, 3 Jan 2023 00:32:48 +0100 Subject: [PATCH 114/166] Refactors ledger sleep --- apps/src/bin/namada-node/cli.rs | 4 ++-- apps/src/lib/node/ledger/mod.rs | 28 +++++++++++++++------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/apps/src/bin/namada-node/cli.rs b/apps/src/bin/namada-node/cli.rs index c2c118d1ce..ca1bbbc7b2 100644 --- a/apps/src/bin/namada-node/cli.rs +++ b/apps/src/bin/namada-node/cli.rs @@ -11,9 +11,9 @@ pub fn main() -> Result<()> { } match cmd { cmds::NamadaNode::Ledger(sub) => match sub { - cmds::Ledger::Run(args) => { + cmds::Ledger::Run(cmds::LedgerRun(args)) => { let wasm_dir = ctx.wasm_dir(); - ledger::run(ctx.config.ledger, args.0, wasm_dir); + ledger::run(ctx.config.ledger, args, wasm_dir); } cmds::Ledger::Reset(_) => { ledger::reset(ctx.config.ledger) diff --git a/apps/src/lib/node/ledger/mod.rs b/apps/src/lib/node/ledger/mod.rs index f6c1f262fe..50b954b096 100644 --- a/apps/src/lib/node/ledger/mod.rs +++ b/apps/src/lib/node/ledger/mod.rs @@ -23,7 +23,7 @@ use tower::ServiceBuilder; use self::abortable::AbortableSpawner; use self::shims::abcipp_shim::AbciService; -use crate::cli::args::LedgerRun; +use crate::cli::args; use crate::config::utils::num_of_threads; use crate::config::TendermintMode; use crate::facade::tendermint_proto::abci::CheckTxType; @@ -158,7 +158,7 @@ impl Shell { } /// Run the ledger with an async runtime -pub fn run(config: config::Ledger, args: LedgerRun, wasm_dir: PathBuf) { +pub fn run(config: config::Ledger, args: args::LedgerRun, wasm_dir: PathBuf) { let logical_cores = num_cpus::get(); tracing::info!("Available logical cores: {}", logical_cores); @@ -176,21 +176,15 @@ pub fn run(config: config::Ledger, args: LedgerRun, wasm_dir: PathBuf) { ); tracing::info!("Using {} threads for Tokio.", tokio_threads); - // Configure number of threads for rayon (used in `par_iter` when running - // VPs) - rayon::ThreadPoolBuilder::new() - .num_threads(rayon_threads) - .thread_name(|i| format!("ledger-rayon-worker-{}", i)) - .build_global() - .unwrap(); - - if let Some(t) = args.0 { + if let Some(time) = args.0 { // Sleep until start time if not yet reached - if let Ok(sleep_time) = t.0.signed_duration_since(Utc::now()).to_std() { + if let Ok(sleep_time) = + time.0.signed_duration_since(Utc::now()).to_std() + { if !sleep_time.is_zero() { tracing::info!( "Waiting ledger start time: {:?}, time left: {:?}", - t, + time, sleep_time ); std::thread::sleep(sleep_time) @@ -198,6 +192,14 @@ pub fn run(config: config::Ledger, args: LedgerRun, wasm_dir: PathBuf) { } } + // Configure number of threads for rayon (used in `par_iter` when running + // VPs) + rayon::ThreadPoolBuilder::new() + .num_threads(rayon_threads) + .thread_name(|i| format!("ledger-rayon-worker-{}", i)) + .build_global() + .unwrap(); + // Start tokio runtime with the `run_aux` function tokio::runtime::Builder::new_multi_thread() .worker_threads(tokio_threads) From 16c4bca5e34046ac617793fa784d4805932dcaee Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Tue, 3 Jan 2023 00:49:37 +0100 Subject: [PATCH 115/166] Moves ledger sleep --- apps/src/bin/namada-node/cli.rs | 20 +++++++++++++++++++- apps/src/lib/node/ledger/mod.rs | 20 +------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/src/bin/namada-node/cli.rs b/apps/src/bin/namada-node/cli.rs index ca1bbbc7b2..b9048ea312 100644 --- a/apps/src/bin/namada-node/cli.rs +++ b/apps/src/bin/namada-node/cli.rs @@ -1,6 +1,7 @@ //! Namada node CLI. use eyre::{Context, Result}; +use namada::types::time::Utc; use namada_apps::cli::{self, cmds}; use namada_apps::node::ledger; @@ -13,7 +14,24 @@ pub fn main() -> Result<()> { cmds::NamadaNode::Ledger(sub) => match sub { cmds::Ledger::Run(cmds::LedgerRun(args)) => { let wasm_dir = ctx.wasm_dir(); - ledger::run(ctx.config.ledger, args, wasm_dir); + + // Sleep until start time if needed + if let Some(time) = args.0 { + if let Ok(sleep_time) = + time.0.signed_duration_since(Utc::now()).to_std() + { + if !sleep_time.is_zero() { + tracing::info!( + "Waiting ledger start time: {:?}, time left: \ + {:?}", + time, + sleep_time + ); + std::thread::sleep(sleep_time) + } + } + } + ledger::run(ctx.config.ledger, wasm_dir); } cmds::Ledger::Reset(_) => { ledger::reset(ctx.config.ledger) diff --git a/apps/src/lib/node/ledger/mod.rs b/apps/src/lib/node/ledger/mod.rs index 50b954b096..ca31310b74 100644 --- a/apps/src/lib/node/ledger/mod.rs +++ b/apps/src/lib/node/ledger/mod.rs @@ -15,7 +15,6 @@ use byte_unit::Byte; use futures::future::TryFutureExt; use namada::ledger::governance::storage as gov_storage; use namada::types::storage::Key; -use namada::types::time::Utc; use once_cell::unsync::Lazy; use sysinfo::{RefreshKind, System, SystemExt}; use tokio::task; @@ -23,7 +22,6 @@ use tower::ServiceBuilder; use self::abortable::AbortableSpawner; use self::shims::abcipp_shim::AbciService; -use crate::cli::args; use crate::config::utils::num_of_threads; use crate::config::TendermintMode; use crate::facade::tendermint_proto::abci::CheckTxType; @@ -158,7 +156,7 @@ impl Shell { } /// Run the ledger with an async runtime -pub fn run(config: config::Ledger, args: args::LedgerRun, wasm_dir: PathBuf) { +pub fn run(config: config::Ledger, wasm_dir: PathBuf) { let logical_cores = num_cpus::get(); tracing::info!("Available logical cores: {}", logical_cores); @@ -176,22 +174,6 @@ pub fn run(config: config::Ledger, args: args::LedgerRun, wasm_dir: PathBuf) { ); tracing::info!("Using {} threads for Tokio.", tokio_threads); - if let Some(time) = args.0 { - // Sleep until start time if not yet reached - if let Ok(sleep_time) = - time.0.signed_duration_since(Utc::now()).to_std() - { - if !sleep_time.is_zero() { - tracing::info!( - "Waiting ledger start time: {:?}, time left: {:?}", - time, - sleep_time - ); - std::thread::sleep(sleep_time) - } - } - } - // Configure number of threads for rayon (used in `par_iter` when running // VPs) rayon::ThreadPoolBuilder::new() From 9976043ebe725f8ccb5e3134619af003d4dd7b01 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Thu, 22 Dec 2022 12:52:18 +0000 Subject: [PATCH 116/166] Add `max_proposal_bytes` ledger param --- apps/src/lib/config/genesis.rs | 31 +++- apps/src/lib/node/ledger/shell/init_chain.rs | 2 + apps/src/lib/node/ledger/tendermint_node.rs | 12 +- core/src/ledger/parameters/mod.rs | 57 ++++-- core/src/ledger/parameters/storage.rs | 19 ++ core/src/ledger/storage/mod.rs | 1 + core/src/types/chain.rs | 179 ++++++++++++++++++- genesis/dev.toml | 2 + genesis/e2e-tests-single-node.toml | 2 + tests/src/e2e/ledger_tests.rs | 1 + 10 files changed, 285 insertions(+), 21 deletions(-) diff --git a/apps/src/lib/config/genesis.rs b/apps/src/lib/config/genesis.rs index ebad28f311..87ff12995e 100644 --- a/apps/src/lib/config/genesis.rs +++ b/apps/src/lib/config/genesis.rs @@ -12,6 +12,7 @@ use namada::ledger::pos::{GenesisValidator, PosParams}; use namada::types::address::Address; #[cfg(not(feature = "dev"))] use namada::types::chain::ChainId; +use namada::types::chain::ProposalBytes; use namada::types::key::dkg_session_keys::DkgPublicKey; use namada::types::key::*; use namada::types::time::{DateTimeUtc, DurationSecs}; @@ -32,6 +33,7 @@ pub mod genesis_config { use namada::ledger::parameters::EpochDuration; use namada::ledger::pos::{GenesisValidator, PosParams}; use namada::types::address::Address; + use namada::types::chain::ProposalBytes; use namada::types::key::dkg_session_keys::DkgPublicKey; use namada::types::key::*; use namada::types::time::Rfc3339String; @@ -222,17 +224,30 @@ pub mod genesis_config { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct ParametersConfig { - // Minimum number of blocks per epoch. + /// Max payload size, in bytes, for a tx batch proposal. + /// + /// Block proposers may never return a `PrepareProposal` + /// response containing `txs` with a byte length greater + /// than whatever is configured through this parameter. + /// + /// Note that this parameter's value will always be strictly + /// smaller than a Tendermint block's `MaxBytes` consensus + /// parameter. Currently, we hard cap `max_proposal_bytes` + /// at 90 MiB in Namada, which leaves at least 10 MiB of + /// room for header data, evidence and protobuf + /// serialization overhead in Tendermint blocks. + pub max_proposal_bytes: ProposalBytes, + /// Minimum number of blocks per epoch. // XXX: u64 doesn't work with toml-rs! pub min_num_of_blocks: u64, - // Maximum duration per block (in seconds). + /// Maximum duration per block (in seconds). // TODO: this is i64 because datetime wants it pub max_expected_time_per_block: i64, - // Hashes of whitelisted vps array. `None` value or an empty array - // disables whitelisting. + /// Hashes of whitelisted vps array. `None` value or an empty array + /// disables whitelisting. pub vp_whitelist: Option>, - // Hashes of whitelisted txs array. `None` value or an empty array - // disables whitelisting. + /// Hashes of whitelisted txs array. `None` value or an empty array + /// disables whitelisting. pub tx_whitelist: Option>, /// Filename of implicit accounts validity predicate WASM code pub implicit_vp: String, @@ -574,6 +589,7 @@ pub mod genesis_config { parameters.max_expected_time_per_block, ) .into(), + max_proposal_bytes: parameters.max_proposal_bytes, vp_whitelist: parameters.vp_whitelist.unwrap_or_default(), tx_whitelist: parameters.tx_whitelist.unwrap_or_default(), implicit_vp_code_path, @@ -796,6 +812,8 @@ pub struct ImplicitAccount { BorshDeserialize, )] pub struct Parameters { + // Max payload size, in bytes, for a tx batch proposal. + pub max_proposal_bytes: ProposalBytes, /// Epoch duration pub epoch_duration: EpochDuration, /// Maximum expected time per block @@ -867,6 +885,7 @@ pub fn genesis() -> Genesis { min_duration: namada::types::time::Duration::seconds(600).into(), }, max_expected_time_per_block: namada::types::time::DurationSecs(30), + max_proposal_bytes: Default::default(), vp_whitelist: vec![], tx_whitelist: vec![], implicit_vp_code_path: vp_implicit_path.into(), diff --git a/apps/src/lib/node/ledger/shell/init_chain.rs b/apps/src/lib/node/ledger/shell/init_chain.rs index d025b2753f..ac783e9cfb 100644 --- a/apps/src/lib/node/ledger/shell/init_chain.rs +++ b/apps/src/lib/node/ledger/shell/init_chain.rs @@ -65,6 +65,7 @@ where // Initialize protocol parameters let genesis::Parameters { epoch_duration, + max_proposal_bytes, max_expected_time_per_block, vp_whitelist, tx_whitelist, @@ -98,6 +99,7 @@ where } let parameters = Parameters { epoch_duration, + max_proposal_bytes, max_expected_time_per_block, vp_whitelist, tx_whitelist, diff --git a/apps/src/lib/node/ledger/tendermint_node.rs b/apps/src/lib/node/ledger/tendermint_node.rs index 748dd2b0c9..da43b0dbc3 100644 --- a/apps/src/lib/node/ledger/tendermint_node.rs +++ b/apps/src/lib/node/ledger/tendermint_node.rs @@ -14,7 +14,7 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::process::Command; use crate::config; -use crate::facade::tendermint::Genesis; +use crate::facade::tendermint::{block, Genesis}; use crate::facade::tendermint_config::net::Address as TendermintAddress; use crate::facade::tendermint_config::{ Error as TendermintError, TendermintConfig, @@ -380,6 +380,16 @@ async fn write_tm_genesis( genesis.genesis_time = genesis_time .try_into() .expect("Couldn't convert DateTimeUtc to Tendermint Time"); + genesis.consensus_params.block = Some(block::Size { + // maximum size of a serialized Tendermint block + // cannot go over 100 MiB + max_bytes: (100 << 20) - 1, /* unsure if we are dealing with an open + * range, so it's better to subtract one, + * here */ + // gas is metered app-side, so we disable it + // at the Tendermint level + max_gas: -1, + }); #[cfg(feature = "abcipp")] { genesis.consensus_params.timeout.commit = diff --git a/core/src/ledger/parameters/mod.rs b/core/src/ledger/parameters/mod.rs index cb84bd56e7..0cadc833a4 100644 --- a/core/src/ledger/parameters/mod.rs +++ b/core/src/ledger/parameters/mod.rs @@ -9,6 +9,7 @@ use super::storage::types::{decode, encode}; use super::storage::{types, Storage}; use crate::ledger::storage::{self as ledger_storage}; use crate::types::address::{Address, InternalAddress}; +use crate::types::chain::ProposalBytes; use crate::types::storage::Key; use crate::types::time::DurationSecs; @@ -32,6 +33,8 @@ pub struct Parameters { pub epoch_duration: EpochDuration, /// Maximum expected time per block (read only) pub max_expected_time_per_block: DurationSecs, + /// Max payload size, in bytes, for a tx batch proposal. + pub max_proposal_bytes: ProposalBytes, /// Whitelisted validity predicate hashes (read only) pub vp_whitelist: Vec, /// Whitelisted tx hashes (read only) @@ -101,6 +104,7 @@ impl Parameters { let Self { epoch_duration, max_expected_time_per_block, + max_proposal_bytes, vp_whitelist, tx_whitelist, implicit_vp, @@ -111,6 +115,16 @@ impl Parameters { pos_inflation_amount, } = self; + // write max proposal bytes parameter + let max_proposal_bytes_key = storage::get_max_proposal_bytes_key(); + let max_proposal_bytes_value = encode(&max_proposal_bytes); + storage + .write(&max_proposal_bytes_key, max_proposal_bytes_value) + .expect( + "Max proposal bytes parameter must be initialized in the \ + genesis block", + ); + // write epoch parameters let epoch_key = storage::get_epoch_duration_storage_key(); let epoch_value = encode(epoch_duration); @@ -382,6 +396,17 @@ where DB: ledger_storage::DB + for<'iter> ledger_storage::DBIter<'iter>, H: ledger_storage::StorageHasher, { + // read max proposal bytes + let (max_proposal_bytes, gas_proposal_bytes) = { + let key = storage::get_max_proposal_bytes_key(); + let (value, gas) = + storage.read(&key).map_err(ReadError::StorageError)?; + let value: ProposalBytes = + decode(value.ok_or(ReadError::ParametersMissing)?) + .map_err(ReadError::StorageTypeError)?; + (value, gas) + }; + // read epoch duration let (epoch_duration, gas_epoch) = read_epoch_duration_parameter(storage) .expect("Couldn't read epoch duration parameters"); @@ -464,10 +489,31 @@ where decode(value.ok_or(ReadError::ParametersMissing)?) .map_err(ReadError::StorageTypeError)?; + let total_gas_cost = [ + gas_epoch, + gas_tx, + gas_vp, + gas_time, + gas_implicit_vp, + gas_epy, + gas_gain_p, + gas_gain_d, + gas_staked, + gas_reward, + gas_proposal_bytes, + ] + .into_iter() + .fold(0u64, |accum, gas| { + accum + .checked_add(gas) + .expect("u64 overflow occurred while doing gas arithmetic") + }); + Ok(( Parameters { epoch_duration, max_expected_time_per_block, + max_proposal_bytes, vp_whitelist, tx_whitelist, implicit_vp, @@ -477,15 +523,6 @@ where staked_ratio, pos_inflation_amount, }, - gas_epoch - + gas_tx - + gas_vp - + gas_time - + gas_implicit_vp - + gas_epy - + gas_gain_p - + gas_gain_d - + gas_staked - + gas_reward, + total_gas_cost, )) } diff --git a/core/src/ledger/parameters/storage.rs b/core/src/ledger/parameters/storage.rs index b8dc84fd76..d41f883332 100644 --- a/core/src/ledger/parameters/storage.rs +++ b/core/src/ledger/parameters/storage.rs @@ -12,6 +12,7 @@ const POS_GAIN_P_KEY: &str = "pos_gain_p"; const POS_GAIN_D_KEY: &str = "pos_gain_d"; const STAKED_RATIO_KEY: &str = "staked_ratio_key"; const POS_INFLATION_AMOUNT_KEY: &str = "pos_inflation_amount_key"; +const MAX_PROPOSAL_BYTES_KEY: &str = "max_proposal_bytes"; /// Returns if the key is a parameter key. pub fn is_parameter_key(key: &Key) -> bool { @@ -106,6 +107,14 @@ pub fn is_pos_inflation_amount_key(key: &Key) -> bool { ] if addr == &ADDRESS && pos_inflation_amount == POS_INFLATION_AMOUNT_KEY) } +/// Returns if the key is the max proposal bytes key. +pub fn is_max_proposal_bytes_key(key: &Key) -> bool { + matches!(&key.segments[..], [ + DbKeySeg::AddressSeg(addr), + DbKeySeg::StringSeg(max_proposal_bytes), + ] if addr == &ADDRESS && max_proposal_bytes == MAX_PROPOSAL_BYTES_KEY) +} + /// Storage key used for epoch parameter. pub fn get_epoch_duration_storage_key() -> Key { Key { @@ -205,3 +214,13 @@ pub fn get_pos_inflation_amount_key() -> Key { ], } } + +/// Storage key used for the max proposal bytes. +pub fn get_max_proposal_bytes_key() -> Key { + Key { + segments: vec![ + DbKeySeg::AddressSeg(ADDRESS), + DbKeySeg::StringSeg(MAX_PROPOSAL_BYTES_KEY.to_string()), + ], + } +} diff --git a/core/src/ledger/storage/mod.rs b/core/src/ledger/storage/mod.rs index 8285e58bab..92efa05c23 100644 --- a/core/src/ledger/storage/mod.rs +++ b/core/src/ledger/storage/mod.rs @@ -1279,6 +1279,7 @@ mod tests { ..Default::default() }; let mut parameters = Parameters { + max_proposal_bytes: Default::default(), epoch_duration: epoch_duration.clone(), max_expected_time_per_block: Duration::seconds(max_expected_time_per_block).into(), vp_whitelist: vec![], diff --git a/core/src/types/chain.rs b/core/src/types/chain.rs index 06a5d3938c..7437793cfc 100644 --- a/core/src/types/chain.rs +++ b/core/src/types/chain.rs @@ -1,10 +1,11 @@ //! Chain related data types // TODO move BlockHash and BlockHeight here from the storage types -use std::fmt::Display; +use std::fmt; +use std::num::NonZeroU64; use std::str::FromStr; -use borsh::{BorshDeserialize, BorshSerialize}; +use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use thiserror::Error; @@ -16,6 +17,165 @@ pub const CHAIN_ID_PREFIX_MAX_LEN: usize = 19; /// Separator between chain ID prefix and the generated hash pub const CHAIN_ID_PREFIX_SEP: char = '.'; +/// Configuration parameter for the upper limit on the number +/// of bytes transactions can occupy in a block proposal. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Hash, + Debug, + BorshSerialize, + BorshDeserialize, +)] +pub struct ProposalBytes { + inner: NonZeroU64, +} + +impl Serialize for ProposalBytes { + fn serialize(&self, s: S) -> Result + where + S: serde::Serializer, + { + s.serialize_u64(self.inner.get()) + } +} + +impl<'de> Deserialize<'de> for ProposalBytes { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct Visitor; + + impl<'de> serde::de::Visitor<'de> for Visitor { + type Value = ProposalBytes; + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "a u64 in the range 1 - {}", + ProposalBytes::RAW_MAX.get() + ) + } + + fn visit_u64(self, size: u64) -> Result + where + E: serde::de::Error, + { + ProposalBytes::new(size).ok_or_else(|| { + serde::de::Error::invalid_value( + serde::de::Unexpected::Unsigned(size), + &self, + ) + }) + } + + // NOTE: this is only needed because of a bug in the toml parser + // https://github.com/toml-rs/toml-rs/issues/256 + fn visit_i64(self, size: i64) -> Result + where + E: serde::de::Error, + { + ProposalBytes::new(size as u64).ok_or_else(|| { + serde::de::Error::invalid_value( + serde::de::Unexpected::Signed(size), + &self, + ) + }) + } + } + + deserializer.deserialize_u64(Visitor) + } +} + +impl BorshSchema for ProposalBytes { + fn add_definitions_recursively( + definitions: &mut std::collections::HashMap< + borsh::schema::Declaration, + borsh::schema::Definition, + >, + ) { + let fields = borsh::schema::Fields::NamedFields(vec![( + "inner".into(), + u64::declaration(), + )]); + let definition = borsh::schema::Definition::Struct { fields }; + definitions.insert(Self::declaration(), definition); + } + + fn declaration() -> borsh::schema::Declaration { + std::any::type_name::().into() + } +} + +impl Default for ProposalBytes { + #[inline] + fn default() -> Self { + Self { + inner: Self::RAW_DEFAULT, + } + } +} + +// constants +impl ProposalBytes { + /// The upper bound of a [`ProposalBytes`] value. + pub const MAX: ProposalBytes = ProposalBytes { + inner: Self::RAW_MAX, + }; + /// The (raw) default value for a [`ProposalBytes`]. + /// + /// This value must be within the range `[1 B, 90 MiB]`. + const RAW_DEFAULT: NonZeroU64 = unsafe { + // SAFETY: We are constructing a greater than zero + // value, so the API contract is never violated. + // Moreover, 21 MiB <= 90 MiB. + NonZeroU64::new_unchecked(21 << 20) + }; + /// The (raw) upper bound of a [`ProposalBytes`] value. + /// + /// The maximum space a serialized Tendermint block can + /// occupy is 100 MiB. We reserve 10 MiB for serialization + /// overhead, evidence and header data, and 90 MiB for + /// tx data. + const RAW_MAX: NonZeroU64 = unsafe { + // SAFETY: We are constructing a greater than zero + // value, so the API contract is never violated. + NonZeroU64::new_unchecked(90 << 20) + }; +} + +impl ProposalBytes { + /// Return the number of bytes as a [`u64`] value. + #[inline] + pub const fn get(self) -> u64 { + self.inner.get() + } + + /// Try to construct a new [`ProposalBytes`] instance, + /// from the given `max_bytes` value. + /// + /// This function will return [`None`] if `max_bytes` is not within + /// the inclusive range of 1 to [`ProposalBytes::MAX`]. + #[inline] + pub fn new(max_bytes: u64) -> Option { + NonZeroU64::new(max_bytes) + .map(|inner| Self { inner }) + .and_then(|value| { + if value.get() > Self::RAW_MAX.get() { + None + } else { + Some(value) + } + }) + } +} + /// Development default chain ID. Must be [`CHAIN_ID_LENGTH`] long. #[cfg(feature = "dev")] pub const DEFAULT_CHAIN_ID: &str = "namada-devchain.00000000000000"; @@ -110,7 +270,7 @@ impl Default for ChainId { } } -impl Display for ChainId { +impl fmt::Display for ChainId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } @@ -158,7 +318,7 @@ impl FromStr for ChainId { #[serde(transparent)] pub struct ChainIdPrefix(String); -impl Display for ChainIdPrefix { +impl fmt::Display for ChainIdPrefix { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } @@ -234,5 +394,16 @@ mod tests { let errors = chain_id.validate(&genesis_bytes); assert!(errors.is_empty(), "There should be no validation errors {:#?}", errors); } + + /// Test if [`ProposalBytes`] serde serialization is correct. + #[test] + fn test_proposal_size_serialize_roundtrip(s in 1u64..=ProposalBytes::MAX.get()) { + let size = ProposalBytes::new(s).expect("Test failed"); + assert_eq!(size.get(), s); + let json = serde_json::to_string(&size).expect("Test failed"); + let deserialized: ProposalBytes = + serde_json::from_str(&json).expect("Test failed"); + assert_eq!(size, deserialized); + } } } diff --git a/genesis/dev.toml b/genesis/dev.toml index 3c8f67c3a1..ea02aabcfe 100644 --- a/genesis/dev.toml +++ b/genesis/dev.toml @@ -146,6 +146,8 @@ min_num_of_blocks = 10 max_expected_time_per_block = 30 # Expected epochs per year (also sets the minimum duration of an epoch in seconds) epochs_per_year = 525_600 +# Max payload size, in bytes, for a tx batch proposal. +max_proposal_bytes = 22020096 # Proof of stake parameters. [pos_params] diff --git a/genesis/e2e-tests-single-node.toml b/genesis/e2e-tests-single-node.toml index 554dfd57b1..249e55ef6d 100644 --- a/genesis/e2e-tests-single-node.toml +++ b/genesis/e2e-tests-single-node.toml @@ -151,6 +151,8 @@ filename = "vp_masp.wasm" min_num_of_blocks = 4 # Maximum expected time per block (in seconds). max_expected_time_per_block = 30 +# Max payload size, in bytes, for a tx batch proposal. +max_proposal_bytes = 22020096 # vp whitelist vp_whitelist = [] # tx whitelist diff --git a/tests/src/e2e/ledger_tests.rs b/tests/src/e2e/ledger_tests.rs index dc129818c3..0ea0f069dc 100644 --- a/tests/src/e2e/ledger_tests.rs +++ b/tests/src/e2e/ledger_tests.rs @@ -2226,6 +2226,7 @@ fn proposal_submission() -> Result<()> { |genesis| { let parameters = ParametersConfig { epochs_per_year: epochs_per_year_from_min_duration(1), + max_proposal_bytes: Default::default(), min_num_of_blocks: 1, max_expected_time_per_block: 1, vp_whitelist: Some(get_all_wasms_hashes( From e2c39eafb2545430194a102b02cc1d454a0e8bf8 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Tue, 3 Jan 2023 15:59:50 +0100 Subject: [PATCH 117/166] Reduces block size to 5 MiB --- apps/src/lib/node/ledger/shell/prepare_proposal.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/prepare_proposal.rs b/apps/src/lib/node/ledger/shell/prepare_proposal.rs index 8f56f9a86a..c4d9a74dd4 100644 --- a/apps/src/lib/node/ledger/shell/prepare_proposal.rs +++ b/apps/src/lib/node/ledger/shell/prepare_proposal.rs @@ -14,10 +14,10 @@ use crate::node::ledger::shell::{process_tx, ShellMode}; use crate::node::ledger::shims::abcipp_shim_types::shim::TxBytes; // TODO: remove this hard-coded value; Tendermint, and thus -// Namada uses 20 MiB max block sizes by default; 16 MiB leaves +// Namada uses 20 MiB max block sizes by default; 5 MiB leaves // plenty of room for header data, evidence and protobuf serialization // overhead -const MAX_PROPOSAL_SIZE: usize = 16 << 20; +const MAX_PROPOSAL_SIZE: usize = 5 << 20; const HALF_MAX_PROPOSAL_SIZE: usize = MAX_PROPOSAL_SIZE / 2; impl Shell From a43de416b5941670475854fab03639923613b955 Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Wed, 4 Jan 2023 16:54:17 +0100 Subject: [PATCH 118/166] ci: fix e2e test script --- .github/workflows/scripts/schedule-e2e.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/scripts/schedule-e2e.py b/.github/workflows/scripts/schedule-e2e.py index 6e68feb736..df0ffed7c0 100644 --- a/.github/workflows/scripts/schedule-e2e.py +++ b/.github/workflows/scripts/schedule-e2e.py @@ -42,4 +42,6 @@ def find_freer_machine(): command = CARGO_TEST_COMMAND.format(test_name) subprocess.check_call(command, shell=True, stdout=sys.stdout, stderr=subprocess.STDOUT) except: - continue + print("TEST FAILED: {}".format(test_name)) + print("run locally with: {}".format(command)) + break From d2f8dfce91e758ead648a41f258b7b824df166e8 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Thu, 5 Jan 2023 05:48:05 -0500 Subject: [PATCH 119/166] Revert "Merge pull request #965 from anoma/brent/fix-validator-commission-change-test" This reverts commit bd4dff2d26ff016bfd57a7b5e8b4e89bfe26d68c, reversing changes made to 05f7fe553f0628591caede79b84b8d03c72ecdf6. This branch was merged in an incorrect state. A rerolled version will be merged later. --- ...65-fix-validator-commission-change-test.md | 3 --- proof_of_stake/src/lib.rs | 11 ++++++---- .../src/tx_change_validator_commission.rs | 22 +++++-------------- 3 files changed, 13 insertions(+), 23 deletions(-) delete mode 100644 .changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md diff --git a/.changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md b/.changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md deleted file mode 100644 index 274b48c5d1..0000000000 --- a/.changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md +++ /dev/null @@ -1,3 +0,0 @@ -- Fix the commission rate change wasm test, which failed because an arbitrary - value for a new rate was allowed that could be equal to the previous rate. - ([#965](https://github.com/anoma/namada/pull/965)) \ No newline at end of file diff --git a/proof_of_stake/src/lib.rs b/proof_of_stake/src/lib.rs index 661533cb16..64c7ffdff8 100644 --- a/proof_of_stake/src/lib.rs +++ b/proof_of_stake/src/lib.rs @@ -563,14 +563,15 @@ pub trait PosActions: PosReadOnly { } }; let params = self.read_pos_params()?; + let rate_at_pipeline = *commission_rates .get_at_offset(current_epoch, DynEpochOffset::PipelineLen, ¶ms) .expect("Could not find a rate in given epoch"); - - // Return early with no further changes if there is no rate change - // instead of returning an error if new_rate == rate_at_pipeline { - return Ok(()); + return Err(CommissionRateChangeError::ChangeIsZero( + validator.clone(), + ) + .into()); } let rate_before_pipeline = *commission_rates @@ -1017,6 +1018,8 @@ pub enum CommissionRateChangeError { NegativeRate(Decimal, Address), #[error("Rate change of {0} is too large for validator {1}")] RateChangeTooLarge(Decimal, Address), + #[error("The rate change is 0 for validator {0}")] + ChangeIsZero(Address), #[error( "There is no maximum rate change written in storage for validator {0}" )] diff --git a/wasm/wasm_source/src/tx_change_validator_commission.rs b/wasm/wasm_source/src/tx_change_validator_commission.rs index 3d30f25908..f32d83f34e 100644 --- a/wasm/wasm_source/src/tx_change_validator_commission.rs +++ b/wasm/wasm_source/src/tx_change_validator_commission.rs @@ -18,8 +18,6 @@ fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { #[cfg(test)] mod tests { - use std::cmp; - use namada::ledger::pos::{PosParams, PosVP}; use namada::proto::Tx; use namada::types::storage::Epoch; @@ -104,6 +102,9 @@ mod tests { .read_validator_commission_rate(&commission_change.validator)? .unwrap(); + dbg!(&commission_rates_pre); + dbg!(&commission_rates_post); + // Before pipeline, the commission rates should not change for epoch in 0..pos_params.pipeline_len { assert_eq!( @@ -159,24 +160,13 @@ mod tests { .prop_map(|num| Decimal::from(num) / Decimal::from(100_000_u64)) } - fn arb_new_rate( - min: Decimal, - max: Decimal, - rate_pre: Decimal, - ) -> impl Strategy { - arb_rate(min, max).prop_filter( - "New rate must not be equal to the previous epoch's rate", - move |v| v != &rate_pre, - ) - } - fn arb_commission_change( rate_pre: Decimal, max_change: Decimal, ) -> impl Strategy { - let min = cmp::max(rate_pre - max_change, Decimal::ZERO); - let max = cmp::min(rate_pre + max_change, Decimal::ONE); - (arb_established_address(), arb_new_rate(min, max, rate_pre)).prop_map( + let min = rate_pre - max_change; + let max = rate_pre + max_change; + (arb_established_address(), arb_rate(min, max)).prop_map( |(validator, new_rate)| transaction::pos::CommissionChange { validator: Address::Established(validator), new_rate, From 0a6e95ae1f57e37235be45786a1db43922309d39 Mon Sep 17 00:00:00 2001 From: brentstone Date: Mon, 26 Dec 2022 16:32:00 -0500 Subject: [PATCH 120/166] fix arb rate: prevent same rate and ensure proper bounds --- .../src/tx_change_validator_commission.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/wasm/wasm_source/src/tx_change_validator_commission.rs b/wasm/wasm_source/src/tx_change_validator_commission.rs index f32d83f34e..89feb652ea 100644 --- a/wasm/wasm_source/src/tx_change_validator_commission.rs +++ b/wasm/wasm_source/src/tx_change_validator_commission.rs @@ -18,6 +18,8 @@ fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { #[cfg(test)] mod tests { + use std::cmp; + use namada::ledger::pos::{PosParams, PosVP}; use namada::proto::Tx; use namada::types::storage::Epoch; @@ -160,13 +162,24 @@ mod tests { .prop_map(|num| Decimal::from(num) / Decimal::from(100_000_u64)) } + fn arb_new_rate( + min: Decimal, + max: Decimal, + rate_pre: Decimal, + ) -> impl Strategy { + arb_rate(min, max).prop_filter( + "New rate must not be equal to the previous epoch's rate", + move |v| v != &rate_pre, + ) + } + fn arb_commission_change( rate_pre: Decimal, max_change: Decimal, ) -> impl Strategy { - let min = rate_pre - max_change; - let max = rate_pre + max_change; - (arb_established_address(), arb_rate(min, max)).prop_map( + let min = cmp::max(rate_pre - max_change, Decimal::ZERO); + let max = cmp::min(rate_pre + max_change, Decimal::ONE); + (arb_established_address(), arb_new_rate(min, max, rate_pre)).prop_map( |(validator, new_rate)| transaction::pos::CommissionChange { validator: Address::Established(validator), new_rate, From 8298afe152a007e3b62444f7056f1827b4b67884 Mon Sep 17 00:00:00 2001 From: brentstone Date: Mon, 26 Dec 2022 16:32:08 -0500 Subject: [PATCH 121/166] remove dbg statements --- wasm/wasm_source/src/tx_change_validator_commission.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/wasm/wasm_source/src/tx_change_validator_commission.rs b/wasm/wasm_source/src/tx_change_validator_commission.rs index 89feb652ea..3d30f25908 100644 --- a/wasm/wasm_source/src/tx_change_validator_commission.rs +++ b/wasm/wasm_source/src/tx_change_validator_commission.rs @@ -104,9 +104,6 @@ mod tests { .read_validator_commission_rate(&commission_change.validator)? .unwrap(); - dbg!(&commission_rates_pre); - dbg!(&commission_rates_post); - // Before pipeline, the commission rates should not change for epoch in 0..pos_params.pipeline_len { assert_eq!( From 2a6189747de469191849a3b48c11d8761fa705dc Mon Sep 17 00:00:00 2001 From: brentstone Date: Mon, 26 Dec 2022 16:34:05 -0500 Subject: [PATCH 122/166] remove `ChangeIsZero` error --- proof_of_stake/src/lib.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/proof_of_stake/src/lib.rs b/proof_of_stake/src/lib.rs index 64c7ffdff8..661533cb16 100644 --- a/proof_of_stake/src/lib.rs +++ b/proof_of_stake/src/lib.rs @@ -563,15 +563,14 @@ pub trait PosActions: PosReadOnly { } }; let params = self.read_pos_params()?; - let rate_at_pipeline = *commission_rates .get_at_offset(current_epoch, DynEpochOffset::PipelineLen, ¶ms) .expect("Could not find a rate in given epoch"); + + // Return early with no further changes if there is no rate change + // instead of returning an error if new_rate == rate_at_pipeline { - return Err(CommissionRateChangeError::ChangeIsZero( - validator.clone(), - ) - .into()); + return Ok(()); } let rate_before_pipeline = *commission_rates @@ -1018,8 +1017,6 @@ pub enum CommissionRateChangeError { NegativeRate(Decimal, Address), #[error("Rate change of {0} is too large for validator {1}")] RateChangeTooLarge(Decimal, Address), - #[error("The rate change is 0 for validator {0}")] - ChangeIsZero(Address), #[error( "There is no maximum rate change written in storage for validator {0}" )] From 61a6d5c8cb9b9701331c2355d1cf9a80afbbca0c Mon Sep 17 00:00:00 2001 From: brentstone Date: Mon, 26 Dec 2022 16:45:56 -0500 Subject: [PATCH 123/166] changelog: add #965 --- .../bug-fixes/965-fix-validator-commission-change-test.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md diff --git a/.changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md b/.changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md new file mode 100644 index 0000000000..274b48c5d1 --- /dev/null +++ b/.changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md @@ -0,0 +1,3 @@ +- Fix the commission rate change wasm test, which failed because an arbitrary + value for a new rate was allowed that could be equal to the previous rate. + ([#965](https://github.com/anoma/namada/pull/965)) \ No newline at end of file From 70c4d4f554c2a772bd23b2d5ee0c290d2ba7ac3a Mon Sep 17 00:00:00 2001 From: Awa Sun Yin <11296013+awasunyin@users.noreply.github.com> Date: Thu, 5 Jan 2023 14:19:29 +0100 Subject: [PATCH 124/166] Update README.md Updated with the info on protocol version upgrade and added discord link --- documentation/docs/src/testnets/README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/documentation/docs/src/testnets/README.md b/documentation/docs/src/testnets/README.md index 220fd4ed72..eddf461ac2 100644 --- a/documentation/docs/src/testnets/README.md +++ b/documentation/docs/src/testnets/README.md @@ -19,8 +19,11 @@ If you find a bug, please submit an issue with the `bug` [issue template](https: 5. [Becoming a validator post-genesis](./post-genesis-validator.md) ![testnet_flowchart](../images/testnet_flowchart.png) -## Testnet versions -All public testnets will be listed here: +## Latest Testnet +The Namada public testnet is permissionless, anyone can join without the authorisation of a centralised party. Expect frequent upgrades (every two weeks). +- Upgrade testnet 1: + - From date: 2nd of January 2023 + - Namada protocol version: `v0.12.2` - Namada public testnet 1: - Namada protocol version: `v0.12.0` - Tendermint version: `v0.1.4-abciplus` @@ -31,4 +34,4 @@ All public testnets will be listed here: The block explorer is currently in development. The latest version can be found at [namada.world](https://namada.world/) ## Community -For questions or feedback, feel free to post or comment on [Reddit](https://www.reddit.com/r/namada) or [Github](https://github.com/anoma/namada/issues). Don't forget to [follow Namada](https://twitter.com/namadanetwork) on Twitter for testnet relevant updates. \ No newline at end of file +For questions or feedback, feel free to post or comment on [Reddit](https://www.reddit.com/r/namada) or [Github](https://github.com/anoma/namada/issues). Don't forget to [follow Namada](https://twitter.com/namadanetwork) on Twitter for testnet relevant updates and to join [Discord](discord.gg/namada) for questions and support for validators. From 284f985f538c50cdcdc75b1a0399dcd1dec999c0 Mon Sep 17 00:00:00 2001 From: Awa Sun Yin <11296013+awasunyin@users.noreply.github.com> Date: Thu, 5 Jan 2023 14:34:27 +0100 Subject: [PATCH 125/166] Update README.md --- documentation/docs/src/testnets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/src/testnets/README.md b/documentation/docs/src/testnets/README.md index eddf461ac2..17317081ac 100644 --- a/documentation/docs/src/testnets/README.md +++ b/documentation/docs/src/testnets/README.md @@ -34,4 +34,4 @@ The Namada public testnet is permissionless, anyone can join without the authori The block explorer is currently in development. The latest version can be found at [namada.world](https://namada.world/) ## Community -For questions or feedback, feel free to post or comment on [Reddit](https://www.reddit.com/r/namada) or [Github](https://github.com/anoma/namada/issues). Don't forget to [follow Namada](https://twitter.com/namadanetwork) on Twitter for testnet relevant updates and to join [Discord](discord.gg/namada) for questions and support for validators. +For questions or feedback, feel free to post or comment on [Reddit](https://www.reddit.com/r/namada) or [Github](https://github.com/anoma/namada/issues). Don't forget to [follow Namada](https://twitter.com/namadanetwork) on Twitter for testnet relevant updates and to join [Discord](https://discord.gg/namada) for questions and support for validators. From e6fab4d364d9f894122e2c459cc842297cf0dec8 Mon Sep 17 00:00:00 2001 From: Bengt Date: Fri, 6 Jan 2023 00:39:54 +0000 Subject: [PATCH 126/166] added ibc docs and new favicon --- documentation/docs/src/SUMMARY.md | 1 + documentation/docs/src/user-guide/ibc.md | 294 +++++++++++++++++++++++ documentation/docs/theme/favicon-old.png | Bin 0 -> 222 bytes documentation/docs/theme/favicon.png | Bin 222 -> 937 bytes 4 files changed, 295 insertions(+) create mode 100644 documentation/docs/src/user-guide/ibc.md create mode 100644 documentation/docs/theme/favicon-old.png diff --git a/documentation/docs/src/SUMMARY.md b/documentation/docs/src/SUMMARY.md index 80763182b2..20134fabcb 100644 --- a/documentation/docs/src/SUMMARY.md +++ b/documentation/docs/src/SUMMARY.md @@ -24,6 +24,7 @@ - [Governance](./user-guide/ledger/governance.md) - [On-chain proposals](./user-guide/ledger/on-chain-governance.md) - [Off-chain proposals](./user-guide/ledger/off-chain-governance.md) + - [IBC](./user-guide/ibc.md) - [Testnets](./testnets/README.md) - [Environment setup](./testnets/environment-setup.md) - [Pre-genesis validator](./testnets/pre-genesis-validator.md) diff --git a/documentation/docs/src/user-guide/ibc.md b/documentation/docs/src/user-guide/ibc.md new file mode 100644 index 0000000000..84b0a47229 --- /dev/null +++ b/documentation/docs/src/user-guide/ibc.md @@ -0,0 +1,294 @@ +# Using IBC with Namada + +This document describes using the inter-blockchain communication (IBC) protocol with Namada. This documentation covers being able to create connections through IBC as well as setting up local fractal instances of Namada for testing purposes. + +> **Warning** +> +> This feature is currently in development. Expect the unexpected. + +This document will cover three essential steps for using IBC with Namada + +1. [Setup Hermes](#setup-hermes) +2. [Setup nodes for Namada instances](#setup-nodes-for-namada-instances) +3. [Transferring assets over IBC](#transferring-assets-over-IBC) + +The below is intended for those that wish to conduct IBC message transfers between two Namada chains. There is of course the cabablitiy to do this between any two IBC compatible chains (such as a cosmos chain). In this case, it is necessary to have a node of both the destination and the source chain running in order to make any package transfers. Below, we discuss first how to enable this connection between two pre-existing chains by Hermes, and second setting up 2 Namada local instances or joining two pre-existing Namada instances for this purpose. + +## Setup Hermes +Hermes is an IBC relayer to relay packets between chains(instances). We have our [Hermes supporting Namada instances](https://github.com/heliaxdev/ibc-rs/tree/yuji/v0.14.0_namada). +Before packet relay, we need the following step to configure and start Hermes. + +1. Make Hermes config file +2. Create IBC client/connection/channel between instances +3. Run Hermes + +### Make Hermes config file +One essential piece of the puzzle is to create a `config.toml` file that describes what connections will be set up that the relayer will be responsible for. + +```bash! +export HERMES_CONFIG="/config.toml" +touch $HERMES_CONFIG +``` + +If you don't specify the file path, `~/.hermes/config.toml` is read as default. + +You can find an example of the config file [here](https://hackmd.io/l6HNSqJmQt6QfkjfTmSfbw). Essentially, you change only the chain IDs, the RPC addresses, and the key names in the config file for Namada. If you don't have nodes, please set up nodes manually or through our [scripts](#setup-nodes-for-namada-instances). + +The path to the config file, which is is saved in the variable `$HERMES_CONFIG` will be useful later. + +```admonish note + + **Interpreting the toml** + + Each chain configuration is specified under the `[[chains]]` object. + + These are the pieces of this puzzle you want to keep your :eyes: on: + - `chains.id` is the name of the chain + - `chains.rpc_address` specifies the port that the channel is communicating through, and will be the argument for the `ledger_address` of Namada when interacting with the ledger (will become clearer later) + - Make sure to change the IP address to the IP address of your local machine that is running this node! + - `chains.key_name` specifies the key of the signer who signs a transaction from the relayer. The key should be generated before starting the relayer. +``` + +### Create IBC client/connection/channel between instances +Hermes CLI has commands to create them. Before the creation, a node of each instance should be running. + +#### Install Hermes +Before conducting any IBC operations, we build Heliax's Hermes fork from source. + +```bash +export COMMIT="97554eab9a30a6efdea3d97e230b827fa7ab053a" +git clone git@github.com:heliaxdev/ibc-rs.git +git checkout $COMMIT +cd ibc-rs +cargo build --release --bin hermes +export IBC_RS=$(pwd) # if needed +``` +Check the binary: +```bash +./target/release/hermes --version +``` + +````admonish note +It is recommended to now add hermes to `$PATH` such that it is callable without any pre-fixes. +For ubuntu users, this can be achieved by +```bash +cp ./target/release/hermes /usr/local/bin/ +``` +```` + +### Create IBC channel +The "create channel" command (below) creates not only the IBC channel but also the necessary IBC client connection. + +```bash +hermes -c $HERMES_CONFIG \ + create channel $CHAIN_A_ID \ + --chain-b $CHAIN_B_ID \ + --port-a transfer \ + --port-b transfer \ + --new-client-connection +``` + +```admonish note +Note that the above `CHAIN_IDs` will depend on your own setup, so do check this for yourself! +``` + +This command will ask you with the following message. You can continue with `y`. +``` +to re-use a pre-existing connection. [y/n] +``` + +When the creation has been completed, you can see the channel IDs. For example, the following text shows that a channel with ID `7` has been created on Chain A `namada-test.0a4c6786dbda39f786`, and a channel with ID `12` has been created on Chain B `namada-test.647287156defa8728c`. You will need the channel IDs for a transfer over IBC. It means that you have to specify `channel-7` as a channel ID (The prefix `channel-` is always required) for a transfer from Chain A to Chain B. Also, you have to specify `channel-12` as a channel ID for a transfer from Chain B to Chain A. +``` +Success: Channel { + ordering: Unordered, + a_side: ChannelSide { + chain: BaseChainHandle { + chain_id: ChainId { + id: "namada-test.0a4c6786dbda39f786", + version: 0, + }, + runtime_sender: Sender { .. }, + }, + client_id: ClientId( + "07-tendermint-0", + ), + connection_id: ConnectionId( + "connection-3", + ), + port_id: PortId( + "transfer", + ), + channel_id: Some( + ChannelId( + 7, + ), + ), + version: None, + }, + b_side: ChannelSide { + chain: BaseChainHandle { + chain_id: ChainId { + id: "namada-test.647287156defa8728c", + version: 0, + }, + runtime_sender: Sender { .. }, + }, + client_id: ClientId( + "07-tendermint-1", + ), + connection_id: ConnectionId( + "connection-2", + ), + port_id: PortId( + "transfer", + ), + channel_id: Some( + ChannelId( + 12, + ), + ), + version: None, + }, + connection_delay: 0ns, +} +``` + +### Run Hermes +Once you run Hermes, it monitors instances via the nodes and relays packets according to monitored events. +```bash +hermes -c $HERMES_CONFIG start +``` + +## Setup nodes for Namada instances +We need a node for each instance to be monitored by Hermes. In this document, we will set up two local nodes for two instances. But, of course, the node doesn't have to be on the same machine as Hermes. + +We will explain for two cases: +- Set up nodes to join existing Namada instances +- Set up local Namada instances for testing purposes + +Before running the following scripts, you have to build Namada and wasm. +```bash +git clone git@github.com:anoma/namada.git +cd namada +git checkout v0.12.2 +make build-release +make build-wasm-scripts +export NAMADA_DIR=$(pwd) # if needed +``` + +You can use scripts in [our Hermes branch](https://github.com/heliaxdev/ibc-rs/tree/yuji/v0.14.0_namada) to setup these nodes automatically. + +### Set up nodes to join existing Namada instances +The script `join-namada.sh` will set up two nodes for two instances, copy necessary files for Hermes, and make an account for Hermes on each ledger. Also, it will make a Hermes' config file `config_for_namada.toml` in the `ibc-rs` directory. + +The script requires the Namada directory path and chain IDs. +```bash +git clone git@github.com:heliaxdev/ibc-rs.git +git checkout $COMMIT # The branch is the same as our Hermes +cd ibc-rs +./scripts/join-namada.sh $NAMADA_DIR $CHAIN_ID_A $CHAIN_ID_B +``` + +You need to wait to sync each node with the corresponding instance. After the sync, you can create the channel and start Hermes as we explain [above](#create-ibc-channel). +```bash +# create a channel +hermes -c $HERMES_CONFIG \ + create channel $CHAIN_A_ID \ + --chain-b $CHAIN_B_ID \ + --port-a transfer \ + --port-b transfer \ + --new-client-connection + +# Run Hermes +hermes -c $HERMES_CONFIG start +``` + +Each node data and configuration files are in `${IBC_RS}/data/namada-*/.namada`. + +In order to close any ledgers setup by the script, one can run +```bash +killall namadan +``` + +### Set up local Namada instances +The script `setup-namada.sh` will set up two instances with one validator node, copy necessary files for Hermes, and make an account for Hermes on each ledger. Also, it will make a Hermes' config file `config_for_namada.toml` in the `ibc-rs` directory. +```bash +git clone git@github.com:heliaxdev/ibc-rs.git +git checkout $COMMIT # The branch is the same as our Hermes +cd ibc-rs +./scripts/setup-namada.sh $NAMADA_DIR $CHAIN_ID_A $CHAIN_ID_B +``` + +In this case, we don't have to wait for sync. You can create a channel and start Hermes immediately as we explain [above](#create-ibc-channel). You find these chain IDs of the instances in the config file `config_for_namada.toml`. One can run `grep "id" ${HERMES_CONFIG}`. +```bash +# create a channel +hermes -c $HERMES_CONFIG \ + create channel $CHAIN_A_ID \ + --chain-b $CHAIN_B_ID \ + --port-a transfer \ + --port-b transfer \ + --new-client-connection + +# Run Hermes +hermes -c $HERMES_CONFIG start +``` + +Each node data and configuration files are in `ibc-rs/data/namada-*/.namada`. + +In order to close any ledgers setup by the script, one can run +```bash +killall namadan +``` + +## Transferring assets over IBC +This will make transfers across chains by Namada CLI. This assumes that a channel has been created and Hermes is running with the proper config. + +In order to do this by Namada's `ibc-transfer` command, we will need to know the `base-dir` and `ledger-address` of each instance (and other transfer parameters). +`base-dir` is the base directory of each node. If you have used the script, the direcotry is `${IBC_RS}/data/namada-*/.namada`. +`ledger-address` is `rpc_addr` in the relevant hermes' config files. +One can run `grep "rpc_addr" ${HERMES_CONFIG}`. + + +````admonish note + **For the local node ONLY** + + To find your ledger address for Chain A, you can run the following command + ```bash + export BASE_DIR_A = "${IBC_RS}/data/namada-a/.namada" + export LEDGER_ADDRESS_A = "$(grep "rpc_address" ${BASE_DIR_A}/${CHAIN_A_ID}/setup/validator-0/.namada/${CHAIN_A_ID}/config.toml)" + ``` +```` + +And then the channel ID for this chain will depend on the order in which one created the channel. Since we have only opened one channel, the `channel-id` is `channel-0`, but as more are created, these increase by index incremented by 1. Please refer to [here](#create-ibc-channel). + +So one can go ahead and run +```bash +export CHANNEL_ID = "channel-0" +``` + +Such transfers from Chain A can be achieved by + +```bash +namadac --base-dir ${BASE_DIR_A} + ibc-transfer \ + --amount ${AMOUNT} \ + --source ${SOURCE_ALIAS} \ + --receiver ${RECEIVER_RAW_ADDRESS} \ + --token ${TOKEN_ALIAS} \ + --channel-id ${CHANNEL_ID} \ + --ledger-address ${LEDGER_ADDRESS_A} +``` +Where the above variables in `${VARIABLE}` must be substituted with appropriate values. The raw address of the receiver can be found by `namadaw --base-dir ${BASE_DIR_B} address find --alias ${RECEIVER}`. + +E.g + +```bash +namadac --base-dir ${BASE_DIR_A} + ibc-transfer \ + --amount 100 \ + --source albert \ + --receiver atest1d9khqw36g56nqwpkgezrvvejg3p5xv2z8y6nydehxprygvp5g4znj3phxfpyv3pcgcunws2x0wwa76 \ + --token nam \ + --channel-id channel-0 \ + --ledger-address 127.0.0.1:27657 +``` diff --git a/documentation/docs/theme/favicon-old.png b/documentation/docs/theme/favicon-old.png new file mode 100644 index 0000000000000000000000000000000000000000..11dfb07620650b235461cc83a25af0665d9329fe GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Gdx`!Ln7SY zPIKgHP!Mq4-*Q`FmxKF@f7?H>JiK>QM!_&<%LUg{0U{q`yB42sH(u%lwd^h>tx2;Q5_k0EUT1vXPbP0l+XkK6n9e? literal 0 HcmV?d00001 diff --git a/documentation/docs/theme/favicon.png b/documentation/docs/theme/favicon.png index 11dfb07620650b235461cc83a25af0665d9329fe..7de1b9c3d8b03e9190e800f251a8655c70ca2177 100644 GIT binary patch delta 902 zcmV;119|-30jUR&FnkBBwjqydq zcR<p zo}|Z=eJ2uW%#|U*qjenrh7u<DuT#*~*K8$3f0lT*Z z^&T^^=-dUKxPN0BC~8C{fq0BdRsFgP#JiJ0>!(2X0b7mfyR@zgT3pU{S)}n)=2H-$ z_nJwW?iQAzsrQVL0B;Jw72se1r>AkW%gfO3!`WH>y%2DB6)t|k`8T+88_v(6T7{V# zaP=EjR-jVx_c~Re`**hsjeBtbpTEH2A#Ary!3lvhEq{1+7J7eRZx41}!0s#k-FyVK z1vof>b_Z71{JD`!LHDbmQJ1KQ=I6Det1B1|!3Cfqsa7?gmzPiopb53w2*BD}jsZ1B zbgd|JmVtU5j@#P7gLODQb^!=lEy?|L*xZEY&!AGoKvPhw$&3LDz)sBEEN}swbOcHv z8|#9TV}Hq!lY*@leEa~9pTOHUFk69MANF34PeBU6?fCvM5_G$gMg!`raMID*wG1c# zM@j?Ru(bvI``VVGKbL}C*m()fhs7yK#UGxCJO;N0QTk8b)rvR${yOsY^$RM}?^VD@Tiqf`25@qEk6vxTOL9_^uBeOH0t}!SyxF z&FSy7>;w$@YCp`(#L7^oIx;v$i*>IU-)hHC$arVfDVWqv&HITHvuIr~>(gM(vq&rc zm+>2qU?N~wgk=_c&@!LlQO4wQ%z1ER$DRp8V`EZc^W_RRJ0wrgQvUevm0^L`Xrxo5 zDSvvD8$J9F8YrgAMx1`ffar@!WXMmdib4YXjWNgWR?`Xnn^9hj)~I`qa!&DOE;NqU z@PJb~1)0#wq<@NIo4FerT1QF3znJ8~aA-XNZ2$lO07*qoM6N<$g7ROopa1{> delta 182 zcmV;n07?I;2i^gYFn<7;Nklt#k_sKm#-&2kH~&!7fuAod5s;07*qoM6N<$f->t&zW@LL From 3a8d3c7baf425903eef38af02a30affe029f1f0a Mon Sep 17 00:00:00 2001 From: bengtlofgren <51077282+bengtlofgren@users.noreply.github.com> Date: Fri, 6 Jan 2023 19:43:07 +0000 Subject: [PATCH 127/166] Update documentation/docs/src/user-guide/ibc.md Co-authored-by: Christopher Goes --- documentation/docs/src/user-guide/ibc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/src/user-guide/ibc.md b/documentation/docs/src/user-guide/ibc.md index 84b0a47229..19e5deace7 100644 --- a/documentation/docs/src/user-guide/ibc.md +++ b/documentation/docs/src/user-guide/ibc.md @@ -1,6 +1,6 @@ # Using IBC with Namada -This document describes using the inter-blockchain communication (IBC) protocol with Namada. This documentation covers being able to create connections through IBC as well as setting up local fractal instances of Namada for testing purposes. +This document describes using the inter-blockchain communication (IBC) protocol with Namada. This documentation covers being able to create connections through IBC as well as setting up local instances of Namada for testing purposes. > **Warning** > From 01eb29edff75c1ddf24fc3cc1ee46ca8e811b5f1 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Tue, 10 Jan 2023 02:02:00 -0500 Subject: [PATCH 128/166] wasm: update checksums.json --- wasm/checksums.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wasm/checksums.json b/wasm/checksums.json index b13508300c..f99192440a 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,13 +1,13 @@ { - "tx_bond.wasm": "tx_bond.be9c75f96b3b4880b7934d42ee218582b6304f6326a4588d1e6ac1ea4cc61c49.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.cd861e0e82f4934be6d8382d6fff98286b4fadbc20ab826b9e817f6666021273.wasm", + "tx_bond.wasm": "tx_bond.8b1368069a74e60c214f1f5f99b2b68af69e9ba82671ad355e5006099e1a3ff9.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.f6fd5102d74a171f11f404f00198d2e24b9596eca1b2e78b6dedd22cb81f73f7.wasm", "tx_ibc.wasm": "tx_ibc.13daeb0c88abba264d3052129eda0713bcf1a71f6f69bf37ec2494d0d9119f1f.wasm", "tx_init_account.wasm": "tx_init_account.e21cfd7e96802f8e841613fb89f1571451401d002a159c5e9586855ac1374df5.wasm", "tx_init_proposal.wasm": "tx_init_proposal.b9a77bc9e416f33f1e715f25696ae41582e1b379422f7a643549884e0c73e9de.wasm", "tx_init_validator.wasm": "tx_init_validator.1e9732873861c625f239e74245f8c504a57359c06614ba40387a71811ca4a097.wasm", "tx_reveal_pk.wasm": "tx_reveal_pk.47bc922a8be5571620a647ae442a1af7d03d05d29bef95f0b32cdfe00b11fee9.wasm", "tx_transfer.wasm": "tx_transfer.bbd1ef5d9461c78f0288986de046baad77e10671addc5edaf3c68ea1ae4ecc99.wasm", - "tx_unbond.wasm": "tx_unbond.c0a690d0ad43a94294a6405bae3327f638a657446c74dc61dbb3a4d2ce488b5e.wasm", + "tx_unbond.wasm": "tx_unbond.5f33417ed604806e01cf181bbd314a91dda3cfa7b553dfd41c4ed59d10d679eb.wasm", "tx_update_vp.wasm": "tx_update_vp.ee2e9b882c4accadf4626e87d801c9ac8ea8c61ccea677e0532fc6c1ee7db6a2.wasm", "tx_vote_proposal.wasm": "tx_vote_proposal.263fd9f4cb40f283756f394d86bdea3417e9ecd0568d6582c07a5b6bd14287d6.wasm", "tx_withdraw.wasm": "tx_withdraw.6ce8faf6a32340178ddeaeb91a9b40e7f0433334e5c1f357964bf8e11d0077f1.wasm", From 122ec91c49e8140af171139b937be44eb57850a2 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Tue, 10 Jan 2023 02:06:59 -0500 Subject: [PATCH 129/166] changelog: add #973 --- .changelog/unreleased/features/973-namada-start-time.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/features/973-namada-start-time.md diff --git a/.changelog/unreleased/features/973-namada-start-time.md b/.changelog/unreleased/features/973-namada-start-time.md new file mode 100644 index 0000000000..4a43cfeb12 --- /dev/null +++ b/.changelog/unreleased/features/973-namada-start-time.md @@ -0,0 +1,2 @@ +- Add a --time argument to the node to specify the time the node should start. + ([#973](https://github.com/anoma/namada/pull/973)) \ No newline at end of file From fc817189f34fe54c5ce0d11678c64c9781a3c3c7 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Tue, 10 Jan 2023 02:08:00 -0500 Subject: [PATCH 130/166] changelog: add #974 --- .changelog/unreleased/features/974-resize-block.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/features/974-resize-block.md diff --git a/.changelog/unreleased/features/974-resize-block.md b/.changelog/unreleased/features/974-resize-block.md new file mode 100644 index 0000000000..71d6ef5b49 --- /dev/null +++ b/.changelog/unreleased/features/974-resize-block.md @@ -0,0 +1,2 @@ +- Reduce the block size for transactions to 5 MiB. + ([#974](https://github.com/anoma/namada/pull/974)) \ No newline at end of file From 704b175c376f50e88e152430877710204d3978b5 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Tue, 10 Jan 2023 02:12:54 -0500 Subject: [PATCH 131/166] changelog: add #926 --- .../unreleased/improvements/926-storage-keys-procmacro.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/926-storage-keys-procmacro.md diff --git a/.changelog/unreleased/improvements/926-storage-keys-procmacro.md b/.changelog/unreleased/improvements/926-storage-keys-procmacro.md new file mode 100644 index 0000000000..2363cb08f2 --- /dev/null +++ b/.changelog/unreleased/improvements/926-storage-keys-procmacro.md @@ -0,0 +1,2 @@ +- Add a macro to derive storage keys from a struct. + ([#926](https://github.com/anoma/namada/pull/926)) \ No newline at end of file From 557320c268efb73d5138dec276da3016de32a84d Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Fri, 16 Dec 2022 10:15:47 +0000 Subject: [PATCH 132/166] Fix #882 --- core/src/ledger/parameters/storage.rs | 28 +++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/core/src/ledger/parameters/storage.rs b/core/src/ledger/parameters/storage.rs index b8dc84fd76..4ea29d609a 100644 --- a/core/src/ledger/parameters/storage.rs +++ b/core/src/ledger/parameters/storage.rs @@ -13,6 +13,21 @@ const POS_GAIN_D_KEY: &str = "pos_gain_d"; const STAKED_RATIO_KEY: &str = "staked_ratio_key"; const POS_INFLATION_AMOUNT_KEY: &str = "pos_inflation_amount_key"; +// keep these keys in sync with the defs above; +// make sure to store them in sorted order! +const ALL_KEYS: &[&str] = &[ + EPOCH_DURATION_KEY, + EPOCHS_PER_YEAR_KEY, + IMPLICIT_VP_KEY, + MAX_EXPECTED_TIME_PER_BLOCK_KEY, + POS_GAIN_D_KEY, + POS_GAIN_P_KEY, + POS_INFLATION_AMOUNT_KEY, + STAKED_RATIO_KEY, + TX_WHITELIST_KEY, + VP_WHITELIST_KEY, +]; + /// Returns if the key is a parameter key. pub fn is_parameter_key(key: &Key) -> bool { matches!(&key.segments[0], DbKeySeg::AddressSeg(addr) if addr == &ADDRESS) @@ -20,10 +35,15 @@ pub fn is_parameter_key(key: &Key) -> bool { /// Returns if the key is a protocol parameter key. pub fn is_protocol_parameter_key(key: &Key) -> bool { - is_epoch_duration_storage_key(key) - || is_max_expected_time_per_block_key(key) - || is_tx_whitelist_key(key) - || is_vp_whitelist_key(key) + let segment = match &key.segments[..] { + [DbKeySeg::AddressSeg(addr), DbKeySeg::StringSeg(segment)] + if addr == &ADDRESS => + { + segment.as_str() + } + _ => return false, + }; + ALL_KEYS.binary_search(&segment).is_ok() } /// Returns if the key is an epoch storage key. From afcedabec9e797ec02d435cff4bc5324d593df52 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Mon, 19 Dec 2022 11:13:56 +0000 Subject: [PATCH 133/166] Define Keys struct with all ledger param key types --- core/src/ledger/parameters/storage.rs | 149 ++++++++++++++++++-------- 1 file changed, 103 insertions(+), 46 deletions(-) diff --git a/core/src/ledger/parameters/storage.rs b/core/src/ledger/parameters/storage.rs index 4ea29d609a..0a317d2cdc 100644 --- a/core/src/ledger/parameters/storage.rs +++ b/core/src/ledger/parameters/storage.rs @@ -1,32 +1,73 @@ //! Parameters storage + use super::ADDRESS; use crate::types::storage::{DbKeySeg, Key}; -const EPOCH_DURATION_KEY: &str = "epoch_duration"; -const VP_WHITELIST_KEY: &str = "vp_whitelist"; -const TX_WHITELIST_KEY: &str = "tx_whitelist"; -const MAX_EXPECTED_TIME_PER_BLOCK_KEY: &str = "max_expected_time_per_block"; -const IMPLICIT_VP_KEY: &str = "implicit_vp"; -const EPOCHS_PER_YEAR_KEY: &str = "epochs_per_year"; -const POS_GAIN_P_KEY: &str = "pos_gain_p"; -const POS_GAIN_D_KEY: &str = "pos_gain_d"; -const STAKED_RATIO_KEY: &str = "staked_ratio_key"; -const POS_INFLATION_AMOUNT_KEY: &str = "pos_inflation_amount_key"; - -// keep these keys in sync with the defs above; -// make sure to store them in sorted order! -const ALL_KEYS: &[&str] = &[ - EPOCH_DURATION_KEY, - EPOCHS_PER_YEAR_KEY, - IMPLICIT_VP_KEY, - MAX_EXPECTED_TIME_PER_BLOCK_KEY, - POS_GAIN_D_KEY, - POS_GAIN_P_KEY, - POS_INFLATION_AMOUNT_KEY, - STAKED_RATIO_KEY, - TX_WHITELIST_KEY, - VP_WHITELIST_KEY, -]; +/// Storage keys for ledger parameters. +struct Keys { + epoch_duration: &'static str, + epochs_per_year: &'static str, + implicit_vp: &'static str, + max_expected_time_per_block: &'static str, + pos_gain_d: &'static str, + pos_gain_p: &'static str, + pos_inflation_amount: &'static str, + staked_ratio: &'static str, + tx_whitelist: &'static str, + vp_whitelist: &'static str, +} + +impl Keys { + /// All ledger parameter key types. + const ALL: &[&'static str] = { + // keep this pattern here to remind us to + // include all fields of `Keys` in the slice + // below (e.g. if we get a compiler error, we + // probably need to add a missing field to the + // slice) + let Keys { + epoch_duration, + epochs_per_year, + implicit_vp, + max_expected_time_per_block, + pos_gain_d, + pos_gain_p, + pos_inflation_amount, + staked_ratio, + tx_whitelist, + vp_whitelist, + } = Keys::VALUES; + + // additionally, the slice itself must be sorted + // in ascending order + &[ + epoch_duration, + epochs_per_year, + implicit_vp, + max_expected_time_per_block, + pos_gain_d, + pos_gain_p, + pos_inflation_amount, + staked_ratio, + tx_whitelist, + vp_whitelist, + ] + }; + /// This constant is contains the stringified version of all + /// the key types for ledger parameters. + const VALUES: Keys = Keys { + epoch_duration: "epoch_duration", + epochs_per_year: "epochs_per_year", + implicit_vp: "implicit_vp", + max_expected_time_per_block: "max_expected_time_per_block", + pos_gain_d: "pos_gain_d", + pos_gain_p: "pos_gain_p", + pos_inflation_amount: "pos_inflation_amount", + staked_ratio: "staked_ratio", + tx_whitelist: "tx_whitelist", + vp_whitelist: "vp_whitelist", + }; +} /// Returns if the key is a parameter key. pub fn is_parameter_key(key: &Key) -> bool { @@ -43,7 +84,7 @@ pub fn is_protocol_parameter_key(key: &Key) -> bool { } _ => return false, }; - ALL_KEYS.binary_search(&segment).is_ok() + Keys::ALL.binary_search(&segment).is_ok() } /// Returns if the key is an epoch storage key. @@ -51,7 +92,7 @@ pub fn is_epoch_duration_storage_key(key: &Key) -> bool { matches!(&key.segments[..], [ DbKeySeg::AddressSeg(addr), DbKeySeg::StringSeg(epoch_duration), - ] if addr == &ADDRESS && epoch_duration == EPOCH_DURATION_KEY) + ] if addr == &ADDRESS && epoch_duration == Keys::VALUES.epoch_duration) } /// Returns if the key is the max_expected_time_per_block key. @@ -59,7 +100,7 @@ pub fn is_max_expected_time_per_block_key(key: &Key) -> bool { matches!(&key.segments[..], [ DbKeySeg::AddressSeg(addr), DbKeySeg::StringSeg(max_expected_time_per_block), - ] if addr == &ADDRESS && max_expected_time_per_block == MAX_EXPECTED_TIME_PER_BLOCK_KEY) + ] if addr == &ADDRESS && max_expected_time_per_block == Keys::VALUES.max_expected_time_per_block) } /// Returns if the key is the tx_whitelist key. @@ -67,7 +108,7 @@ pub fn is_tx_whitelist_key(key: &Key) -> bool { matches!(&key.segments[..], [ DbKeySeg::AddressSeg(addr), DbKeySeg::StringSeg(tx_whitelist), - ] if addr == &ADDRESS && tx_whitelist == TX_WHITELIST_KEY) + ] if addr == &ADDRESS && tx_whitelist == Keys::VALUES.tx_whitelist) } /// Returns if the key is the vp_whitelist key. @@ -75,7 +116,7 @@ pub fn is_vp_whitelist_key(key: &Key) -> bool { matches!(&key.segments[..], [ DbKeySeg::AddressSeg(addr), DbKeySeg::StringSeg(vp_whitelist), - ] if addr == &ADDRESS && vp_whitelist == VP_WHITELIST_KEY) + ] if addr == &ADDRESS && vp_whitelist == Keys::VALUES.vp_whitelist) } /// Returns if the key is the implicit VP key. @@ -83,7 +124,7 @@ pub fn is_implicit_vp_key(key: &Key) -> bool { matches!(&key.segments[..], [ DbKeySeg::AddressSeg(addr), DbKeySeg::StringSeg(sub_key), - ] if addr == &ADDRESS && sub_key == IMPLICIT_VP_KEY) + ] if addr == &ADDRESS && sub_key == Keys::VALUES.implicit_vp) } /// Returns if the key is the epoch_per_year key. @@ -91,7 +132,7 @@ pub fn is_epochs_per_year_key(key: &Key) -> bool { matches!(&key.segments[..], [ DbKeySeg::AddressSeg(addr), DbKeySeg::StringSeg(epochs_per_year), - ] if addr == &ADDRESS && epochs_per_year == EPOCHS_PER_YEAR_KEY) + ] if addr == &ADDRESS && epochs_per_year == Keys::VALUES.epochs_per_year) } /// Returns if the key is the pos_gain_p key. @@ -99,7 +140,7 @@ pub fn is_pos_gain_p_key(key: &Key) -> bool { matches!(&key.segments[..], [ DbKeySeg::AddressSeg(addr), DbKeySeg::StringSeg(pos_gain_p), - ] if addr == &ADDRESS && pos_gain_p == POS_GAIN_P_KEY) + ] if addr == &ADDRESS && pos_gain_p == Keys::VALUES.pos_gain_p) } /// Returns if the key is the pos_gain_d key. @@ -107,7 +148,7 @@ pub fn is_pos_gain_d_key(key: &Key) -> bool { matches!(&key.segments[..], [ DbKeySeg::AddressSeg(addr), DbKeySeg::StringSeg(pos_gain_d), - ] if addr == &ADDRESS && pos_gain_d == POS_GAIN_D_KEY) + ] if addr == &ADDRESS && pos_gain_d == Keys::VALUES.pos_gain_d) } /// Returns if the key is the staked ratio key. @@ -115,7 +156,7 @@ pub fn is_staked_ratio_key(key: &Key) -> bool { matches!(&key.segments[..], [ DbKeySeg::AddressSeg(addr), DbKeySeg::StringSeg(staked_ratio), - ] if addr == &ADDRESS && staked_ratio == STAKED_RATIO_KEY) + ] if addr == &ADDRESS && staked_ratio == Keys::VALUES.staked_ratio) } /// Returns if the key is the PoS reward rate key. @@ -123,7 +164,7 @@ pub fn is_pos_inflation_amount_key(key: &Key) -> bool { matches!(&key.segments[..], [ DbKeySeg::AddressSeg(addr), DbKeySeg::StringSeg(pos_inflation_amount), - ] if addr == &ADDRESS && pos_inflation_amount == POS_INFLATION_AMOUNT_KEY) + ] if addr == &ADDRESS && pos_inflation_amount == Keys::VALUES.pos_inflation_amount) } /// Storage key used for epoch parameter. @@ -131,7 +172,7 @@ pub fn get_epoch_duration_storage_key() -> Key { Key { segments: vec![ DbKeySeg::AddressSeg(ADDRESS), - DbKeySeg::StringSeg(EPOCH_DURATION_KEY.to_string()), + DbKeySeg::StringSeg(Keys::VALUES.epoch_duration.to_string()), ], } } @@ -141,7 +182,7 @@ pub fn get_vp_whitelist_storage_key() -> Key { Key { segments: vec![ DbKeySeg::AddressSeg(ADDRESS), - DbKeySeg::StringSeg(VP_WHITELIST_KEY.to_string()), + DbKeySeg::StringSeg(Keys::VALUES.vp_whitelist.to_string()), ], } } @@ -151,7 +192,7 @@ pub fn get_tx_whitelist_storage_key() -> Key { Key { segments: vec![ DbKeySeg::AddressSeg(ADDRESS), - DbKeySeg::StringSeg(TX_WHITELIST_KEY.to_string()), + DbKeySeg::StringSeg(Keys::VALUES.tx_whitelist.to_string()), ], } } @@ -161,7 +202,9 @@ pub fn get_max_expected_time_per_block_key() -> Key { Key { segments: vec![ DbKeySeg::AddressSeg(ADDRESS), - DbKeySeg::StringSeg(MAX_EXPECTED_TIME_PER_BLOCK_KEY.to_string()), + DbKeySeg::StringSeg( + Keys::VALUES.max_expected_time_per_block.to_string(), + ), ], } } @@ -171,7 +214,7 @@ pub fn get_implicit_vp_key() -> Key { Key { segments: vec![ DbKeySeg::AddressSeg(ADDRESS), - DbKeySeg::StringSeg(IMPLICIT_VP_KEY.to_string()), + DbKeySeg::StringSeg(Keys::VALUES.implicit_vp.to_string()), ], } } @@ -181,7 +224,7 @@ pub fn get_epochs_per_year_key() -> Key { Key { segments: vec![ DbKeySeg::AddressSeg(ADDRESS), - DbKeySeg::StringSeg(EPOCHS_PER_YEAR_KEY.to_string()), + DbKeySeg::StringSeg(Keys::VALUES.epochs_per_year.to_string()), ], } } @@ -191,7 +234,7 @@ pub fn get_pos_gain_p_key() -> Key { Key { segments: vec![ DbKeySeg::AddressSeg(ADDRESS), - DbKeySeg::StringSeg(POS_GAIN_P_KEY.to_string()), + DbKeySeg::StringSeg(Keys::VALUES.pos_gain_p.to_string()), ], } } @@ -201,7 +244,7 @@ pub fn get_pos_gain_d_key() -> Key { Key { segments: vec![ DbKeySeg::AddressSeg(ADDRESS), - DbKeySeg::StringSeg(POS_GAIN_D_KEY.to_string()), + DbKeySeg::StringSeg(Keys::VALUES.pos_gain_d.to_string()), ], } } @@ -211,7 +254,7 @@ pub fn get_staked_ratio_key() -> Key { Key { segments: vec![ DbKeySeg::AddressSeg(ADDRESS), - DbKeySeg::StringSeg(STAKED_RATIO_KEY.to_string()), + DbKeySeg::StringSeg(Keys::VALUES.staked_ratio.to_string()), ], } } @@ -221,7 +264,21 @@ pub fn get_pos_inflation_amount_key() -> Key { Key { segments: vec![ DbKeySeg::AddressSeg(ADDRESS), - DbKeySeg::StringSeg(POS_INFLATION_AMOUNT_KEY.to_string()), + DbKeySeg::StringSeg(Keys::VALUES.pos_inflation_amount.to_string()), ], } } + +#[cfg(test)] +mod tests { + use super::*; + + /// Check if [`Keys::ALL`] is sorted. + /// + /// This is required for binary searching over this slice of data + /// to work as intended. + #[test] + fn test_keys_slice_is_sorted() { + itertools::assert_equal(itertools::sorted(Keys::ALL), Keys::ALL) + } +} From 92b05f0e2214304b567b9d0ba276101fab9630a2 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Mon, 19 Dec 2022 15:12:09 +0000 Subject: [PATCH 134/166] Update Cargo deps --- Cargo.lock | 1 + core/Cargo.toml | 1 + wasm/Cargo.lock | 1 + wasm_for_tests/wasm_source/Cargo.lock | 2 ++ 4 files changed, 5 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 60883727ba..8c61cd3b87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3803,6 +3803,7 @@ dependencies = [ "itertools", "libsecp256k1", "masp_primitives", + "namada_macros", "pretty_assertions", "proptest", "prost", diff --git a/core/Cargo.toml b/core/Cargo.toml index 7754310669..ac969fb7d6 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -52,6 +52,7 @@ testing = [ ] [dependencies] +namada_macros = {path = "../macros"} ark-bls12-381 = {version = "0.3"} ark-ec = {version = "0.3", optional = true} ark-serialize = {version = "0.3"} diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index a3f84ae2e1..8c7fa2a2ff 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -2519,6 +2519,7 @@ dependencies = [ "itertools", "libsecp256k1", "masp_primitives", + "namada_macros", "proptest", "prost", "prost-types", diff --git a/wasm_for_tests/wasm_source/Cargo.lock b/wasm_for_tests/wasm_source/Cargo.lock index 1abb89a73c..c38df3f4ce 100644 --- a/wasm_for_tests/wasm_source/Cargo.lock +++ b/wasm_for_tests/wasm_source/Cargo.lock @@ -2519,6 +2519,7 @@ dependencies = [ "itertools", "libsecp256k1", "masp_primitives", + "namada_macros", "proptest", "prost", "prost-types", @@ -2543,6 +2544,7 @@ dependencies = [ name = "namada_macros" version = "0.12.0" dependencies = [ + "proc-macro2", "quote", "syn", ] From 8fd279c44eff430440618cfc7842fa21eccdd1f5 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Mon, 19 Dec 2022 15:17:58 +0000 Subject: [PATCH 135/166] Remove boilerplate code in favor of StorageKeys macro --- core/src/ledger/parameters/storage.rs | 69 ++------------------------- 1 file changed, 3 insertions(+), 66 deletions(-) diff --git a/core/src/ledger/parameters/storage.rs b/core/src/ledger/parameters/storage.rs index 0a317d2cdc..9af08defab 100644 --- a/core/src/ledger/parameters/storage.rs +++ b/core/src/ledger/parameters/storage.rs @@ -1,9 +1,12 @@ //! Parameters storage +use namada_macros::StorageKeys; + use super::ADDRESS; use crate::types::storage::{DbKeySeg, Key}; /// Storage keys for ledger parameters. +#[derive(StorageKeys)] struct Keys { epoch_duration: &'static str, epochs_per_year: &'static str, @@ -17,58 +20,6 @@ struct Keys { vp_whitelist: &'static str, } -impl Keys { - /// All ledger parameter key types. - const ALL: &[&'static str] = { - // keep this pattern here to remind us to - // include all fields of `Keys` in the slice - // below (e.g. if we get a compiler error, we - // probably need to add a missing field to the - // slice) - let Keys { - epoch_duration, - epochs_per_year, - implicit_vp, - max_expected_time_per_block, - pos_gain_d, - pos_gain_p, - pos_inflation_amount, - staked_ratio, - tx_whitelist, - vp_whitelist, - } = Keys::VALUES; - - // additionally, the slice itself must be sorted - // in ascending order - &[ - epoch_duration, - epochs_per_year, - implicit_vp, - max_expected_time_per_block, - pos_gain_d, - pos_gain_p, - pos_inflation_amount, - staked_ratio, - tx_whitelist, - vp_whitelist, - ] - }; - /// This constant is contains the stringified version of all - /// the key types for ledger parameters. - const VALUES: Keys = Keys { - epoch_duration: "epoch_duration", - epochs_per_year: "epochs_per_year", - implicit_vp: "implicit_vp", - max_expected_time_per_block: "max_expected_time_per_block", - pos_gain_d: "pos_gain_d", - pos_gain_p: "pos_gain_p", - pos_inflation_amount: "pos_inflation_amount", - staked_ratio: "staked_ratio", - tx_whitelist: "tx_whitelist", - vp_whitelist: "vp_whitelist", - }; -} - /// Returns if the key is a parameter key. pub fn is_parameter_key(key: &Key) -> bool { matches!(&key.segments[0], DbKeySeg::AddressSeg(addr) if addr == &ADDRESS) @@ -268,17 +219,3 @@ pub fn get_pos_inflation_amount_key() -> Key { ], } } - -#[cfg(test)] -mod tests { - use super::*; - - /// Check if [`Keys::ALL`] is sorted. - /// - /// This is required for binary searching over this slice of data - /// to work as intended. - #[test] - fn test_keys_slice_is_sorted() { - itertools::assert_equal(itertools::sorted(Keys::ALL), Keys::ALL) - } -} From 9a8c84eb2d59e7a1b4f7a5ec6a1244aac3ad0b5d Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Wed, 21 Dec 2022 13:37:25 -0500 Subject: [PATCH 136/166] wasm: update checksums.json --- wasm/checksums.json | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/wasm/checksums.json b/wasm/checksums.json index 347c7096aa..5fd9a5b6e6 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,20 +1,20 @@ { - "tx_bond.wasm": "tx_bond.1b720ddefc9b6e0f37145ab041363426cc0e0d82f2fa33e71063ca61efe2389e.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.f6fd5102d74a171f11f404f00198d2e24b9596eca1b2e78b6dedd22cb81f73f7.wasm", - "tx_ibc.wasm": "tx_ibc.f261d127df2cb05489ad2655fcc6d0d8e7378789226ee27f0251ae90adfc1b0a.wasm", - "tx_init_account.wasm": "tx_init_account.e21cfd7e96802f8e841613fb89f1571451401d002a159c5e9586855ac1374df5.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.211265350906ad7aef3aca30d6ef463d065b738707accd0acaa19992977bfabe.wasm", - "tx_init_validator.wasm": "tx_init_validator.eac9858c4f96bbefd120e3ebe0489e1700a83e8a22d778d5aa2b14ab0627f172.wasm", - "tx_reveal_pk.wasm": "tx_reveal_pk.47bc922a8be5571620a647ae442a1af7d03d05d29bef95f0b32cdfe00b11fee9.wasm", - "tx_transfer.wasm": "tx_transfer.5b95e6f1f6b2d4b0ec6f07ac1ec66089374ece2e4a6c5bdb32297985670a2ab0.wasm", - "tx_unbond.wasm": "tx_unbond.d943090852fee7e2f4f72ac3981e0181003bc5da0e46bec786a136298974e6fa.wasm", - "tx_update_vp.wasm": "tx_update_vp.ee2e9b882c4accadf4626e87d801c9ac8ea8c61ccea677e0532fc6c1ee7db6a2.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.263fd9f4cb40f283756f394d86bdea3417e9ecd0568d6582c07a5b6bd14287d6.wasm", - "tx_withdraw.wasm": "tx_withdraw.b9b8623217202de2cb2c3941f740f6acd8558eaa05406efc60ee471c212aa513.wasm", - "vp_implicit.wasm": "vp_implicit.6c221c5210973b8d39dae73378cb8291ffebb9fb99e790f89290a1b51eb6a690.wasm", - "vp_masp.wasm": "vp_masp.16516aeafa4c2c814cf3a4289b7f924d2551966f98b9ce136fbae361aba2a73c.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.e893d1f02ec8b3668a58ab69f9dd676ccb18d0cc96d3b5c9c789714552ea715e.wasm", - "vp_token.wasm": "vp_token.bfeddd3c5954174e95064f753cb743d84659f05910cbcb31a6d8b23769b59638.wasm", - "vp_user.wasm": "vp_user.40087a1e14bdafb4429427f47c5c7a0a247433d4f72927f2ec5906119192c900.wasm", - "vp_validator.wasm": "vp_validator.3f219ebb7f3f058f6681fe3d461d6296ab1d21d92ae1578ad421b272789f451e.wasm" + "tx_bond.wasm": "tx_bond.9f81e4e7bd4299360eb7f2fa2ae91323b338b8a5aa703153514b8e7356b88ff7.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.06a8fce9c3be6ab30fdaa02adb4ed1dc71f351b35dcc97c7065aae538a9689d6.wasm", + "tx_ibc.wasm": "tx_ibc.b52231fab5cc94295e2f792638d02b91b42995a8c8c8e3ec3f07922238acebbc.wasm", + "tx_init_account.wasm": "tx_init_account.20ed7f181769c015ca8422323dd65d306f7b5538cb90c65167cba7bf835260dc.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.7db93b827dc290e3cfab4f76472bfe9dbc9dec1c571fb15018f8572e071e1f3f.wasm", + "tx_init_validator.wasm": "tx_init_validator.eaab84b4011df885a2863e8588f1065a0e8161a2dbbf8b6fcc2c1db7e89b224a.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.90c1fb51c0478c7408ed798fc349f272630068a249b670c428dd3fe17fa71acf.wasm", + "tx_transfer.wasm": "tx_transfer.c77a21c95d3fbc02c4fd1f5dbe08a4be8c7a008f8dfc5bccf5712583f4ecf192.wasm", + "tx_unbond.wasm": "tx_unbond.9b88041a341a75ad625fa2f332e48e83f199a3b66e29fb01cbf691bbefefe5da.wasm", + "tx_update_vp.wasm": "tx_update_vp.173c2e833fad6e3926dc86dd7dd900dc6b399d68dabde893520e4d736f91b713.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.31d3c0de38e2fd72f2777a53e3fcbdeb5536e1aff19cd986cb3c0b2e2f66a714.wasm", + "tx_withdraw.wasm": "tx_withdraw.5a070f75bd8c114eb10378b5aab515d9afc0abe2d7644df9ffd59c59c4a9f5e9.wasm", + "vp_implicit.wasm": "vp_implicit.c5875ac39d20b27b1cfede5c177e39fd95415ccabc8437488b17776e4deded29.wasm", + "vp_masp.wasm": "vp_masp.aa2164bcba9e9009c52cbf9cad69cc46758dfbc21a07c19cd5d2ce335bd82e99.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.de73f663e14ed775ce2095d885e840a61a345bedc7f1ef21c49219271da1540f.wasm", + "vp_token.wasm": "vp_token.4b1c5b6a93f2c1fb557bad5b383249db4fb660601c4f9ffe033b57d96f88294e.wasm", + "vp_user.wasm": "vp_user.52f0f4bcc857d07ca3fa48da30c7260880bd21472cef2f04291fabfa1b6feba3.wasm", + "vp_validator.wasm": "vp_validator.f9f53319402d86dc4d85a693a3c554797a640043bbeea5d16ad29e3550fe4f0f.wasm" } \ No newline at end of file From 5dd1273e2b247e8ac23485e5270bc7d588d845b2 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Tue, 3 Jan 2023 09:30:22 +0000 Subject: [PATCH 137/166] Fix consensus params config for ABCI++ --- apps/src/lib/node/ledger/tendermint_node.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/src/lib/node/ledger/tendermint_node.rs b/apps/src/lib/node/ledger/tendermint_node.rs index da43b0dbc3..b3fdad5dff 100644 --- a/apps/src/lib/node/ledger/tendermint_node.rs +++ b/apps/src/lib/node/ledger/tendermint_node.rs @@ -380,7 +380,7 @@ async fn write_tm_genesis( genesis.genesis_time = genesis_time .try_into() .expect("Couldn't convert DateTimeUtc to Tendermint Time"); - genesis.consensus_params.block = Some(block::Size { + let size = block::Size { // maximum size of a serialized Tendermint block // cannot go over 100 MiB max_bytes: (100 << 20) - 1, /* unsure if we are dealing with an open @@ -389,7 +389,10 @@ async fn write_tm_genesis( // gas is metered app-side, so we disable it // at the Tendermint level max_gas: -1, - }); + }; + #[cfg(not(feature = "abcipp"))] + let size = Some(size); + genesis.consensus_params.block = size; #[cfg(feature = "abcipp")] { genesis.consensus_params.timeout.commit = From ee159ff037236639616f51a12ca5c26f55c24c3c Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Tue, 10 Jan 2023 03:02:15 -0500 Subject: [PATCH 138/166] wasm: update checksums.json --- wasm/checksums.json | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/wasm/checksums.json b/wasm/checksums.json index 28920cb703..1846982242 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,20 +1,20 @@ { - "tx_bond.wasm": "tx_bond.ca30060af7fd7e9a8573c6ee157dccc1e2f3612383716d6bb2ca0b06026f1856.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.7d09576a72068734b8e259df35ce98fabe98db990c337588793a616aa095d24f.wasm", - "tx_ibc.wasm": "tx_ibc.92813d74be4f538b7599236f948498a6f41248f9470cce1410245460f968509b.wasm", - "tx_init_account.wasm": "tx_init_account.9f01fbd633bf6197cec25c1459706e0a9eeb209f02770bebf60b58668f296449.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.61e6a2dcdcbb21e5b75fd222d41bacb8cce8079ee59343c0d6121cf2e979a192.wasm", - "tx_init_validator.wasm": "tx_init_validator.0e467208eedbc236ff899abe2afdd3d4b7ceae5bd2f74a6a884d8de68d77867f.wasm", - "tx_reveal_pk.wasm": "tx_reveal_pk.05dfde69e33f0833fc25ad653066da73ef04a2b2f7894ba9fa509d2dd759ae8b.wasm", - "tx_transfer.wasm": "tx_transfer.67251510b104fc2485fe15c02bea2adb53d5b48b83fb04c19eeceba99d0b3d8c.wasm", - "tx_unbond.wasm": "tx_unbond.59758396baa9c88432610a3912fa98060f07430fc182736eba7bfb1d53f4b71d.wasm", - "tx_update_vp.wasm": "tx_update_vp.ee2e9b882c4accadf4626e87d801c9ac8ea8c61ccea677e0532fc6c1ee7db6a2.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.7764e840c0208e33c1d36248d90bbac1b46b3895da856f3b43023e4514452f7f.wasm", - "tx_withdraw.wasm": "tx_withdraw.b12de7e85658ccf62cf768b4453cfb0874a69b2a44cc6700bfa6d2051cc76951.wasm", - "vp_implicit.wasm": "vp_implicit.6ed791b49045ec27261e443b136890a82503b3647eca8e1e9c41c5fa9718b963.wasm", - "vp_masp.wasm": "vp_masp.55b19f9f592ed699af841905530e4b753117203afb4444c9add61ea10bda8d10.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.044176fd93e4158f1e0c3a872bcd5a9a5fd6c25cff9b1e0055f9b6ace6a54870.wasm", - "vp_token.wasm": "vp_token.31036edb5bc48f4c9d6915486e61e5c4aadc1e8d8602d658b27f1789b2697e35.wasm", - "vp_user.wasm": "vp_user.675c2a29d5e5383a6d465bd88dd9a4586f4a2821db2f13fd2662963ac3906527.wasm", - "vp_validator.wasm": "vp_validator.cdbd8e31bffe2911e7b4a89f4aad408a8cf7a103b1463acdd932f680f16641d3.wasm" + "tx_bond.wasm": "tx_bond.aff33e0cd2d15ed158913c9068bada33e06b0aae2026f20025e2a1118664f356.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.319b612338b4cbcd1810f4b78011c792087681ab2ebf493f9c721754569e7fe4.wasm", + "tx_ibc.wasm": "tx_ibc.d06b65bf23c77d59803097d441edb9ba018a1f5558c5219477079fd8d5f846d2.wasm", + "tx_init_account.wasm": "tx_init_account.a6d0e3bf09939f9289a483c2de97a76f1daa932bf3a88a2b984e5a28e445f85e.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.84ddc2f8b7b1bd137f2a653b31d9d48bec624c1ab4e1f92cff55701ce287f690.wasm", + "tx_init_validator.wasm": "tx_init_validator.28033f1e8975cc80675a7b73249f09633fdf869ecabc632a3c7e0b4c5a01438a.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.047bfa1d78d6ee733ac81afc903ceef2f0de1413e078ff02c351d287141a388a.wasm", + "tx_transfer.wasm": "tx_transfer.063748c6eecdc847d576f9750cca0d445e801f5477cf8f325e0de2d8721dd038.wasm", + "tx_unbond.wasm": "tx_unbond.1edbf0e245b7e4f03c21a2f52ed0c48e29502bc0728a77524c824565aea20d3f.wasm", + "tx_update_vp.wasm": "tx_update_vp.1f380efc5ddc9cc994ad34c7614c95dc405ef3d7ff5f4c4b687258a47d7e4eb1.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.06babee1f8165594c5e6b936d4303bf205b85735087aed123974a010fabc549e.wasm", + "tx_withdraw.wasm": "tx_withdraw.98bcf2f789cf570895c1f8b5855ccd631cc99c2538dcba28990c167fc38b830d.wasm", + "vp_implicit.wasm": "vp_implicit.25365cb05966cb224dbd558007dc847a0deb8dee285b9da17677808c63db1813.wasm", + "vp_masp.wasm": "vp_masp.93392d675d3a334871b8483e0d6ee4c17570f378546786dfa6dc2eecf007697c.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.8e01776b3b3f39f4872f0b0325ae0cb94fca82b25e4698ec5745869a6fa06b52.wasm", + "vp_token.wasm": "vp_token.c20c7179024cf277876cf19756340ca0ff10fd1ef805b3283ef2a5a983e21569.wasm", + "vp_user.wasm": "vp_user.722ddd67f64d714fbb3e51fe8e5194c3ba56fb73b25832da8d3b3dcddb5efa75.wasm", + "vp_validator.wasm": "vp_validator.740e2aaa46a1b0a270b4f6a9570b6a1affb989790d1f1eb771b88b86429d02e1.wasm" } \ No newline at end of file From 80292e64ff95df9f257475da5d975aa56762b891 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Tue, 10 Jan 2023 02:53:35 -0500 Subject: [PATCH 139/166] changelog: add #975 --- .changelog/unreleased/improvements/975-max-block-size.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/975-max-block-size.md diff --git a/.changelog/unreleased/improvements/975-max-block-size.md b/.changelog/unreleased/improvements/975-max-block-size.md new file mode 100644 index 0000000000..01fc123448 --- /dev/null +++ b/.changelog/unreleased/improvements/975-max-block-size.md @@ -0,0 +1,2 @@ +- Add a max_proposal_bytes parameter to the ledger. + ([#975](https://github.com/anoma/namada/pull/975)) \ No newline at end of file From bfb8ae8eff856d505982b5cecc669ca24f1e1e11 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Tue, 10 Jan 2023 03:04:31 -0500 Subject: [PATCH 140/166] changelog: add #903 --- .../unreleased/improvements/903-fix-ledger-params-match.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/903-fix-ledger-params-match.md diff --git a/.changelog/unreleased/improvements/903-fix-ledger-params-match.md b/.changelog/unreleased/improvements/903-fix-ledger-params-match.md new file mode 100644 index 0000000000..f746f084dc --- /dev/null +++ b/.changelog/unreleased/improvements/903-fix-ledger-params-match.md @@ -0,0 +1,2 @@ +- Binary search ledger storage keys to match faster. + ([#903](https://github.com/anoma/namada/pull/903)) \ No newline at end of file From 535e9ab04ba3660b58d8030ba935e970a8a66525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Wed, 28 Dec 2022 13:41:07 +0100 Subject: [PATCH 141/166] re-export `namada` from `namada_tests` for `namada_core` dev-deps --- Cargo.lock | 1 + core/Cargo.toml | 4 +++- tests/src/lib.rs | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 56f159760d..1bbdf7b3c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3804,6 +3804,7 @@ dependencies = [ "libsecp256k1", "masp_primitives", "namada_macros", + "namada_tests", "pretty_assertions", "proptest", "prost", diff --git a/core/Cargo.toml b/core/Cargo.toml index c195acfb1d..349fbb0025 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -28,13 +28,14 @@ abcipp = [ "ibc-proto-abcipp", "ibc-abcipp", "tendermint-abcipp", - "tendermint-proto-abcipp" + "tendermint-proto-abcipp", ] abciplus = [ "ibc", "ibc-proto", "tendermint", "tendermint-proto", + "namada_tests/abciplus", ] ibc-mocks = [ @@ -99,6 +100,7 @@ tracing = "0.1.30" zeroize = {version = "1.5.5", features = ["zeroize_derive"]} [dev-dependencies] +namada_tests = {path = "../tests", default-features = false, features = ["wasm-runtime"]} assert_matches = "1.5.0" libsecp256k1 = {git = "https://github.com/heliaxdev/libsecp256k1", rev = "bbb3bd44a49db361f21d9db80f9a087c194c0ae9"} pretty_assertions = "0.7.2" diff --git a/tests/src/lib.rs b/tests/src/lib.rs index f39bc5b0e8..db37039878 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -5,6 +5,8 @@ #![deny(rustdoc::broken_intra_doc_links)] #![deny(rustdoc::private_intra_doc_links)] +pub use namada; + mod vm_host_env; pub use vm_host_env::{ibc, tx, vp}; #[cfg(test)] From 19f13730d68a8aee6b81c1d7f6898d80b83bb6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 30 Dec 2022 11:47:30 +0100 Subject: [PATCH 142/166] core/ledger: add testnet_pow module --- core/src/ledger/mod.rs | 1 + core/src/ledger/testnet_pow.rs | 603 +++++++++++++++++++++++++++++++++ 2 files changed, 604 insertions(+) create mode 100644 core/src/ledger/testnet_pow.rs diff --git a/core/src/ledger/mod.rs b/core/src/ledger/mod.rs index 83568c0da7..31879e9b99 100644 --- a/core/src/ledger/mod.rs +++ b/core/src/ledger/mod.rs @@ -8,5 +8,6 @@ pub mod parameters; pub mod slash_fund; pub mod storage; pub mod storage_api; +pub mod testnet_pow; pub mod tx_env; pub mod vp_env; diff --git a/core/src/ledger/testnet_pow.rs b/core/src/ledger/testnet_pow.rs new file mode 100644 index 0000000000..e40eb7a96e --- /dev/null +++ b/core/src/ledger/testnet_pow.rs @@ -0,0 +1,603 @@ +//! PoW challenge is used for testnet zero-fee transaction to prevent spam. + +use std::fmt::Display; + +use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; +use namada_macros::StorageKeys; +use serde::{Deserialize, Serialize}; + +use super::storage_api::collections::{lazy_map, LazyCollection}; +use super::storage_api::{self, StorageRead, StorageWrite}; +use crate::ledger::storage_api::collections::LazyMap; +use crate::types::address::Address; +use crate::types::hash::Hash; +use crate::types::storage::{self, DbKeySeg}; +use crate::types::token; + +/// Initialize faucet's storage. This must be called at genesis if faucet +/// account is being used. +pub fn init_faucet_storage( + storage: &mut S, + address: &Address, + difficulty: Difficulty, + withdrawal_limit: token::Amount, +) -> storage_api::Result<()> +where + S: StorageWrite, +{ + write_difficulty(storage, address, difficulty)?; + write_withdrawal_limit(storage, address, withdrawal_limit) +} + +/// Counters are associated with transfer target addresses. +pub type Counter = u64; + +/// A PoW challenge that must be provably solved to withdraw from faucet. +#[derive( + Clone, + Debug, + BorshSerialize, + BorshDeserialize, + PartialEq, + Serialize, + Deserialize, +)] +pub struct Challenge { + /// The address derived from the `WrapperTx`'s signer `pk` field + pub source: Address, + /// Parameters + pub params: ChallengeParams, +} + +/// PoW challenge parameters. +#[derive( + Clone, + Debug, + BorshSerialize, + BorshDeserialize, + BorshSchema, + PartialEq, + Serialize, + Deserialize, +)] +pub struct ChallengeParams { + /// PoW difficulty + pub difficulty: Difficulty, + /// The counter value of the `transfer.target`. + pub counter: Counter, +} + +/// One must find a value for this type to solve a [`Challenge`] that is at +/// least of the matching difficulty of the challenge. +pub type SolutionValue = u64; +/// Size of `SolutionValue` when serialized with borsh +const SOLUTION_VAL_BYTES_LEN: usize = 8; + +/// A [`SolutionValue`] with the [`Challenge`]. +#[derive( + Clone, + Debug, + BorshSerialize, + BorshDeserialize, + BorshSchema, + Serialize, + Deserialize, +)] +pub struct Solution { + /// Challenge params + pub params: ChallengeParams, + /// Solution value, that produces hash with at least `difficulty` leading + /// zeros + pub value: SolutionValue, +} + +impl ChallengeParams { + /// Obtain a PoW challenge for a given transfer. + pub fn new( + storage: &mut S, + faucet_address: &Address, + source: &Address, + ) -> storage_api::Result + where + S: StorageRead + StorageWrite, + { + let difficulty = read_difficulty(storage, faucet_address)?; + let counter = get_counter(storage, faucet_address, source)?; + Ok(Self { + difficulty, + counter, + }) + } +} + +impl Challenge { + /// Obtain a PoW challenge for a given transfer. + pub fn new( + storage: &mut S, + faucet_address: &Address, + source: Address, + ) -> storage_api::Result + where + S: StorageRead + StorageWrite, + { + let params = ChallengeParams::new(storage, faucet_address, &source)?; + Ok(Self { source, params }) + } + + /// Try to find a solution to the [`Challenge`]. + pub fn solve(self) -> Solution { + use std::io::Write; + + println!( + "Looking for a solution with difficulty {}...", + self.params.difficulty + ); + let challenge_bytes = self.try_to_vec().expect("Serializable"); + let challenge_len = challenge_bytes.len(); + let mut stdout = std::io::stdout(); + + // Pre-allocate for the bytes + let mut bytes: Vec = + vec![0; challenge_bytes.len() + SOLUTION_VAL_BYTES_LEN]; + + // Set the first part from `challenge_bytes`... + for (old, new) in + bytes[0..challenge_len].iter_mut().zip(&challenge_bytes[..]) + { + *old = *new; + } + let mut maybe_solution: SolutionValue = 0; + 'outer: loop { + stdout.flush().unwrap(); + print!("\rChecking {}.", maybe_solution); + let solution_bytes = + maybe_solution.try_to_vec().expect("Serializable"); + // ...and the second part from `solution_bytes` + for (old, new) in + bytes[challenge_len..].iter_mut().zip(&solution_bytes[..]) + { + *old = *new; + } + let hash = Hash::sha256(&bytes); + + // Check if it's a solution + for i in 0..self.params.difficulty.0 as usize { + if hash.0[i] != b'0' { + maybe_solution += 1; + continue 'outer; + } + } + + println!(); + println!("Found a solution: {}.", maybe_solution); + stdout.flush().unwrap(); + return Solution { + params: self.params, + value: maybe_solution, + }; + } + } +} + +impl Solution { + /// Invalidate a solution if it's valid so that it cannot be used again by + /// updating the counter in storage. + pub fn invalidate_if_valid( + &self, + storage: &mut S, + faucet_address: &Address, + source: &Address, + ) -> storage_api::Result + where + S: StorageWrite + StorageRead, + { + if self.validate(storage, faucet_address, source.clone())? { + self.apply_from_tx(storage, faucet_address, source)?; + Ok(true) + } else { + Ok(false) + } + } + + /// Apply a solution from a tx so that it cannot be used again. + pub fn apply_from_tx( + &self, + storage: &mut S, + faucet_address: &Address, + source: &Address, + ) -> storage_api::Result<()> + where + S: StorageWrite + StorageRead, + { + increment_counter(storage, faucet_address, source, self.params.counter) + } + + /// Verify a solution and that the counter has been increment to prevent + /// solution replay. + /// The difficulty of the challenge must match the one set in faucet's + /// storage and the counter value. + pub fn validate( + &self, + storage: &S, + faucet_address: &Address, + source: Address, + ) -> storage_api::Result + where + S: StorageRead, + { + let counter = get_counter(storage, faucet_address, &source)?; + // Check that the counter matches expected counter + if self.params.counter != counter { + return Ok(false); + } + // Check that the difficulty matches expected difficulty + let current_difficulty = read_difficulty(storage, faucet_address)?; + if self.params.difficulty != current_difficulty { + return Ok(false); + } + + // Check the solution itself + if !self.verify_solution(source) { + return Ok(false); + } + + Ok(true) + } + + /// Verify that the given solution is correct. Note that this doesn't check + /// the difficulty or the counter. + pub fn verify_solution(&self, source: Address) -> bool { + let challenge = Challenge { + source, + params: self.params.clone(), + }; + let mut bytes = challenge.try_to_vec().expect("Serializable"); + let mut solution_bytes = self.value.try_to_vec().expect("Serializable"); + bytes.append(&mut solution_bytes); + let hash = Hash::sha256(&bytes); + + // Check if it's a solution + for i in 0..challenge.params.difficulty.0 as usize { + if hash.0[i] != b'0' { + return false; + } + } + + true + } +} + +/// Storage keys +#[derive(StorageKeys)] +pub struct Keys { + /// Withdrawal counters associated with recipient addresses. To withdraw + /// tokens from faucet, one must find a solution to a PoW challenge + /// containing the current value of their counter (or `0` is none). + counters: &'static str, + /// PoW difficulty + pow_difficulty: &'static str, + /// withdrawal limit + withdrawal_limit: &'static str, +} + +/// Storage key prefix to the `counters` field. The rest of the key is composed +/// from `LazyMap` stored at this key. +pub fn counter_prefix(address: &Address) -> storage::Key { + storage::Key { + segments: vec![ + DbKeySeg::AddressSeg(address.clone()), + DbKeySeg::StringSeg(Keys::VALUES.counters.to_string()), + ], + } +} + +/// Is the storage key for the `counters` field? If so, returns the owner. +pub fn is_counter_key<'a>( + key: &'a storage::Key, + faucet_address: &Address, +) -> Option<&'a Address> { + match &key.segments[..] { + [ + DbKeySeg::AddressSeg(address), + DbKeySeg::StringSeg(sub_key), + DbKeySeg::StringSeg(data), + DbKeySeg::AddressSeg(owner), + ] if address == faucet_address + && sub_key.as_str() == Keys::VALUES.counters + && data.as_str() == lazy_map::DATA_SUBKEY => + { + Some(owner) + } + _ => None, + } +} + +/// Storage key to the `difficulty` field. +pub fn difficulty_key(address: &Address) -> storage::Key { + storage::Key { + segments: vec![ + DbKeySeg::AddressSeg(address.clone()), + DbKeySeg::StringSeg(Keys::VALUES.pow_difficulty.to_string()), + ], + } +} + +/// Is the storage key for the `difficulty` field? +pub fn is_difficulty_key(key: &storage::Key, faucet_address: &Address) -> bool { + matches!( + &key.segments[..], + [ + DbKeySeg::AddressSeg(address), + DbKeySeg::StringSeg(sub_key), + ] if address == faucet_address && sub_key.as_str() == Keys::VALUES.pow_difficulty, + ) +} + +/// Storage key to the `withdrawal_limit` field. +pub fn withdrawal_limit_key(address: &Address) -> storage::Key { + storage::Key { + segments: vec![ + DbKeySeg::AddressSeg(address.clone()), + DbKeySeg::StringSeg(Keys::VALUES.withdrawal_limit.to_string()), + ], + } +} + +/// Is the storage key for the `withdrawal_limit` field? +pub fn is_withdrawal_limit_key( + key: &storage::Key, + faucet_address: &Address, +) -> bool { + matches!( + &key.segments[..], + [ + DbKeySeg::AddressSeg(address), + DbKeySeg::StringSeg(sub_key), + ] if address == faucet_address && sub_key.as_str() == Keys::VALUES.withdrawal_limit, + ) +} + +/// Read faucet's counter value for a given target address. +pub fn get_counter( + storage: &S, + faucet_address: &Address, + source: &Address, +) -> storage_api::Result +where + S: StorageRead, +{ + let counter: Counter = counters_handle(faucet_address) + .get(storage, source)? + // `0` if not previously set + .unwrap_or_default(); + Ok(counter) +} + +/// Increment faucet's counter value for a given source address. +pub fn increment_counter( + storage: &mut S, + faucet_address: &Address, + source: &Address, + current_counter: Counter, +) -> storage_api::Result<()> +where + S: StorageWrite + StorageRead, +{ + counters_handle(faucet_address).insert( + storage, + source.clone(), + current_counter + 1, + )?; + Ok(()) +} + +/// A handle to read/write withdrawal counters +pub fn counters_handle(address: &Address) -> LazyMap { + LazyMap::open(counter_prefix(address)) +} + +/// PoW difficulty (value between `0..=9`). +#[derive( + Copy, + Clone, + Debug, + Default, + BorshSerialize, + BorshDeserialize, + BorshSchema, + Eq, + PartialEq, + PartialOrd, + Ord, + Serialize, + Deserialize, +)] +#[serde(transparent)] +pub struct Difficulty(u8); +impl Difficulty { + /// The value must be between `0..=9` (inclusive upper bound). + pub fn try_new(raw: u8) -> Option { + if raw > 9 { None } else { Some(Self(raw)) } + } +} + +impl Display for Difficulty { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +/// Read PoW [`Difficulty`]. +pub fn read_difficulty( + storage: &S, + address: &Address, +) -> storage_api::Result +where + S: StorageRead, +{ + let difficulty = storage + .read(&difficulty_key(address))? + .expect("difficulty must always be set"); + Ok(difficulty) +} + +/// Write PoW [`Difficulty`]. +pub fn write_difficulty( + storage: &mut S, + address: &Address, + difficulty: Difficulty, +) -> storage_api::Result<()> +where + S: StorageWrite, +{ + storage.write(&difficulty_key(address), difficulty) +} + +/// Read the withdrawal limit. +pub fn read_withdrawal_limit( + storage: &S, + address: &Address, +) -> storage_api::Result +where + S: StorageRead, +{ + let withdrawal_limit = storage + .read(&withdrawal_limit_key(address))? + .expect("withdrawal_limit must always be set"); + Ok(withdrawal_limit) +} + +/// Write faucet withdrawal limit +pub fn write_withdrawal_limit( + storage: &mut S, + address: &Address, + withdrawal_limit: token::Amount, +) -> Result<(), storage_api::Error> +where + S: StorageWrite, +{ + storage.write(&withdrawal_limit_key(address), withdrawal_limit) +} + +#[cfg(test)] +mod test { + use super::*; + #[test] + fn test_solution_val_bytes_len() { + let val: SolutionValue = 10; + let bytes = val.try_to_vec().unwrap(); + assert_eq!(bytes.len(), SOLUTION_VAL_BYTES_LEN); + } +} + +#[cfg(test)] +mod test_with_tx_and_vp_env { + // IMPORTANT: do not import anything directly from this `crate` here, only + // via `namada_tests`. This gets us around the `core -> tests -> core` dep + // cycle, which is okay, because `tests` is only a `dev-dependency` of + // core and allows us to test the code in the same module as its defined. + // + // This imports the same code as `super::*` but from a different version of + // this crate (one that `namada_tests` depends on). It's re-exported + // from `namada_tests` so that we can use it together with + // `namada_tests` modules back in here. + use namada_tests::namada::core::ledger::storage_api; + use namada_tests::namada::core::ledger::testnet_pow::*; + use namada_tests::namada::core::types::{address, token}; + use namada_tests::tx::{self, TestTxEnv}; + use namada_tests::vp; + + #[test] + fn test_challenge_and_solution() -> storage_api::Result<()> { + let faucet_address = address::testing::established_address_1(); + let difficulty = Difficulty::try_new(1).unwrap(); + let withdrawal_limit = token::Amount::whole(1_000); + + let mut tx_env = TestTxEnv::default(); + + // Source address that's using PoW (this would be derived from the tx + // wrapper pk) + let source = address::testing::established_address_2(); + + // Ensure that the addresses exists, so we can use them in a tx + tx_env.spawn_accounts([&faucet_address, &source]); + + init_faucet_storage( + &mut tx_env.storage, + &faucet_address, + difficulty, + withdrawal_limit, + )?; + + let challenge = Challenge::new( + &mut tx_env.storage, + &faucet_address, + source.clone(), + )?; + + let solution = challenge.solve(); + + // The solution must be valid + assert!(solution.verify_solution(source.clone())); + + // Changing the solution to `0` invalidates it + { + let mut solution = solution.clone(); + solution.value = 0; + // If you're unlucky and this fails, try changing the solution to + // a different literal. + assert!(!solution.verify_solution(source.clone())); + } + // Changing the counter invalidates it + { + let mut solution = solution.clone(); + solution.params.counter = 10; + // If you're unlucky and this fails, try changing the counter to + // a different literal. + assert!(!solution.verify_solution(source.clone())); + } + + // Apply the solution from a tx + vp::vp_host_env::init_from_tx( + faucet_address.clone(), + tx_env, + |_addr| { + solution + .apply_from_tx(tx::ctx(), &faucet_address, &source) + .unwrap(); + }, + ); + + // Check that it's valid + let is_valid = solution.validate( + &vp::ctx().pre(), + &faucet_address, + source.clone(), + )?; + assert!(is_valid); + + // Commit the tx + let vp_env = vp::vp_host_env::take(); + tx::tx_host_env::set_from_vp_env(vp_env); + tx::tx_host_env::commit_tx_and_block(); + let tx_env = tx::tx_host_env::take(); + + // Re-apply the same solution from a tx + vp::vp_host_env::init_from_tx( + faucet_address.clone(), + tx_env, + |_addr| { + solution + .apply_from_tx(tx::ctx(), &faucet_address, &source) + .unwrap(); + }, + ); + + // Check that it's not longer valid + let is_valid = + solution.validate(&vp::ctx().pre(), &faucet_address, source)?; + assert!(!is_valid); + + Ok(()) + } +} From 72d9f3685b363818bb2422507c01a9b7d732c835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 30 Dec 2022 11:48:03 +0100 Subject: [PATCH 143/166] storage_api/lazy_map: export `get_data_key` fn for client --- core/src/ledger/storage_api/collections/lazy_map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/ledger/storage_api/collections/lazy_map.rs b/core/src/ledger/storage_api/collections/lazy_map.rs index 81ddd7f42d..ec4a958002 100644 --- a/core/src/ledger/storage_api/collections/lazy_map.rs +++ b/core/src/ledger/storage_api/collections/lazy_map.rs @@ -334,7 +334,7 @@ where } /// Get the sub-key of a given element - fn get_data_key(&self, key: &K) -> storage::Key { + pub fn get_data_key(&self, key: &K) -> storage::Key { let key_str = key.to_db_key(); self.get_data_prefix().push(&key_str).unwrap() } From 9ca9c94bcaa6d4e4f75c744e2b739d8fe703ac49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 30 Dec 2022 11:49:54 +0100 Subject: [PATCH 144/166] add "mainnet" feature flag, off by default for now --- Makefile | 13 +++++++++++++ apps/Cargo.toml | 3 +++ core/Cargo.toml | 1 + shared/Cargo.toml | 3 +++ tests/Cargo.toml | 3 +++ 5 files changed, 23 insertions(+) diff --git a/Makefile b/Makefile index 58329ea22b..6ba375aac7 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,9 @@ check-abcipp: --no-default-features \ --features "abcipp ibc-mocks-abcipp testing" +check-mainnet: + $(cargo) check --workspace --features "mainnet" + clippy-wasm = $(cargo) +$(nightly) clippy --manifest-path $(wasm)/Cargo.toml --all-targets -- -D warnings clippy: @@ -76,6 +79,9 @@ clippy-abcipp: make -C $(wasms) clippy && \ $(foreach wasm,$(wasm_templates),$(clippy-wasm) && ) true +clippy-mainnet: + $(cargo) +$(nightly) clippy --all-targets --features "mainnet" -- -D warnings + clippy-fix: $(cargo) +$(nightly) clippy --fix -Z unstable-options --all-targets --allow-dirty --allow-staged @@ -143,6 +149,13 @@ test-unit: --skip e2e \ -Z unstable-options --report-time +test-unit-mainnet: + $(cargo) test \ + --features "mainnet" \ + $(TEST_FILTER) -- \ + --skip e2e \ + -Z unstable-options --report-time + test-unit-debug: $(debug-cargo) test \ $(TEST_FILTER) -- \ diff --git a/apps/Cargo.toml b/apps/Cargo.toml index 972eb41f53..d39c4c13c4 100644 --- a/apps/Cargo.toml +++ b/apps/Cargo.toml @@ -41,6 +41,9 @@ path = "src/bin/namada-wallet/main.rs" [features] default = ["std", "abciplus"] +mainnet = [ + "namada/mainnet", +] dev = ["namada/dev"] std = ["ed25519-consensus/std", "rand/std", "rand_core/std"] # for integration tests and test utilies diff --git a/core/Cargo.toml b/core/Cargo.toml index 349fbb0025..a101f4c3b9 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -8,6 +8,7 @@ version = "0.12.2" [features] default = [] +mainnet = [] ferveo-tpke = [ "ferveo", "tpke", diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 25b039963e..6fd22f6a06 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -10,6 +10,9 @@ version = "0.12.2" [features] default = ["abciplus"] +mainnet = [ + "namada_core/mainnet", +] # NOTE "dev" features that shouldn't be used in live networks are enabled by default for now dev = [] ferveo-tpke = [ diff --git a/tests/Cargo.toml b/tests/Cargo.toml index b4c4065ec0..1b5b2b50f6 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -9,6 +9,9 @@ version = "0.12.2" [features] default = ["abciplus", "wasm-runtime"] +mainnet = [ + "namada/mainnet", +] abciplus = [ "namada/abciplus", "namada/ibc-mocks", From 19134a7868f7c9375716738ad50685500b1ee455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 30 Dec 2022 11:50:38 +0100 Subject: [PATCH 145/166] genesis: add faucet_pow_difficulty and faucet_withdrawal_limit --- apps/src/lib/config/genesis.rs | 26 ++++++++++++++++++++++++++ genesis/e2e-tests-single-node.toml | 2 ++ 2 files changed, 28 insertions(+) diff --git a/apps/src/lib/config/genesis.rs b/apps/src/lib/config/genesis.rs index 87ff12995e..3ab8e60b6f 100644 --- a/apps/src/lib/config/genesis.rs +++ b/apps/src/lib/config/genesis.rs @@ -6,6 +6,8 @@ use std::path::Path; use borsh::{BorshDeserialize, BorshSerialize}; use derivative::Derivative; +#[cfg(not(feature = "mainnet"))] +use namada::core::ledger::testnet_pow; use namada::ledger::governance::parameters::GovParams; use namada::ledger::parameters::EpochDuration; use namada::ledger::pos::{GenesisValidator, PosParams}; @@ -29,6 +31,8 @@ pub mod genesis_config { use data_encoding::HEXLOWER; use eyre::Context; + #[cfg(not(feature = "mainnet"))] + use namada::core::ledger::testnet_pow; use namada::ledger::governance::parameters::GovParams; use namada::ledger::parameters::EpochDuration; use namada::ledger::pos::{GenesisValidator, PosParams}; @@ -111,6 +115,12 @@ pub mod genesis_config { // Name of the native token - this must one of the tokens included in // the `token` field pub native_token: String, + #[cfg(not(feature = "mainnet"))] + /// Testnet faucet PoW difficulty - defaults to `0` when not set + pub faucet_pow_difficulty: Option, + #[cfg(not(feature = "mainnet"))] + /// Testnet faucet withdrawal limit - defaults to 1000 NAM when not set + pub faucet_withdrawal_limit: Option, // Initial validator set pub validator: HashMap, // Token accounts present at genesis @@ -510,6 +520,10 @@ pub mod genesis_config { let GenesisConfig { genesis_time, native_token, + #[cfg(not(feature = "mainnet"))] + faucet_pow_difficulty, + #[cfg(not(feature = "mainnet"))] + faucet_withdrawal_limit, validator, token, established, @@ -646,6 +660,10 @@ pub mod genesis_config { let mut genesis = Genesis { genesis_time: genesis_time.try_into().unwrap(), native_token, + #[cfg(not(feature = "mainnet"))] + faucet_pow_difficulty, + #[cfg(not(feature = "mainnet"))] + faucet_withdrawal_limit, validators: validators.into_values().collect(), token_accounts, established_accounts: established_accounts.into_values().collect(), @@ -694,6 +712,10 @@ pub mod genesis_config { pub struct Genesis { pub genesis_time: DateTimeUtc, pub native_token: Address, + #[cfg(not(feature = "mainnet"))] + pub faucet_pow_difficulty: Option, + #[cfg(not(feature = "mainnet"))] + pub faucet_withdrawal_limit: Option, pub validators: Vec, pub token_accounts: Vec, pub established_accounts: Vec, @@ -971,6 +993,10 @@ pub fn genesis() -> Genesis { pos_params: PosParams::default(), gov_params: GovParams::default(), native_token: address::nam(), + #[cfg(not(feature = "mainnet"))] + faucet_pow_difficulty: None, + #[cfg(not(feature = "mainnet"))] + faucet_withdrawal_limit: None, } } diff --git a/genesis/e2e-tests-single-node.toml b/genesis/e2e-tests-single-node.toml index 249e55ef6d..9cecf64aee 100644 --- a/genesis/e2e-tests-single-node.toml +++ b/genesis/e2e-tests-single-node.toml @@ -4,6 +4,8 @@ genesis_time = "2021-09-30T10:00:00Z" native_token = "NAM" +faucet_pow_difficulty = 1 +faucet_withdrawal_limit = "1_000" [validator.validator-0] # Validator's staked NAM at genesis. From 33832d43f2bb86c66b1b8c6f251ee6715d5fe653 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 30 Dec 2022 11:52:30 +0100 Subject: [PATCH 146/166] add `faucet_account` parameter and set it from `init_chain` if found --- apps/src/lib/node/ledger/shell/init_chain.rs | 21 +++++++++ core/src/ledger/parameters/mod.rs | 46 ++++++++++++++++++++ core/src/ledger/parameters/storage.rs | 11 +++++ core/src/ledger/storage/mod.rs | 2 + 4 files changed, 80 insertions(+) diff --git a/apps/src/lib/node/ledger/shell/init_chain.rs b/apps/src/lib/node/ledger/shell/init_chain.rs index ac783e9cfb..7fadf747a0 100644 --- a/apps/src/lib/node/ledger/shell/init_chain.rs +++ b/apps/src/lib/node/ledger/shell/init_chain.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::hash::Hash; +use namada::core::ledger::testnet_pow; use namada::ledger::parameters::Parameters; use namada::ledger::pos::into_tm_voting_power; use namada::types::key::*; @@ -97,6 +98,24 @@ where implicit_vp_code_path ); } + #[cfg(not(feature = "mainnet"))] + // Try to find a faucet account + let faucet_account = { + genesis.established_accounts.iter().find_map( + |genesis::EstablishedAccount { + address, + vp_code_path, + .. + }| { + if vp_code_path == "vp_testnet_faucet.wasm" { + Some(address.clone()) + } else { + None + } + }, + ) + }; + let parameters = Parameters { epoch_duration, max_proposal_bytes, @@ -109,6 +128,8 @@ where pos_gain_d, staked_ratio, pos_inflation_amount, + #[cfg(not(feature = "mainnet"))] + faucet_account, }; parameters.init_storage(&mut self.storage); diff --git a/core/src/ledger/parameters/mod.rs b/core/src/ledger/parameters/mod.rs index 0cadc833a4..75c6d33d9f 100644 --- a/core/src/ledger/parameters/mod.rs +++ b/core/src/ledger/parameters/mod.rs @@ -51,6 +51,9 @@ pub struct Parameters { pub staked_ratio: Decimal, /// PoS inflation amount from the last epoch (read + write for every epoch) pub pos_inflation_amount: u64, + #[cfg(not(feature = "mainnet"))] + /// Faucet account for free token withdrawal + pub faucet_account: Option
, } /// Epoch duration. A new epoch begins as soon as both the `min_num_of_blocks` @@ -113,6 +116,8 @@ impl Parameters { pos_gain_d, staked_ratio, pos_inflation_amount, + #[cfg(not(feature = "mainnet"))] + faucet_account, } = self; // write max proposal bytes parameter @@ -201,6 +206,18 @@ impl Parameters { "PoS inflation rate parameter must be initialized in the genesis \ block", ); + + #[cfg(not(feature = "mainnet"))] + if let Some(faucet_account) = faucet_account { + let faucet_account_key = storage::get_faucet_account_key(); + let faucet_account_val = encode(faucet_account); + storage + .write(&faucet_account_key, faucet_account_val) + .expect( + "Faucet account parameter must be initialized in the \ + genesis block, if any", + ); + } } } /// Update the max_expected_time_per_block parameter in storage. Returns the @@ -387,6 +404,25 @@ where Ok((epoch_duration, gas)) } +#[cfg(not(feature = "mainnet"))] +/// Read the faucet account's address, if any +pub fn read_faucet_account_parameter( + storage: &Storage, +) -> std::result::Result<(Option
, u64), ReadError> +where + DB: ledger_storage::DB + for<'iter> ledger_storage::DBIter<'iter>, + H: ledger_storage::StorageHasher, +{ + let faucet_account_key = storage::get_faucet_account_key(); + let (value, gas_faucet_account) = storage + .read(&faucet_account_key) + .map_err(ReadError::StorageError)?; + let address: Option
= value + .map(|value| decode(value).map_err(ReadError::StorageTypeError)) + .transpose()?; + Ok((address, gas_faucet_account)) +} + // Read the all the parameters from storage. Returns the parameters and gas /// cost. pub fn read( @@ -489,6 +525,13 @@ where decode(value.ok_or(ReadError::ParametersMissing)?) .map_err(ReadError::StorageTypeError)?; + // read faucet account + #[cfg(not(feature = "mainnet"))] + let (faucet_account, gas_faucet_account) = + read_faucet_account_parameter(storage)?; + #[cfg(feature = "mainnet")] + let gas_faucet_account = 0; + let total_gas_cost = [ gas_epoch, gas_tx, @@ -501,6 +544,7 @@ where gas_staked, gas_reward, gas_proposal_bytes, + gas_faucet_account, ] .into_iter() .fold(0u64, |accum, gas| { @@ -522,6 +566,8 @@ where pos_gain_d, staked_ratio, pos_inflation_amount, + #[cfg(not(feature = "mainnet"))] + faucet_account, }, total_gas_cost, )) diff --git a/core/src/ledger/parameters/storage.rs b/core/src/ledger/parameters/storage.rs index 477eb932b9..f2b5d1353d 100644 --- a/core/src/ledger/parameters/storage.rs +++ b/core/src/ledger/parameters/storage.rs @@ -19,6 +19,7 @@ struct Keys { tx_whitelist: &'static str, vp_whitelist: &'static str, max_proposal_bytes: &'static str, + faucet_account: &'static str, } /// Returns if the key is a parameter key. @@ -238,3 +239,13 @@ pub fn get_max_proposal_bytes_key() -> Key { ], } } + +/// Storage key used for faucet account. +pub fn get_faucet_account_key() -> Key { + Key { + segments: vec![ + DbKeySeg::AddressSeg(ADDRESS), + DbKeySeg::StringSeg(Keys::VALUES.faucet_account.to_string()), + ], + } +} diff --git a/core/src/ledger/storage/mod.rs b/core/src/ledger/storage/mod.rs index fc0aedf52b..8f0606bd70 100644 --- a/core/src/ledger/storage/mod.rs +++ b/core/src/ledger/storage/mod.rs @@ -1240,6 +1240,8 @@ mod tests { pos_gain_d: dec!(0.1), staked_ratio: dec!(0.1), pos_inflation_amount: 0, + #[cfg(not(feature = "mainnet"))] + faucet_account: None, }; parameters.init_storage(&mut storage); From 473c43aed0db67d20c39d1ac5d80898404e085e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 30 Dec 2022 11:53:17 +0100 Subject: [PATCH 147/166] shell/init_chain: init faucet storage, if used --- apps/src/lib/node/ledger/shell/init_chain.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/apps/src/lib/node/ledger/shell/init_chain.rs b/apps/src/lib/node/ledger/shell/init_chain.rs index 7fadf747a0..6930c35f3a 100644 --- a/apps/src/lib/node/ledger/shell/init_chain.rs +++ b/apps/src/lib/node/ledger/shell/init_chain.rs @@ -194,6 +194,24 @@ where for (key, value) in storage { self.storage.write(&key, value).unwrap(); } + + // When using a faucet WASM, initialize its PoW challenge storage + #[cfg(not(feature = "mainnet"))] + if vp_code_path == "vp_testnet_faucet.wasm" { + let difficulty = + genesis.faucet_pow_difficulty.unwrap_or_default(); + // withdrawal limit defaults to 1000 NAM when not set + let withdrawal_limit = genesis + .faucet_withdrawal_limit + .unwrap_or_else(|| token::Amount::whole(1_000)); + testnet_pow::init_faucet_storage( + &mut self.storage, + &address, + difficulty, + withdrawal_limit, + ) + .expect("Couldn't init faucet storage") + } } // Initialize genesis implicit From 2225839d9087419e53354d2204e23be3902a499e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 30 Dec 2022 11:56:40 +0100 Subject: [PATCH 148/166] validate PoW in mempool, proposal and finalize and keep the result --- apps/src/lib/client/rpc.rs | 12 ++- .../lib/node/ledger/shell/finalize_block.rs | 72 ++++++++++----- apps/src/lib/node/ledger/shell/governance.rs | 6 +- apps/src/lib/node/ledger/shell/init_chain.rs | 1 + apps/src/lib/node/ledger/shell/mod.rs | 88 +++++++++++++++++-- .../lib/node/ledger/shell/prepare_proposal.rs | 36 ++++++-- .../lib/node/ledger/shell/process_proposal.rs | 49 +++++++++-- core/src/proto/types.rs | 6 +- core/src/types/internal.rs | 26 ++++-- core/src/types/transaction/decrypted.rs | 31 ++++++- core/src/types/transaction/mod.rs | 28 +++++- core/src/types/transaction/wrapper.rs | 14 +++ shared/src/ledger/protocol/mod.rs | 6 +- shared/src/ledger/queries/shell.rs | 6 +- 14 files changed, 319 insertions(+), 62 deletions(-) diff --git a/apps/src/lib/client/rpc.rs b/apps/src/lib/client/rpc.rs index 3fb4d8eea8..91bdee5831 100644 --- a/apps/src/lib/client/rpc.rs +++ b/apps/src/lib/client/rpc.rs @@ -389,7 +389,11 @@ fn extract_payload( let privkey = ::G2Affine::prime_subgroup_generator(); extract_payload( Tx::from(match wrapper_tx.decrypt(privkey) { - Ok(tx) => DecryptedTx::Decrypted(tx), + Ok(tx) => DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, + }, _ => DecryptedTx::Undecryptable(wrapper_tx.clone()), }), wrapper, @@ -397,7 +401,11 @@ fn extract_payload( ); *wrapper = Some(wrapper_tx); } - Ok(TxType::Decrypted(DecryptedTx::Decrypted(tx))) => { + Ok(TxType::Decrypted(DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: _, + })) => { let empty_vec = vec![]; let tx_data = tx.data.as_ref().unwrap_or(&empty_vec); let _ = SignedTxData::try_from_slice(tx_data).map(|signed| { diff --git a/apps/src/lib/node/ledger/shell/finalize_block.rs b/apps/src/lib/node/ledger/shell/finalize_block.rs index 0541c287b5..577a4ac003 100644 --- a/apps/src/lib/node/ledger/shell/finalize_block.rs +++ b/apps/src/lib/node/ledger/shell/finalize_block.rs @@ -135,6 +135,10 @@ where TxType::Wrapper(wrapper) => { let mut tx_event = Event::new_tx_event(&tx_type, height.0); + #[cfg(not(feature = "mainnet"))] + let has_valid_pow = + self.invalidate_pow_solution_if_valid(wrapper); + // Charge fee let fee_payer = if wrapper.pk != address::masp_tx_key().ref_to() { @@ -186,23 +190,33 @@ where .unwrap(); } None => { - // Burn remaining funds - self.write_log - .write( - &balance_key, - Amount::from(0).try_to_vec().unwrap(), - ) - .unwrap(); - tx_event["log"] = - "Insufficient balance for fee".into(); - tx_event["code"] = ErrorCodes::InvalidTx.into(); + #[cfg(not(feature = "mainnet"))] + let reject = !has_valid_pow; + #[cfg(feature = "mainnet")] + let reject = true; + if reject { + // Burn remaining funds + self.write_log + .write( + &balance_key, + Amount::from(0).try_to_vec().unwrap(), + ) + .unwrap(); + tx_event["log"] = + "Insufficient balance for fee".into(); + tx_event["code"] = ErrorCodes::InvalidTx.into(); - response.events.push(tx_event); - continue; + response.events.push(tx_event); + continue; + } } } - self.storage.tx_queue.push(wrapper.clone()); + self.storage.tx_queue.push(WrapperTxInQueue { + tx: wrapper.clone(), + #[cfg(not(feature = "mainnet"))] + has_valid_pow, + }); tx_event } TxType::Decrypted(inner) => { @@ -404,7 +418,7 @@ where #[cfg(test)] mod test_finalize_block { use namada::types::storage::Epoch; - use namada::types::transaction::{EncryptionKey, Fee}; + use namada::types::transaction::{EncryptionKey, Fee, WrapperTx}; use super::*; use crate::node::ledger::shell::test_utils::*; @@ -448,6 +462,8 @@ mod test_finalize_block { 0.into(), raw_tx.clone(), Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); let tx = wrapper.sign(&keypair).expect("Test failed"); if i > 1 { @@ -489,7 +505,7 @@ mod test_finalize_block { // we cannot easily implement the PartialEq trait for WrapperTx // so we check the hashes of the inner txs for equality assert_eq!( - wrapper.tx_hash, + wrapper.tx.tx_hash, valid_tx.next().expect("Test failed").tx_hash ); counter += 1; @@ -519,11 +535,17 @@ mod test_finalize_block { 0.into(), raw_tx.clone(), Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); let processed_tx = ProcessedTx { - tx: Tx::from(TxType::Decrypted(DecryptedTx::Decrypted(raw_tx))) - .to_bytes(), + tx: Tx::from(TxType::Decrypted(DecryptedTx::Decrypted { + tx: raw_tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, + })) + .to_bytes(), result: TxResult { code: ErrorCodes::InvalidTx.into(), info: "".into(), @@ -571,6 +593,8 @@ mod test_finalize_block { gas_limit: 0.into(), inner_tx, tx_hash: hash_tx(&tx), + #[cfg(not(feature = "mainnet"))] + pow_solution: None, }; let processed_tx = ProcessedTx { tx: Tx::from(TxType::Decrypted(DecryptedTx::Undecryptable( @@ -647,11 +671,17 @@ mod test_finalize_block { 0.into(), raw_tx.clone(), Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); shell.enqueue_tx(wrapper_tx); processed_txs.push(ProcessedTx { - tx: Tx::from(TxType::Decrypted(DecryptedTx::Decrypted(raw_tx))) - .to_bytes(), + tx: Tx::from(TxType::Decrypted(DecryptedTx::Decrypted { + tx: raw_tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, + })) + .to_bytes(), result: TxResult { code: ErrorCodes::Ok.into(), info: "".into(), @@ -678,6 +708,8 @@ mod test_finalize_block { 0.into(), raw_tx.clone(), Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); let wrapper = wrapper_tx.sign(&keypair).expect("Test failed"); valid_txs.push(wrapper_tx); @@ -729,7 +761,7 @@ mod test_finalize_block { let mut counter = 0; for wrapper in shell.iter_tx_queue() { assert_eq!( - wrapper.tx_hash, + wrapper.tx.tx_hash, txs.next().expect("Test failed").tx_hash ); counter += 1; diff --git a/apps/src/lib/node/ledger/shell/governance.rs b/apps/src/lib/node/ledger/shell/governance.rs index 02a22b1caa..67c49c714d 100644 --- a/apps/src/lib/node/ledger/shell/governance.rs +++ b/apps/src/lib/node/ledger/shell/governance.rs @@ -74,7 +74,11 @@ where Some(proposal_code) => { let tx = Tx::new(proposal_code, Some(encode(&id))); let tx_type = - TxType::Decrypted(DecryptedTx::Decrypted(tx)); + TxType::Decrypted(DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, + }); let pending_execution_key = gov_storage::get_proposal_execution_key(id); shell diff --git a/apps/src/lib/node/ledger/shell/init_chain.rs b/apps/src/lib/node/ledger/shell/init_chain.rs index 6930c35f3a..5e4415a0c9 100644 --- a/apps/src/lib/node/ledger/shell/init_chain.rs +++ b/apps/src/lib/node/ledger/shell/init_chain.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::hash::Hash; +#[cfg(not(feature = "mainnet"))] use namada::core::ledger::testnet_pow; use namada::ledger::parameters::Parameters; use namada::ledger::pos::into_tm_voting_power; diff --git a/apps/src/lib/node/ledger/shell/mod.rs b/apps/src/lib/node/ledger/shell/mod.rs index 7bfd8bdb5c..3b5940f99c 100644 --- a/apps/src/lib/node/ledger/shell/mod.rs +++ b/apps/src/lib/node/ledger/shell/mod.rs @@ -36,13 +36,14 @@ use namada::proto::{self, Tx}; use namada::types::address; use namada::types::address::{masp, masp_tx_key, Address}; use namada::types::chain::ChainId; +use namada::types::internal::WrapperTxInQueue; use namada::types::key::*; use namada::types::storage::{BlockHeight, Key, TxIndex}; use namada::types::time::{DateTimeUtc, TimeZone, Utc}; use namada::types::token::{self, Amount}; use namada::types::transaction::{ hash_tx, process_tx, verify_decrypted_correctly, AffineCurve, DecryptedTx, - EllipticCurve, PairingEngine, TxType, WrapperTx, MIN_FEE, + EllipticCurve, PairingEngine, TxType, MIN_FEE, }; use namada::vm::wasm::{TxCache, VpCache}; use namada::vm::WasmCacheRwAccess; @@ -351,7 +352,7 @@ where /// Iterate over the wrapper txs in order #[allow(dead_code)] - fn iter_tx_queue(&mut self) -> impl Iterator { + fn iter_tx_queue(&mut self) -> impl Iterator { self.storage.tx_queue.iter() } @@ -588,7 +589,14 @@ where let balance = self.get_balance(&wrapper.fee.token, &fee_payer); - if Amount::from(MIN_FEE) > balance { + // In testnets with a faucet, tx is allowed to skip fees if + // it includes a valid PoW + #[cfg(not(feature = "mainnet"))] + let has_valid_pow = self.has_valid_pow_solution(&wrapper); + #[cfg(feature = "mainnet")] + let has_valid_pow = false; + + if !has_valid_pow && Amount::from(MIN_FEE) > balance { response.code = 1; response.log = String::from( "The address given does not have sufficient \ @@ -618,7 +626,13 @@ where let mut tx_wasm_cache = self.tx_wasm_cache.read_only(); match Tx::try_from(tx_bytes) { Ok(tx) => { - let tx = TxType::Decrypted(DecryptedTx::Decrypted(tx)); + let tx = TxType::Decrypted(DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + // To be able to dry-run testnet faucet withdrawal, pretend + // that we got a valid PoW + has_valid_pow: true, + }); match protocol::apply_tx( tx, tx_bytes.len(), @@ -681,6 +695,56 @@ where ) }) } + + #[cfg(not(feature = "mainnet"))] + /// Check if the tx has a valid PoW solution. Unlike + /// `apply_pow_solution_if_valid`, this won't invalidate the solution. + fn has_valid_pow_solution( + &self, + tx: &namada::types::transaction::WrapperTx, + ) -> bool { + if let Some(solution) = &tx.pow_solution { + if let (Some(faucet_address), _gas) = + namada::ledger::parameters::read_faucet_account_parameter( + &self.storage, + ) + .expect("Must be able to read faucet account parameter") + { + let source = Address::from(&tx.pk); + return solution + .validate(&self.storage, &faucet_address, source) + .expect("Must be able to validate PoW solutions"); + } + } + false + } + + #[cfg(not(feature = "mainnet"))] + /// Check if the tx has a valid PoW solution and if so invalidate it to + /// prevent replay. + fn invalidate_pow_solution_if_valid( + &mut self, + tx: &namada::types::transaction::WrapperTx, + ) -> bool { + if let Some(solution) = &tx.pow_solution { + if let (Some(faucet_address), _gas) = + namada::ledger::parameters::read_faucet_account_parameter( + &self.storage, + ) + .expect("Must be able to read faucet account parameter") + { + let source = Address::from(&tx.pk); + return solution + .invalidate_if_valid( + &mut self.storage, + &faucet_address, + &source, + ) + .expect("Must be able to validate PoW solutions"); + } + } + false + } } /// Helper functions and types for writing unit tests @@ -697,7 +761,7 @@ mod test_utils { use namada::types::hash::Hash; use namada::types::key::*; use namada::types::storage::{BlockHash, BlockResults, Epoch, Header}; - use namada::types::transaction::Fee; + use namada::types::transaction::{Fee, WrapperTx}; use tempfile::tempdir; use tokio::sync::mpsc::UnboundedReceiver; @@ -846,7 +910,11 @@ mod test_utils { /// in the current block proposal #[cfg(test)] pub fn enqueue_tx(&mut self, wrapper: WrapperTx) { - self.shell.storage.tx_queue.push(wrapper); + self.shell.storage.tx_queue.push(WrapperTxInQueue { + tx: wrapper, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, + }); } } @@ -922,8 +990,14 @@ mod test_utils { 0.into(), tx, Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); - shell.storage.tx_queue.push(wrapper); + shell.storage.tx_queue.push(WrapperTxInQueue { + tx: wrapper, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, + }); // Artificially increase the block height so that chain // will read the new block when restarted let merkle_tree = MerkleTree::::default(); diff --git a/apps/src/lib/node/ledger/shell/prepare_proposal.rs b/apps/src/lib/node/ledger/shell/prepare_proposal.rs index c4d9a74dd4..04953fa029 100644 --- a/apps/src/lib/node/ledger/shell/prepare_proposal.rs +++ b/apps/src/lib/node/ledger/shell/prepare_proposal.rs @@ -2,6 +2,7 @@ use namada::ledger::storage::{DBIter, StorageHasher, DB}; use namada::proto::Tx; +use namada::types::internal::WrapperTxInQueue; use namada::types::transaction::tx_types::TxType; use namada::types::transaction::wrapper::wrapper_tx::PairingEngine; use namada::types::transaction::{AffineCurve, DecryptedTx, EllipticCurve}; @@ -97,13 +98,23 @@ where .collect(); // decrypt the wrapper txs included in the previous block - let decrypted_txs = self.storage.tx_queue.iter().map(|tx| { - Tx::from(match tx.decrypt(privkey) { - Ok(tx) => DecryptedTx::Decrypted(tx), - _ => DecryptedTx::Undecryptable(tx.clone()), - }) - .to_bytes() - }); + let decrypted_txs = self.storage.tx_queue.iter().map( + |WrapperTxInQueue { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow, + }| { + Tx::from(match tx.decrypt(privkey) { + Ok(tx) => DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: *has_valid_pow, + }, + _ => DecryptedTx::Undecryptable(tx.clone()), + }) + .to_bytes() + }, + ); #[cfg(feature = "abcipp")] let mut decrypted_txs: Vec<_> = decrypted_txs.map(record::add).collect(); @@ -221,6 +232,8 @@ mod test_prepare_proposal { 0.into(), tx, Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ) .try_to_vec() .expect("Test failed"), @@ -264,8 +277,11 @@ mod test_prepare_proposal { "wasm_code".as_bytes().to_owned(), Some(format!("transaction data: {}", i).as_bytes().to_owned()), ); - expected_decrypted - .push(Tx::from(DecryptedTx::Decrypted(tx.clone()))); + expected_decrypted.push(Tx::from(DecryptedTx::Decrypted { + tx: tx.clone(), + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, + })); let wrapper_tx = WrapperTx::new( Fee { amount: 0.into(), @@ -276,6 +292,8 @@ mod test_prepare_proposal { 0.into(), tx, Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); let wrapper = wrapper_tx.sign(&keypair).expect("Test failed"); shell.enqueue_tx(wrapper_tx); diff --git a/apps/src/lib/node/ledger/shell/process_proposal.rs b/apps/src/lib/node/ledger/shell/process_proposal.rs index 0c4a1f0a8e..4ba10d2bcb 100644 --- a/apps/src/lib/node/ledger/shell/process_proposal.rs +++ b/apps/src/lib/node/ledger/shell/process_proposal.rs @@ -1,6 +1,8 @@ //! Implementation of the ['VerifyHeader`], [`ProcessProposal`], //! and [`RevertProposal`] ABCI++ methods for the Shell +use namada::types::internal::WrapperTxInQueue; + use super::*; use crate::facade::tendermint_proto::abci::response_process_proposal::ProposalStatus; use crate::facade::tendermint_proto::abci::RequestProcessProposal; @@ -70,7 +72,7 @@ where pub(crate) fn process_single_tx<'a>( &self, tx_bytes: &[u8], - tx_queue_iter: &mut impl Iterator, + tx_queue_iter: &mut impl Iterator, ) -> TxResult { let tx = match Tx::try_from(tx_bytes) { Ok(tx) => tx, @@ -106,7 +108,11 @@ where .into(), }, TxType::Decrypted(tx) => match tx_queue_iter.next() { - Some(wrapper) => { + Some(WrapperTxInQueue { + tx: wrapper, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: _, + }) => { if wrapper.tx_hash != tx.hash_commitment() { TxResult { code: ErrorCodes::InvalidOrder.into(), @@ -162,7 +168,14 @@ where let balance = self.get_balance(&tx.fee.token, &fee_payer); - if Amount::from(MIN_FEE) <= balance { + // In testnets, tx is allowed to skip fees if it + // includes a valid PoW + #[cfg(not(feature = "mainnet"))] + let has_valid_pow = self.has_valid_pow_solution(&tx); + #[cfg(feature = "mainnet")] + let has_valid_pow = false; + + if has_valid_pow || Amount::from(MIN_FEE) <= balance { TxResult { code: ErrorCodes::Ok.into(), info: "Process proposal accepted this \ @@ -202,7 +215,7 @@ mod test_process_proposal { use namada::types::storage::Epoch; use namada::types::token::Amount; use namada::types::transaction::encrypted::EncryptedTx; - use namada::types::transaction::{EncryptionKey, Fee}; + use namada::types::transaction::{EncryptionKey, Fee, WrapperTx}; use super::*; use crate::facade::tendermint_proto::abci::RequestInitChain; @@ -231,6 +244,8 @@ mod test_process_proposal { 0.into(), tx, Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); let tx = Tx::new( vec![], @@ -278,6 +293,8 @@ mod test_process_proposal { 0.into(), tx, Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ) .sign(&keypair) .expect("Test failed"); @@ -360,6 +377,8 @@ mod test_process_proposal { 0.into(), tx, Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ) .sign(&keypair) .expect("Test failed"); @@ -422,6 +441,8 @@ mod test_process_proposal { 0.into(), tx, Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ) .sign(&keypair) .expect("Test failed"); @@ -470,9 +491,15 @@ mod test_process_proposal { 0.into(), tx.clone(), Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); shell.enqueue_tx(wrapper); - txs.push(Tx::from(TxType::Decrypted(DecryptedTx::Decrypted(tx)))); + txs.push(Tx::from(TxType::Decrypted(DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, + }))); } let req_1 = ProcessProposal { txs: vec![txs[0].to_bytes()], @@ -534,6 +561,8 @@ mod test_process_proposal { 0.into(), tx, Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); shell.enqueue_tx(wrapper.clone()); @@ -593,6 +622,8 @@ mod test_process_proposal { 0.into(), tx, Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); wrapper.tx_hash = Hash([0; 32]); @@ -646,6 +677,8 @@ mod test_process_proposal { gas_limit: 0.into(), inner_tx, tx_hash: hash_tx(&tx), + #[cfg(not(feature = "mainnet"))] + pow_solution: None, }; shell.enqueue_tx(wrapper.clone()); @@ -679,7 +712,11 @@ mod test_process_proposal { Some("transaction data".as_bytes().to_owned()), ); - let tx = Tx::from(TxType::Decrypted(DecryptedTx::Decrypted(tx))); + let tx = Tx::from(TxType::Decrypted(DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, + })); let request = ProcessProposal { txs: vec![tx.to_bytes()], diff --git a/core/src/proto/types.rs b/core/src/proto/types.rs index d7fbb49aad..40e343d1bf 100644 --- a/core/src/proto/types.rs +++ b/core/src/proto/types.rs @@ -284,7 +284,11 @@ impl From for ResponseDeliverTx { x } match process_tx(tx) { - Ok(TxType::Decrypted(DecryptedTx::Decrypted(tx))) => { + Ok(TxType::Decrypted(DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: _, + })) => { let empty_vec = vec![]; let tx_data = tx.data.as_ref().unwrap_or(&empty_vec); let signed = diff --git a/core/src/types/internal.rs b/core/src/types/internal.rs index 848c09bec1..8c85a4236e 100644 --- a/core/src/types/internal.rs +++ b/core/src/types/internal.rs @@ -48,25 +48,39 @@ impl From for HostEnvResult { mod tx_queue { use borsh::{BorshDeserialize, BorshSerialize}; - use crate::types::transaction::WrapperTx; + /// A wrapper for `crate::types::transaction::WrapperTx` to conditionally + /// add `has_valid_pow` flag for only used in testnets. + #[derive(Debug, Clone, BorshDeserialize, BorshSerialize)] + pub struct WrapperTxInQueue { + /// Wrapper tx + pub tx: crate::types::transaction::WrapperTx, + #[cfg(not(feature = "mainnet"))] + /// A PoW solution can be used to allow zero-fee testnet + /// transactions. + /// This is true when the wrapper of this tx contains a valid + /// `testnet_pow::Solution` + pub has_valid_pow: bool, + } #[derive(Default, Debug, Clone, BorshDeserialize, BorshSerialize)] /// Wrapper txs to be decrypted in the next block proposal - pub struct TxQueue(std::collections::VecDeque); + pub struct TxQueue(std::collections::VecDeque); impl TxQueue { /// Add a new wrapper at the back of the queue - pub fn push(&mut self, wrapper: WrapperTx) { + pub fn push(&mut self, wrapper: WrapperTxInQueue) { self.0.push_back(wrapper); } /// Remove the wrapper at the head of the queue - pub fn pop(&mut self) -> Option { + pub fn pop(&mut self) -> Option { self.0.pop_front() } /// Get an iterator over the queue - pub fn iter(&self) -> impl std::iter::Iterator { + pub fn iter( + &self, + ) -> impl std::iter::Iterator { self.0.iter() } @@ -79,4 +93,4 @@ mod tx_queue { } #[cfg(feature = "ferveo-tpke")] -pub use tx_queue::TxQueue; +pub use tx_queue::{TxQueue, WrapperTxInQueue}; diff --git a/core/src/types/transaction/decrypted.rs b/core/src/types/transaction/decrypted.rs index d0697dc18f..3ac49efc77 100644 --- a/core/src/types/transaction/decrypted.rs +++ b/core/src/types/transaction/decrypted.rs @@ -20,7 +20,22 @@ pub mod decrypted_tx { /// other validators to verify pub enum DecryptedTx { /// The decrypted payload - Decrypted(Tx), + Decrypted { + /// Inner tx. + // For some reason, we get `warning: fields `tx` and + // `has_valid_pow` are never read` even though they are being used! + #[allow(dead_code)] + tx: Tx, + #[cfg(not(feature = "mainnet"))] + /// A PoW solution can be used to allow zero-fee testnet + /// transactions. + /// This is true when the wrapper of this tx contains a valid + /// `testnet_pow::Solution`. + // For some reason, we get `warning: fields `tx` and + // `has_valid_pow` are never read` even though they are being used! + #[allow(dead_code)] + has_valid_pow: bool, + }, /// The wrapper whose payload could not be decrypted Undecryptable(WrapperTx), } @@ -29,7 +44,11 @@ pub mod decrypted_tx { /// Convert the inner tx value to bytes pub fn to_bytes(&self) -> Vec { match self { - DecryptedTx::Decrypted(tx) => tx.to_bytes(), + DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: _, + } => tx.to_bytes(), DecryptedTx::Undecryptable(wrapper) => { wrapper.try_to_vec().unwrap() } @@ -40,7 +59,11 @@ pub mod decrypted_tx { /// wrapper tx that includes this tx as an encrypted payload. pub fn hash_commitment(&self) -> Hash { match self { - DecryptedTx::Decrypted(tx) => hash_tx(&tx.to_bytes()), + DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: _, + } => hash_tx(&tx.to_bytes()), DecryptedTx::Undecryptable(wrapper) => wrapper.tx_hash.clone(), } } @@ -54,7 +77,7 @@ pub mod decrypted_tx { privkey: ::G2Affine, ) -> bool { match decrypted { - DecryptedTx::Decrypted(_) => true, + DecryptedTx::Decrypted { .. } => true, DecryptedTx::Undecryptable(tx) => tx.decrypt(privkey).is_err(), } } diff --git a/core/src/types/transaction/mod.rs b/core/src/types/transaction/mod.rs index 69b212f4c8..0e0a5e980e 100644 --- a/core/src/types/transaction/mod.rs +++ b/core/src/types/transaction/mod.rs @@ -431,6 +431,8 @@ pub mod tx_types { 0.into(), tx.clone(), Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ) .sign(&keypair) .expect("Test failed"); @@ -466,6 +468,8 @@ pub mod tx_types { 0.into(), tx, Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); let tx = Tx::new( @@ -487,10 +491,18 @@ pub mod tx_types { "transaction data".as_bytes().to_owned(), Some("transaction data".as_bytes().to_owned()), ); - let decrypted = DecryptedTx::Decrypted(payload.clone()); + let decrypted = DecryptedTx::Decrypted { + tx: payload.clone(), + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, + }; let tx = Tx::from(TxType::Decrypted(decrypted)); match process_tx(tx).expect("Test failed") { - TxType::Decrypted(DecryptedTx::Decrypted(processed)) => { + TxType::Decrypted(DecryptedTx::Decrypted { + tx: processed, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: _, + }) => { assert_eq!(payload, processed); } _ => panic!("Test failed"), @@ -506,7 +518,11 @@ pub mod tx_types { "transaction data".as_bytes().to_owned(), Some("transaction data".as_bytes().to_owned()), ); - let decrypted = DecryptedTx::Decrypted(payload.clone()); + let decrypted = DecryptedTx::Decrypted { + tx: payload.clone(), + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, + }; // Invalid signed data let ed_sig = ed25519::Signature::try_from_slice([0u8; 64].as_ref()).unwrap(); @@ -522,7 +538,11 @@ pub mod tx_types { let tx = Tx::new(vec![], Some(signed.try_to_vec().expect("Test failed"))); match process_tx(tx).expect("Test failed") { - TxType::Decrypted(DecryptedTx::Decrypted(processed)) => { + TxType::Decrypted(DecryptedTx::Decrypted { + tx: processed, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: _, + }) => { assert_eq!(payload, processed); } _ => panic!("Test failed"), diff --git a/core/src/types/transaction/wrapper.rs b/core/src/types/transaction/wrapper.rs index 7d9493960d..70ef2827bc 100644 --- a/core/src/types/transaction/wrapper.rs +++ b/core/src/types/transaction/wrapper.rs @@ -178,6 +178,9 @@ pub mod wrapper_tx { /// sha-2 hash of the inner transaction acting as a commitment /// the contents of the encrypted payload pub tx_hash: Hash, + #[cfg(not(feature = "mainnet"))] + /// A PoW solution can be used to allow zero-fee testnet transactions + pub pow_solution: Option, } impl WrapperTx { @@ -192,6 +195,9 @@ pub mod wrapper_tx { gas_limit: GasLimit, tx: Tx, encryption_key: EncryptionKey, + #[cfg(not(feature = "mainnet"))] pow_solution: Option< + crate::ledger::testnet_pow::Solution, + >, ) -> WrapperTx { let inner_tx = EncryptedTx::encrypt(&tx.to_bytes(), encryption_key); Self { @@ -201,6 +207,8 @@ pub mod wrapper_tx { gas_limit, inner_tx, tx_hash: hash_tx(&tx.to_bytes()), + #[cfg(not(feature = "mainnet"))] + pow_solution, } } @@ -369,6 +377,8 @@ pub mod wrapper_tx { 0.into(), tx.clone(), Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); assert!(wrapper.validate_ciphertext()); let privkey = ::G2Affine::prime_subgroup_generator(); @@ -395,6 +405,8 @@ pub mod wrapper_tx { 0.into(), tx, Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ); // give a incorrect commitment to the decrypted contents of the tx wrapper.tx_hash = Hash([0u8; 32]); @@ -427,6 +439,8 @@ pub mod wrapper_tx { 0.into(), tx, Default::default(), + #[cfg(not(feature = "mainnet"))] + None, ) .sign(&keypair) .expect("Test failed"); diff --git a/shared/src/ledger/protocol/mod.rs b/shared/src/ledger/protocol/mod.rs index edb801700b..6c237e5b46 100644 --- a/shared/src/ledger/protocol/mod.rs +++ b/shared/src/ledger/protocol/mod.rs @@ -92,7 +92,11 @@ where .map_err(Error::GasError)?; match tx { TxType::Raw(_) => Err(Error::TxTypeError), - TxType::Decrypted(DecryptedTx::Decrypted(tx)) => { + TxType::Decrypted(DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow, + }) => { let verifiers = execute_tx( &tx, &tx_index, diff --git a/shared/src/ledger/queries/shell.rs b/shared/src/ledger/queries/shell.rs index 4883294c78..61f43a6289 100644 --- a/shared/src/ledger/queries/shell.rs +++ b/shared/src/ledger/queries/shell.rs @@ -79,7 +79,11 @@ where let mut gas_meter = BlockGasMeter::default(); let mut write_log = WriteLog::default(); let tx = Tx::try_from(&request.data[..]).into_storage_result()?; - let tx = TxType::Decrypted(DecryptedTx::Decrypted(tx)); + let tx = TxType::Decrypted(DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: true, + }); let data = protocol::apply_tx( tx, request.data.len(), From c22a8e1902daa4c24b28d6ab8efd59e4bf7c0298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 30 Dec 2022 11:58:20 +0100 Subject: [PATCH 149/166] expose the `has_valid_pow` result via VP wasm host env --- shared/src/ledger/native_vp/mod.rs | 2 ++ shared/src/ledger/protocol/mod.rs | 15 +++++++++++ shared/src/vm/host_env.rs | 42 ++++++++++++++++++++++++++++++ shared/src/vm/wasm/host_env.rs | 1 + shared/src/vm/wasm/run.rs | 19 ++++++++++++++ tests/src/vm_host_env/vp.rs | 21 ++++++++++++--- vm_env/src/lib.rs | 2 ++ vp_prelude/src/lib.rs | 8 +++++- 8 files changed, 105 insertions(+), 5 deletions(-) diff --git a/shared/src/ledger/native_vp/mod.rs b/shared/src/ledger/native_vp/mod.rs index 0907c1cc38..e14378c3d3 100644 --- a/shared/src/ledger/native_vp/mod.rs +++ b/shared/src/ledger/native_vp/mod.rs @@ -469,6 +469,8 @@ where self.keys_changed, &eval_runner, &mut vp_wasm_cache, + #[cfg(not(feature = "mainnet"))] + false, ); match eval_runner.eval_native_result(ctx, vp_code, input_data) { Ok(result) => Ok(result), diff --git a/shared/src/ledger/protocol/mod.rs b/shared/src/ledger/protocol/mod.rs index 6c237e5b46..cfd416c14d 100644 --- a/shared/src/ledger/protocol/mod.rs +++ b/shared/src/ledger/protocol/mod.rs @@ -115,6 +115,8 @@ where write_log, &verifiers, vp_wasm_cache, + #[cfg(not(feature = "mainnet"))] + has_valid_pow, )?; let gas_used = block_gas_meter @@ -178,6 +180,7 @@ where } /// Check the acceptance of a transaction by validity predicates +#[allow(clippy::too_many_arguments)] fn check_vps( tx: &Tx, tx_index: &TxIndex, @@ -186,6 +189,10 @@ fn check_vps( write_log: &WriteLog, verifiers_from_tx: &BTreeSet
, vp_wasm_cache: &mut VpCache, + #[cfg(not(feature = "mainnet"))] + // This is true when the wrapper of this tx contained a valid + // `testnet_pow::Solution` + has_valid_pow: bool, ) -> Result where D: 'static + DB + for<'iter> DBIter<'iter> + Sync, @@ -206,6 +213,8 @@ where write_log, initial_gas, vp_wasm_cache, + #[cfg(not(feature = "mainnet"))] + has_valid_pow, )?; tracing::debug!("Total VPs gas cost {:?}", vps_result.gas_used); @@ -227,6 +236,10 @@ fn execute_vps( write_log: &WriteLog, initial_gas: u64, vp_wasm_cache: &mut VpCache, + #[cfg(not(feature = "mainnet"))] + // This is true when the wrapper of this tx contained a valid + // `testnet_pow::Solution` + has_valid_pow: bool, ) -> Result where D: 'static + DB + for<'iter> DBIter<'iter> + Sync, @@ -261,6 +274,8 @@ where &keys_changed, &verifiers, vp_wasm_cache.clone(), + #[cfg(not(feature = "mainnet"))] + has_valid_pow, ) .map_err(Error::VpRunnerError) } diff --git a/shared/src/vm/host_env.rs b/shared/src/vm/host_env.rs index c6d572d8db..ee8e8a3601 100644 --- a/shared/src/vm/host_env.rs +++ b/shared/src/vm/host_env.rs @@ -261,6 +261,10 @@ where /// To avoid unused parameter without "wasm-runtime" feature #[cfg(not(feature = "wasm-runtime"))] pub cache_access: std::marker::PhantomData, + #[cfg(not(feature = "mainnet"))] + /// This is true when the wrapper of this tx contained a valid + /// `testnet_pow::Solution` + has_valid_pow: bool, } /// A Validity predicate runner for calls from the [`vp_eval`] function. @@ -317,6 +321,7 @@ where keys_changed: &BTreeSet, eval_runner: &EVAL, #[cfg(feature = "wasm-runtime")] vp_wasm_cache: &mut VpCache, + #[cfg(not(feature = "mainnet"))] has_valid_pow: bool, ) -> Self { let ctx = VpCtx::new( address, @@ -332,6 +337,8 @@ where eval_runner, #[cfg(feature = "wasm-runtime")] vp_wasm_cache, + #[cfg(not(feature = "mainnet"))] + has_valid_pow, ); Self { memory, ctx } @@ -382,6 +389,7 @@ where keys_changed: &BTreeSet, eval_runner: &EVAL, #[cfg(feature = "wasm-runtime")] vp_wasm_cache: &mut VpCache, + #[cfg(not(feature = "mainnet"))] has_valid_pow: bool, ) -> Self { let address = unsafe { HostRef::new(address) }; let storage = unsafe { HostRef::new(storage) }; @@ -412,6 +420,8 @@ where vp_wasm_cache, #[cfg(not(feature = "wasm-runtime"))] cache_access: std::marker::PhantomData, + #[cfg(not(feature = "mainnet"))] + has_valid_pow, } } } @@ -440,6 +450,8 @@ where vp_wasm_cache: self.vp_wasm_cache.clone(), #[cfg(not(feature = "wasm-runtime"))] cache_access: std::marker::PhantomData, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: self.has_valid_pow, } } } @@ -1874,6 +1886,33 @@ where vp_host_fns::add_gas(gas_meter, gas) } +/// Find if the wrapper tx had a valid `testnet_pow::Solution` +pub fn vp_has_valid_pow( + env: &VpVmEnv, +) -> vp_host_fns::EnvResult +where + MEM: VmMemory, + DB: storage::DB + for<'iter> storage::DBIter<'iter>, + H: StorageHasher, + EVAL: VpEvaluator, + CA: WasmCacheAccess, +{ + #[cfg(feature = "mainnet")] + let _ = env; + + #[cfg(not(feature = "mainnet"))] + let has_valid_pow = env.ctx.has_valid_pow; + #[cfg(feature = "mainnet")] + let has_valid_pow = false; + + Ok(if has_valid_pow { + HostEnvResult::Success + } else { + HostEnvResult::Fail + } + .to_i64()) +} + /// Log a string from exposed to the wasm VM VP environment. The message will be /// printed at the [`tracing::Level::INFO`]. This function is for development /// only. @@ -1955,6 +1994,7 @@ pub mod testing { keys_changed: &BTreeSet, eval_runner: &EVAL, #[cfg(feature = "wasm-runtime")] vp_wasm_cache: &mut VpCache, + #[cfg(not(feature = "mainnet"))] has_valid_pow: bool, ) -> VpVmEnv<'static, NativeMemory, DB, H, EVAL, CA> where DB: 'static + storage::DB + for<'iter> storage::DBIter<'iter>, @@ -1977,6 +2017,8 @@ pub mod testing { eval_runner, #[cfg(feature = "wasm-runtime")] vp_wasm_cache, + #[cfg(not(feature = "mainnet"))] + has_valid_pow, ) } } diff --git a/shared/src/vm/wasm/host_env.rs b/shared/src/vm/wasm/host_env.rs index b9eeffecfc..28fb2cc12a 100644 --- a/shared/src/vm/wasm/host_env.rs +++ b/shared/src/vm/wasm/host_env.rs @@ -121,6 +121,7 @@ where "namada_vp_verify_masp" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_verify_masp), "namada_vp_eval" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_eval), "namada_vp_get_native_token" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_get_native_token), + "namada_vp_has_valid_pow" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_has_valid_pow), "namada_vp_log_string" => Function::new_native_with_env(wasm_store, env.clone(), host_env::vp_log_string), }, } diff --git a/shared/src/vm/wasm/run.rs b/shared/src/vm/wasm/run.rs index 103f92a75c..233a5f72a0 100644 --- a/shared/src/vm/wasm/run.rs +++ b/shared/src/vm/wasm/run.rs @@ -167,6 +167,7 @@ pub fn vp( keys_changed: &BTreeSet, verifiers: &BTreeSet
, mut vp_wasm_cache: VpCache, + #[cfg(not(feature = "mainnet"))] has_valid_pow: bool, ) -> Result where DB: 'static + storage::DB + for<'iter> storage::DBIter<'iter>, @@ -208,6 +209,8 @@ where keys_changed, &eval_runner, &mut vp_wasm_cache, + #[cfg(not(feature = "mainnet"))] + has_valid_pow, ); let initial_memory = @@ -562,6 +565,8 @@ mod tests { &keys_changed, &verifiers, vp_cache.clone(), + #[cfg(not(feature = "mainnet"))] + false, ) .unwrap(); assert!(passed); @@ -589,6 +594,8 @@ mod tests { &keys_changed, &verifiers, vp_cache, + #[cfg(not(feature = "mainnet"))] + false, ) .unwrap(); @@ -630,6 +637,8 @@ mod tests { &keys_changed, &verifiers, vp_cache.clone(), + #[cfg(not(feature = "mainnet"))] + false, ); assert!(result.is_ok(), "Expected success, got {:?}", result); @@ -648,6 +657,8 @@ mod tests { &keys_changed, &verifiers, vp_cache, + #[cfg(not(feature = "mainnet"))] + false, ) .expect_err("Expected to run out of memory"); @@ -740,6 +751,8 @@ mod tests { &keys_changed, &verifiers, vp_cache, + #[cfg(not(feature = "mainnet"))] + false, ); // Depending on platform, we get a different error from the running out // of memory @@ -847,6 +860,8 @@ mod tests { &keys_changed, &verifiers, vp_cache, + #[cfg(not(feature = "mainnet"))] + false, ) .expect_err("Expected to run out of memory"); @@ -903,6 +918,8 @@ mod tests { &keys_changed, &verifiers, vp_cache, + #[cfg(not(feature = "mainnet"))] + false, ) .unwrap(); assert!(!passed); @@ -1013,6 +1030,8 @@ mod tests { &keys_changed, &verifiers, vp_cache, + #[cfg(not(feature = "mainnet"))] + false, ) } diff --git a/tests/src/vm_host_env/vp.rs b/tests/src/vm_host_env/vp.rs index a88176d182..88d9d6ca3c 100644 --- a/tests/src/vm_host_env/vp.rs +++ b/tests/src/vm_host_env/vp.rs @@ -49,6 +49,8 @@ pub struct TestVpEnv { pub result_buffer: Option>, pub vp_wasm_cache: VpCache, pub vp_cache_dir: TempDir, + #[cfg(not(feature = "mainnet"))] + pub has_valid_pow: bool, } impl Default for TestVpEnv { @@ -75,6 +77,8 @@ impl Default for TestVpEnv { result_buffer: None, vp_wasm_cache, vp_cache_dir, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, } } } @@ -246,14 +250,16 @@ mod native_vp_host_env { write_log, iterators, gas_meter, - tx, - tx_index, + tx, + tx_index, keys_changed, verifiers, eval_runner, result_buffer, vp_wasm_cache, vp_cache_dir: _, + #[cfg(not(feature = "mainnet"))] + has_valid_pow, }: &mut TestVpEnv| { let env = vm::host_env::testing::vp_env( @@ -269,6 +275,8 @@ mod native_vp_host_env { keys_changed, eval_runner, vp_wasm_cache, + #[cfg(not(feature = "mainnet"))] + *has_valid_pow, ); // Call the `host_env` function and unwrap any @@ -290,14 +298,16 @@ mod native_vp_host_env { write_log, iterators, gas_meter, - tx, - tx_index, + tx, + tx_index, keys_changed, verifiers, eval_runner, result_buffer, vp_wasm_cache, vp_cache_dir: _, + #[cfg(not(feature = "mainnet"))] + has_valid_pow, }: &mut TestVpEnv| { let env = vm::host_env::testing::vp_env( @@ -313,6 +323,8 @@ mod native_vp_host_env { keys_changed, eval_runner, vp_wasm_cache, + #[cfg(not(feature = "mainnet"))] + *has_valid_pow, ); // Call the `host_env` function and unwrap any @@ -353,5 +365,6 @@ mod native_vp_host_env { input_data_ptr: u64, input_data_len: u64, ) -> i64); + native_host_fn!(vp_has_valid_pow() -> i64); native_host_fn!(vp_log_string(str_ptr: u64, str_len: u64)); } diff --git a/vm_env/src/lib.rs b/vm_env/src/lib.rs index e328a8748c..b38feb83f2 100644 --- a/vm_env/src/lib.rs +++ b/vm_env/src/lib.rs @@ -197,6 +197,8 @@ pub mod vp { ) -> i64; pub fn namada_vp_verify_masp(tx_ptr: u64, tx_len: u64) -> i64; + + pub fn namada_vp_has_valid_pow() -> i64; } } diff --git a/vp_prelude/src/lib.rs b/vp_prelude/src/lib.rs index 58ee37e756..d67f0d980b 100644 --- a/vp_prelude/src/lib.rs +++ b/vp_prelude/src/lib.rs @@ -18,12 +18,12 @@ use std::marker::PhantomData; pub use borsh::{BorshDeserialize, BorshSerialize}; pub use namada_core::ledger::governance::storage as gov_storage; -pub use namada_core::ledger::parameters; pub use namada_core::ledger::storage_api::{ self, iter_prefix, iter_prefix_bytes, Error, OptionExt, ResultExt, StorageRead, }; pub use namada_core::ledger::vp_env::VpEnv; +pub use namada_core::ledger::{parameters, testnet_pow}; pub use namada_core::proto::{Signed, SignedTxData}; pub use namada_core::types::address::Address; use namada_core::types::chain::CHAIN_ID_LENGTH; @@ -152,6 +152,12 @@ impl Ctx { pub fn post(&self) -> CtxPostStorageRead<'_> { CtxPostStorageRead { _ctx: self } } + + /// Check if the wrapper tx contained a valid testnet PoW + pub fn has_valid_pow(&self) -> bool { + let valid = unsafe { namada_vp_has_valid_pow() }; + HostEnvResult::is_success(valid) + } } /// Read access to the prior storage (state before tx execution) via From fff5b1e3c01ddd6079b25d3331adb243c05608ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 30 Dec 2022 11:58:57 +0100 Subject: [PATCH 150/166] wasm/vp_testnet_faucet: check PoW, use withdrawal_limit set in storage --- wasm/wasm_source/src/vp_testnet_faucet.rs | 85 +++++++++++++++++++---- 1 file changed, 70 insertions(+), 15 deletions(-) diff --git a/wasm/wasm_source/src/vp_testnet_faucet.rs b/wasm/wasm_source/src/vp_testnet_faucet.rs index 4ae7ddad71..8e4e79719f 100644 --- a/wasm/wasm_source/src/vp_testnet_faucet.rs +++ b/wasm/wasm_source/src/vp_testnet_faucet.rs @@ -1,16 +1,14 @@ //! A "faucet" account for testnet. //! -//! This VP allows anyone to withdraw up to [`MAX_FREE_DEBIT`] tokens without -//! the faucet's signature. +//! This VP allows anyone to withdraw up to +//! [`testnet_pow::read_withdrawal_limit`] tokens without the faucet's +//! signature, but with a valid PoW challenge solution that cannot be replayed. //! //! Any other storage key changes are allowed only with a valid signature. -use namada_vp_prelude::{SignedTxData, *}; +use namada_vp_prelude::*; use once_cell::unsync::Lazy; -/// Allows anyone to withdraw up to 1_000 tokens in a single tx -pub const MAX_FREE_DEBIT: i128 = 1_000_000_000; // in micro units - #[validity_predicate] fn validate_tx( ctx: &Ctx, @@ -58,10 +56,27 @@ fn validate_tx( let post: token::Amount = ctx.read_post(key)?.unwrap_or_default(); let change = post.change() - pre.change(); - // Debit over `MAX_FREE_DEBIT` has to signed, credit doesn't - change >= -MAX_FREE_DEBIT || change >= 0 || *valid_sig + + if change < 0 { + // Allow to withdraw without a sig if there's a valid PoW + if ctx.has_valid_pow() { + let max_free_debit = + testnet_pow::read_withdrawal_limit( + &ctx.pre(), + &addr, + )?; + change >= -max_free_debit.change() + } else { + debug_log!("No PoW solution, a signature is required"); + // Debit without a solution has to signed + *valid_sig + } + } else { + // credit is permissive + true + } } else { - // If this is not the owner, allow any change + // balance changes of other accounts true } } else if let Some(owner) = key.is_validity_predicate() { @@ -81,11 +96,13 @@ fn validate_tx( // Allow any other key change if authorized by a signature *valid_sig }; + if !is_valid { debug_log!("key {} modification failed vp", key); return reject(); } } + accept() } @@ -98,7 +115,7 @@ mod tests { use namada_tests::vp::vp_host_env::storage::Key; use namada_tests::vp::*; use namada_tx_prelude::{StorageWrite, TxEnv}; - use namada_vp_prelude::key::RefTo; + use namada_vp_prelude::key::{RefTo, SigScheme}; use proptest::prelude::*; use storage::testing::arb_account_storage_key_no_vp; @@ -107,6 +124,9 @@ mod tests { const VP_ALWAYS_TRUE_WASM: &str = "../../wasm_for_tests/vp_always_true.wasm"; + /// Allows anyone to withdraw up to 1_000 tokens in a single tx + pub const MAX_FREE_DEBIT: i128 = 1_000_000_000; // in micro units + /// Test that no-op transaction (i.e. no storage modifications) accepted. #[test] fn test_no_op_transaction() { @@ -267,7 +287,12 @@ mod tests { // Initialize a tx environment let mut tx_env = TestTxEnv::default(); + // Init the VP let vp_owner = address::testing::established_address_1(); + let difficulty = testnet_pow::Difficulty::try_new(0).unwrap(); + let withdrawal_limit = token::Amount::from(MAX_FREE_DEBIT as u64); + testnet_pow::init_faucet_storage(&mut tx_env.storage, &vp_owner, difficulty, withdrawal_limit).unwrap(); + let target = address::testing::established_address_2(); let token = address::nam(); let amount = token::Amount::from(amount); @@ -294,14 +319,21 @@ mod tests { assert!(!validate_tx(&CTX, tx_data, vp_owner, keys_changed, verifiers).unwrap()); } - /// Test that a debit of less than or equal to [`MAX_FREE_DEBIT`] tokens without a valid signature is accepted. + /// Test that a debit of less than or equal to [`MAX_FREE_DEBIT`] tokens + /// without a valid signature but with a valid PoW solution is accepted. #[test] fn test_unsigned_debit_under_limit_accepted(amount in (..MAX_FREE_DEBIT as u64 + 1)) { // Initialize a tx environment let mut tx_env = TestTxEnv::default(); + // Init the VP let vp_owner = address::testing::established_address_1(); + let difficulty = testnet_pow::Difficulty::try_new(0).unwrap(); + let withdrawal_limit = token::Amount::from(MAX_FREE_DEBIT as u64); + testnet_pow::init_faucet_storage(&mut tx_env.storage, &vp_owner, difficulty, withdrawal_limit).unwrap(); + let target = address::testing::established_address_2(); + let target_key = key::testing::keypair_1(); let token = address::nam(); let amount = token::Amount::from(amount); @@ -312,14 +344,32 @@ mod tests { // be able to transfer from it tx_env.credit_tokens(&vp_owner, &token, None, amount); + // Construct a PoW solution like a client would + let challenge = testnet_pow::Challenge::new(&mut tx_env.storage, &vp_owner, target.clone()).unwrap(); + let solution = challenge.solve(); + let solution_bytes = solution.try_to_vec().unwrap(); + // The signature itself doesn't matter and is not being checked in this + // test, it's just used to construct `SignedTxData` + let sig = key::common::SigScheme::sign(&target_key, &solution_bytes); + let signed_solution = SignedTxData { + data: Some(solution_bytes), + sig, + }; + // Initialize VP environment from a transaction vp_host_env::init_from_tx(vp_owner.clone(), tx_env, |address| { - // Apply transfer in a transaction - tx_host_env::token::transfer(tx::ctx(), address, &target, &token, None, amount, &None, &None).unwrap(); + // Don't call `Solution::invalidate_if_valid` - this is done by the + // shell's finalize_block. + let valid = solution.validate(tx::ctx(), address, target.clone()).unwrap(); + assert!(valid); + // Apply transfer in a transaction + tx_host_env::token::transfer(tx::ctx(), address, &target, &token, None, amount, &None, &None).unwrap(); }); - let vp_env = vp_host_env::take(); - let tx_data: Vec = vec![]; + let mut vp_env = vp_host_env::take(); + // This is set by the protocol when the wrapper tx has a valid PoW + vp_env.has_valid_pow = true; + let tx_data: Vec = signed_solution.try_to_vec().unwrap(); let keys_changed: BTreeSet = vp_env.all_touched_storage_keys(); let verifiers: BTreeSet
= BTreeSet::default(); @@ -338,6 +388,11 @@ mod tests { // Initialize a tx environment let mut tx_env = TestTxEnv::default(); + // Init the VP + let difficulty = testnet_pow::Difficulty::try_new(0).unwrap(); + let withdrawal_limit = token::Amount::from(MAX_FREE_DEBIT as u64); + testnet_pow::init_faucet_storage(&mut tx_env.storage, &vp_owner, difficulty, withdrawal_limit).unwrap(); + let keypair = key::testing::keypair_1(); let public_key = &keypair.ref_to(); From bb85eafa7accfcfae649988be8eeea3b68ae6d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 30 Dec 2022 11:59:37 +0100 Subject: [PATCH 151/166] ledger/queries/vp: add testnet pow and faucet methods --- apps/src/lib/client/rpc.rs | 34 ++++++++ shared/src/ledger/queries/vp/mod.rs | 131 ++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) diff --git a/apps/src/lib/client/rpc.rs b/apps/src/lib/client/rpc.rs index 91bdee5831..ab64ce948d 100644 --- a/apps/src/lib/client/rpc.rs +++ b/apps/src/lib/client/rpc.rs @@ -22,6 +22,8 @@ use masp_primitives::primitives::ViewingKey; use masp_primitives::sapling::Node; use masp_primitives::transaction::components::Amount; use masp_primitives::zip32::ExtendedFullViewingKey; +#[cfg(not(feature = "mainnet"))] +use namada::core::ledger::testnet_pow; use namada::ledger::events::Event; use namada::ledger::governance::parameters::GovParams; use namada::ledger::governance::storage as gov_storage; @@ -2013,6 +2015,38 @@ pub async fn known_address( } } +#[cfg(not(feature = "mainnet"))] +/// Check if the given address is a testnet faucet account address. +pub async fn is_faucet_account( + address: &Address, + ledger_address: TendermintAddress, +) -> bool { + let client = HttpClient::new(ledger_address).unwrap(); + unwrap_client_response(RPC.vp().is_faucet(&client, address).await) +} + +#[cfg(not(feature = "mainnet"))] +/// Get faucet account address, if any is setup for the network. +pub async fn get_faucet_address( + ledger_address: TendermintAddress, +) -> Option
{ + let client = HttpClient::new(ledger_address).unwrap(); + unwrap_client_response(RPC.vp().get_faucet_address(&client).await) +} + +#[cfg(not(feature = "mainnet"))] +/// Obtain a PoW challenge for a withdrawal from a testnet faucet account, if +/// any is setup for the network. +pub async fn get_testnet_pow_challenge( + source: Address, + ledger_address: TendermintAddress, +) -> testnet_pow::Challenge { + let client = HttpClient::new(ledger_address).unwrap(); + unwrap_client_response( + RPC.vp().testnet_pow_challenge(&client, source).await, + ) +} + /// Accumulate slashes starting from `epoch_start` until (optionally) /// `withdraw_epoch` and apply them to the token amount `delta`. fn apply_slashes( diff --git a/shared/src/ledger/queries/vp/mod.rs b/shared/src/ledger/queries/vp/mod.rs index a4de26e20b..5f5b5f6081 100644 --- a/shared/src/ledger/queries/vp/mod.rs +++ b/shared/src/ledger/queries/vp/mod.rs @@ -7,3 +7,134 @@ mod pos; router! {VP, ( "pos" ) = (sub POS), } + +#[cfg(any(test, feature = "async-client"))] +pub mod client_only_methods { + #[cfg(not(feature = "mainnet"))] + use borsh::BorshDeserialize; + #[cfg(not(feature = "mainnet"))] + use namada_core::ledger::testnet_pow; + + use super::Vp; + #[cfg(not(feature = "mainnet"))] + use crate::ledger::queries::{Client, RPC}; + #[cfg(not(feature = "mainnet"))] + use crate::types::address::Address; + + impl Vp { + #[cfg(not(feature = "mainnet"))] + /// Get faucet account address, if any is setup for the network. + pub async fn get_faucet_address( + &self, + client: &CLIENT, + ) -> Result, ::Error> + where + CLIENT: Client + Sync, + { + let faucet_account_key = namada_core::ledger::parameters::storage::get_faucet_account_key(); + if RPC + .shell() + .storage_has_key(client, &faucet_account_key) + .await? + { + let faucet_account = Address::try_from_slice( + &RPC.shell() + .storage_value( + client, + None, + None, + false, + &faucet_account_key, + ) + .await? + .data, + ) + .expect("Faucet address couldn't be read"); + Ok(Some(faucet_account)) + } else { + Ok(None) + } + } + + #[cfg(not(feature = "mainnet"))] + /// Check if the given address is a faucet account address. + pub async fn is_faucet( + &self, + client: &CLIENT, + address: &Address, + ) -> Result::Error> + where + CLIENT: Client + Sync, + { + if let Some(faucet_address) = + self.get_faucet_address(client).await? + { + Ok(address == &faucet_address) + } else { + Ok(false) + } + } + + #[cfg(not(feature = "mainnet"))] + /// Get a faucet PoW challenge for token withdrawal. + pub async fn testnet_pow_challenge( + &self, + client: &CLIENT, + source: Address, + ) -> Result::Error> + where + CLIENT: Client + Sync, + { + let params = self.testnet_pow_params(client, &source).await?; + Ok(testnet_pow::Challenge { source, params }) + } + + #[cfg(not(feature = "mainnet"))] + /// Read faucet PoW challenge parameters for token withdrawal. + pub async fn testnet_pow_params( + &self, + client: &CLIENT, + source: &Address, + ) -> Result::Error> + where + CLIENT: Client + Sync, + { + let faucet_address = self + .get_faucet_address(client) + .await? + .expect("No faucet account found"); + let difficulty_key = &testnet_pow::difficulty_key(&faucet_address); + let counter_key = &testnet_pow::counters_handle(&faucet_address) + .get_data_key(source); + let difficulty = testnet_pow::Difficulty::try_from_slice( + &RPC.shell() + .storage_value(client, None, None, false, difficulty_key) + .await? + .data, + ) + .expect("Faucet PoW difficulty couldn't be read"); + let counter = if RPC + .shell() + .storage_has_key(client, counter_key) + .await? + { + testnet_pow::Counter::try_from_slice( + &RPC.shell() + .storage_value(client, None, None, false, counter_key) + .await? + .data, + ) + .expect("Faucet counter has unexpected encoding") + } else { + // `0` if not previously set (same as + // `testnet_pow::get_counter`) + testnet_pow::Counter::default() + }; + + Ok(testnet_pow::ChallengeParams { + difficulty, + counter, + }) + } + } +} From 50630e35714f1275a395801b7fdfb625a5288f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 30 Dec 2022 12:01:06 +0100 Subject: [PATCH 152/166] client/tx and signing: add wrapper signer balance check and add PoW --- apps/src/lib/client/signing.rs | 62 ++++++++++++++++- apps/src/lib/client/tx.rs | 117 ++++++++++++++++++++++++++++----- 2 files changed, 158 insertions(+), 21 deletions(-) diff --git a/apps/src/lib/client/signing.rs b/apps/src/lib/client/signing.rs index 6d61cfa9ce..c35f9aef6d 100644 --- a/apps/src/lib/client/signing.rs +++ b/apps/src/lib/client/signing.rs @@ -6,6 +6,7 @@ use namada::proto::Tx; use namada::types::address::{Address, ImplicitAddress}; use namada::types::key::*; use namada::types::storage::Epoch; +use namada::types::token; use namada::types::token::Amount; use namada::types::transaction::{hash_tx, Fee, WrapperTx, MIN_FEE}; @@ -14,6 +15,7 @@ use crate::cli::context::{WalletAddress, WalletKeypair}; use crate::cli::{self, args, Context}; use crate::client::tendermint_rpc_types::TxBroadcastData; use crate::facade::tendermint_config::net::Address as TendermintAddress; +use crate::facade::tendermint_rpc::HttpClient; use crate::wallet::Wallet; /// Find the public key for the given address and try to load the keypair @@ -146,6 +148,7 @@ pub async fn sign_tx( tx: Tx, args: &args::Tx, default: TxSigningKey, + #[cfg(not(feature = "mainnet"))] requires_pow: bool, ) -> (Context, TxBroadcastData) { let keypair = tx_signer(&mut ctx, args, default).await; let tx = tx.sign(&keypair); @@ -157,7 +160,16 @@ pub async fn sign_tx( let broadcast_data = if args.dry_run { TxBroadcastData::DryRun(tx) } else { - sign_wrapper(&ctx, args, epoch, tx, &keypair).await + sign_wrapper( + &ctx, + args, + epoch, + tx, + &keypair, + #[cfg(not(feature = "mainnet"))] + requires_pow, + ) + .await }; (ctx, broadcast_data) } @@ -171,12 +183,54 @@ pub async fn sign_wrapper( epoch: Epoch, tx: Tx, keypair: &common::SecretKey, + #[cfg(not(feature = "mainnet"))] requires_pow: bool, ) -> TxBroadcastData { + let fee_amount = Amount::from(MIN_FEE); + let fee_token = ctx.get(&args.fee_token); + let source = Address::from(&keypair.ref_to()); + let balance_key = token::balance_key(&fee_token, &source); + let client = HttpClient::new(args.ledger_address.clone()).unwrap(); + let balance = + rpc::query_storage_value::(&client, &balance_key) + .await + .unwrap_or_default(); + if balance < fee_amount { + eprintln!( + "The wrapper transaction source doesn't have enough balance to \ + pay fee {fee_amount}, got {balance}." + ); + if !args.force && cfg!(feature = "mainnet") { + cli::safe_exit(1); + } + } + + #[cfg(not(feature = "mainnet"))] + // A PoW solution can be used to allow zero-fee testnet transactions + let pow_solution: Option = { + // If the address derived from the keypair doesn't have enough balance + // to pay for the fee, allow to find a PoW solution instead. + if requires_pow || balance < fee_amount { + println!("The transaction requires to a PoW challenge."); + // Obtain a PoW challenge for faucet withdrawal + let challenge = rpc::get_testnet_pow_challenge( + source, + args.ledger_address.clone(), + ) + .await; + + // Solve the solution, this blocks until a solution is found + let solution = challenge.solve(); + Some(solution) + } else { + None + } + }; + let tx = { WrapperTx::new( Fee { - amount: Amount::from(MIN_FEE), - token: ctx.get(&args.fee_token), + amount: fee_amount, + token: fee_token, }, keypair, epoch, @@ -184,6 +238,8 @@ pub async fn sign_wrapper( tx, // TODO: Actually use the fetched encryption key Default::default(), + #[cfg(not(feature = "mainnet"))] + pow_solution, ) }; diff --git a/apps/src/lib/client/tx.rs b/apps/src/lib/client/tx.rs index bff1349732..9ae1d0562f 100644 --- a/apps/src/lib/client/tx.rs +++ b/apps/src/lib/client/tx.rs @@ -107,8 +107,15 @@ pub async fn submit_custom(ctx: Context, args: args::TxCustom) { std::fs::read(data_path).expect("Expected a file at given data path") }); let tx = Tx::new(tx_code, data); - let (ctx, initialized_accounts) = - process_tx(ctx, &args.tx, tx, TxSigningKey::None).await; + let (ctx, initialized_accounts) = process_tx( + ctx, + &args.tx, + tx, + TxSigningKey::None, + #[cfg(not(feature = "mainnet"))] + false, + ) + .await; save_initialized_accounts(ctx, &args.tx, initialized_accounts).await; } @@ -163,7 +170,15 @@ pub async fn submit_update_vp(ctx: Context, args: args::TxUpdateVp) { let data = data.try_to_vec().expect("Encoding tx data shouldn't fail"); let tx = Tx::new(tx_code, Some(data)); - process_tx(ctx, &args.tx, tx, TxSigningKey::WalletAddress(args.addr)).await; + process_tx( + ctx, + &args.tx, + tx, + TxSigningKey::WalletAddress(args.addr), + #[cfg(not(feature = "mainnet"))] + false, + ) + .await; } pub async fn submit_init_account(mut ctx: Context, args: args::TxInitAccount) { @@ -188,9 +203,15 @@ pub async fn submit_init_account(mut ctx: Context, args: args::TxInitAccount) { let data = data.try_to_vec().expect("Encoding tx data shouldn't fail"); let tx = Tx::new(tx_code, Some(data)); - let (ctx, initialized_accounts) = - process_tx(ctx, &args.tx, tx, TxSigningKey::WalletAddress(args.source)) - .await; + let (ctx, initialized_accounts) = process_tx( + ctx, + &args.tx, + tx, + TxSigningKey::WalletAddress(args.source), + #[cfg(not(feature = "mainnet"))] + false, + ) + .await; save_initialized_accounts(ctx, &args.tx, initialized_accounts).await; } @@ -315,9 +336,15 @@ pub async fn submit_init_validator( }; let data = data.try_to_vec().expect("Encoding tx data shouldn't fail"); let tx = Tx::new(tx_code, Some(data)); - let (mut ctx, initialized_accounts) = - process_tx(ctx, &tx_args, tx, TxSigningKey::WalletAddress(source)) - .await; + let (mut ctx, initialized_accounts) = process_tx( + ctx, + &tx_args, + tx, + TxSigningKey::WalletAddress(source), + #[cfg(not(feature = "mainnet"))] + false, + ) + .await; if !tx_args.dry_run { let (validator_address_alias, validator_address) = match &initialized_accounts[..] { @@ -1552,7 +1579,6 @@ pub async fn submit_transfer(mut ctx: Context, args: args::TxTransfer) { } }; - let tx_code = ctx.read_wasm(TX_TRANSFER_WASM); let masp_addr = masp(); // For MASP sources, use a special sentinel key recognized by VPs as default // signer. Also, if the transaction is shielded, redact the amount and token @@ -1591,6 +1617,10 @@ pub async fn submit_transfer(mut ctx: Context, args: args::TxTransfer) { _ => None, }; + #[cfg(not(feature = "mainnet"))] + let is_source_faucet = + rpc::is_faucet_account(&source, args.tx.ledger_address.clone()).await; + let transfer = token::Transfer { source, target, @@ -1646,10 +1676,19 @@ pub async fn submit_transfer(mut ctx: Context, args: args::TxTransfer) { let data = transfer .try_to_vec() .expect("Encoding tx data shouldn't fail"); - + let tx_code = ctx.read_wasm(TX_TRANSFER_WASM); let tx = Tx::new(tx_code, Some(data)); let signing_address = TxSigningKey::WalletAddress(args.source.to_address()); - process_tx(ctx, &args.tx, tx, signing_address).await; + + process_tx( + ctx, + &args.tx, + tx, + signing_address, + #[cfg(not(feature = "mainnet"))] + is_source_faucet, + ) + .await; } pub async fn submit_ibc_transfer(ctx: Context, args: args::TxIbcTransfer) { @@ -1759,8 +1798,15 @@ pub async fn submit_ibc_transfer(ctx: Context, args: args::TxIbcTransfer) { .expect("Encoding tx data shouldn't fail"); let tx = Tx::new(tx_code, Some(data)); - process_tx(ctx, &args.tx, tx, TxSigningKey::WalletAddress(args.source)) - .await; + process_tx( + ctx, + &args.tx, + tx, + TxSigningKey::WalletAddress(args.source), + #[cfg(not(feature = "mainnet"))] + false, + ) + .await; } pub async fn submit_init_proposal(mut ctx: Context, args: args::InitProposal) { @@ -1898,8 +1944,15 @@ pub async fn submit_init_proposal(mut ctx: Context, args: args::InitProposal) { let tx_code = ctx.read_wasm(TX_INIT_PROPOSAL); let tx = Tx::new(tx_code, Some(data)); - process_tx(ctx, &args.tx, tx, TxSigningKey::WalletAddress(signer)) - .await; + process_tx( + ctx, + &args.tx, + tx, + TxSigningKey::WalletAddress(signer), + #[cfg(not(feature = "mainnet"))] + false, + ) + .await; } } @@ -2036,6 +2089,8 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) { &args.tx, tx, TxSigningKey::WalletAddress(signer.clone()), + #[cfg(not(feature = "mainnet"))] + false, ) .await; } @@ -2118,7 +2173,16 @@ pub async fn submit_reveal_pk_aux( let to_broadcast = if args.dry_run { TxBroadcastData::DryRun(tx) } else { - super::signing::sign_wrapper(ctx, args, epoch, tx, &keypair).await + super::signing::sign_wrapper( + ctx, + args, + epoch, + tx, + &keypair, + #[cfg(not(feature = "mainnet"))] + false, + ) + .await }; if args.dry_run { @@ -2297,6 +2361,8 @@ pub async fn submit_bond(ctx: Context, args: args::Bond) { &args.tx, tx, TxSigningKey::WalletAddress(default_signer), + #[cfg(not(feature = "mainnet"))] + false, ) .await; } @@ -2370,6 +2436,8 @@ pub async fn submit_unbond(ctx: Context, args: args::Unbond) { &args.tx, tx, TxSigningKey::WalletAddress(default_signer), + #[cfg(not(feature = "mainnet"))] + false, ) .await; } @@ -2443,6 +2511,8 @@ pub async fn submit_withdraw(ctx: Context, args: args::Withdraw) { &args.tx, tx, TxSigningKey::WalletAddress(default_signer), + #[cfg(not(feature = "mainnet"))] + false, ) .await; } @@ -2525,6 +2595,8 @@ pub async fn submit_validator_commission_change( &args.tx, tx, TxSigningKey::WalletAddress(default_signer), + #[cfg(not(feature = "mainnet"))] + false, ) .await; } @@ -2536,8 +2608,17 @@ async fn process_tx( args: &args::Tx, tx: Tx, default_signer: TxSigningKey, + #[cfg(not(feature = "mainnet"))] requires_pow: bool, ) -> (Context, Vec
) { - let (ctx, to_broadcast) = sign_tx(ctx, tx, args, default_signer).await; + let (ctx, to_broadcast) = sign_tx( + ctx, + tx, + args, + default_signer, + #[cfg(not(feature = "mainnet"))] + requires_pow, + ) + .await; // NOTE: use this to print the request JSON body: // let request = From b4aaeb994a4b81654c51d6a801c0c24dbc3d5251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Mon, 26 Dec 2022 16:10:45 +0100 Subject: [PATCH 153/166] test/e2e: add a case to withdraw from PoW faucet --- tests/src/e2e/ledger_tests.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/tests/src/e2e/ledger_tests.rs b/tests/src/e2e/ledger_tests.rs index 3f95769fc9..46e300dab0 100644 --- a/tests/src/e2e/ledger_tests.rs +++ b/tests/src/e2e/ledger_tests.rs @@ -271,8 +271,10 @@ fn run_ledger_load_state_and_reset() -> Result<()> { /// 3. Submit a transaction to update an account's validity predicate /// 4. Submit a custom tx /// 5. Submit a tx to initialize a new account -/// 6. Query token balance -/// 7. Query the raw bytes of a storage key +/// 6. Submit a tx to withdraw from faucet account (requires PoW challenge +/// solution) +/// 7. Query token balance +/// 8. Query the raw bytes of a storage key #[test] fn ledger_txs_and_queries() -> Result<()> { let test = setup::network(|genesis| genesis, None)?; @@ -388,6 +390,24 @@ fn ledger_txs_and_queries() -> Result<()> { "--ledger-address", &validator_one_rpc, ], + // 6. Submit a tx to withdraw from faucet account (requires PoW challenge + // solution) + vec![ + "transfer", + "--source", + "faucet", + "--target", + ALBERT, + "--token", + NAM, + "--amount", + "10.1", + // Faucet withdrawal requires an explicit signer + "--signer", + ALBERT, + "--ledger-address", + &validator_one_rpc, + ], ]; for tx_args in &txs_args { @@ -409,7 +429,7 @@ fn ledger_txs_and_queries() -> Result<()> { } let query_args_and_expected_response = vec![ - // 6. Query token balance + // 7. Query token balance ( vec![ "balance", @@ -436,7 +456,7 @@ fn ledger_txs_and_queries() -> Result<()> { let nam = find_address(&test, NAM)?; let storage_key = token::balance_key(&nam, &christel).to_string(); let query_args_and_expected_response = vec![ - // 7. Query storage key and get hex-encoded raw bytes + // 8. Query storage key and get hex-encoded raw bytes ( vec![ "query-bytes", From c36c0aca5c8a13b1a871a3ccbf1bb4c0ee0e4fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 30 Dec 2022 13:25:18 +0100 Subject: [PATCH 154/166] changelog: add #969 --- .changelog/unreleased/improvements/969-testnet-pow.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .changelog/unreleased/improvements/969-testnet-pow.md diff --git a/.changelog/unreleased/improvements/969-testnet-pow.md b/.changelog/unreleased/improvements/969-testnet-pow.md new file mode 100644 index 0000000000..906b8a947a --- /dev/null +++ b/.changelog/unreleased/improvements/969-testnet-pow.md @@ -0,0 +1,4 @@ +- Added an optional PoW challenge to the wrapper transactions for testnets, + to allow to submit transactions without having enough balance to cover + the minimum transaction fee and to withdraw tokens from a faucet account. + ([#969](https://github.com/anoma/namada/pull/969)) \ No newline at end of file From 5e26b4dd05dc8ac144ac19b3ab2a111f74d743f0 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Tue, 10 Jan 2023 03:39:33 -0500 Subject: [PATCH 155/166] wasm: update checksums.json --- wasm/checksums.json | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/wasm/checksums.json b/wasm/checksums.json index 504b4c4400..ae9693b08c 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,20 +1,20 @@ { - "tx_bond.wasm": "tx_bond.1812334d1716364411ca3d124f4efcc5c642301f73d5e252c4ce04b407180df9.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.7bded4db73242bd2dc9fd66e0b7831580df1e62be8abafaaa68a633a031e515a.wasm", - "tx_ibc.wasm": "tx_ibc.077b3fdc1c098fa6571106def33090dda746c8e9f17068919f0bc7e067bbd954.wasm", - "tx_init_account.wasm": "tx_init_account.2f8b499298d01f89bc38e792fd6ba1a631785acf1740c361b0510dd3c9d76b34.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.b6c9e4240ebf040fca2ac6c66dee758cff5eed4af5206e05a2595f71a2d20092.wasm", - "tx_init_validator.wasm": "tx_init_validator.40b632d65c7e40bebf3788a71c3d1b9126ae3945ba500a84a8e94cd8597c9897.wasm", - "tx_reveal_pk.wasm": "tx_reveal_pk.6eae9d6bdd2256520ee2bd9c441af9814f4db3fa54a2828cc86ab5d9a954c32c.wasm", - "tx_transfer.wasm": "tx_transfer.685842801dc360b5d127247a55d79bd5a5afa094f4765e20ade0474cc123d8ec.wasm", - "tx_unbond.wasm": "tx_unbond.1848c0ff04f7a3ad097b882079f29afae1e2bb6e44d801f0f87b2ee8ea7bed9e.wasm", - "tx_update_vp.wasm": "tx_update_vp.4ab245accfa86f1f89fc7d2d0e84a166db20f0358e25135209482f4e6c9da4bd.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.9cac6990f94050ff2197ae2cec11c5961c5418fd1308ab60379b13d2daf20ea1.wasm", - "tx_withdraw.wasm": "tx_withdraw.49ea89d9eb032bcf36b53fbf0757e80a32a7495470a7f26cecf3cbcaf4b7034e.wasm", - "vp_implicit.wasm": "vp_implicit.c5b5999b4220e2b47d654f3ec421fc05ae0286add4c88cc494f86787761d5c12.wasm", - "vp_masp.wasm": "vp_masp.91fc1b5e4a8a73ffee55ae91b63eba3fdc917f6aa7c78028247adb38dd565a5b.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.b642bebb92280935b528beb227a8cc84c349dba3c49ec12e875c752de37b37be.wasm", - "vp_token.wasm": "vp_token.333debcfa75aa5efc539e1e74a03f132c3f3f9d5b4e8f7aecda2d260121dd6fa.wasm", - "vp_user.wasm": "vp_user.09ac4a770b399d432ab9fa3d19bcb980d718d9e1f34314078ec87e3fea0f6c08.wasm", - "vp_validator.wasm": "vp_validator.b91d785f4cad1c30b05c6071ff47cc93a4d3848d401061f633ed03e51e3ddffe.wasm" + "tx_bond.wasm": "tx_bond.fb562d319764625cd87e370267fab1f554a60000bcfc027f878a4af2ccf39f73.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.4ab089a82e3a074a8f7ac7d50f9fff1566cbdce529ce9b1523a5c3f6e326a969.wasm", + "tx_ibc.wasm": "tx_ibc.af169e534ad8ed379e7d7166ab486b32aa372f3a06fa1e26e775417adeacb1ab.wasm", + "tx_init_account.wasm": "tx_init_account.792905665629c310061dabef65b5ac638ee35bea03307a6199ca690b89046a80.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.52eb5ce8eb1b8a104d4316a7ee35ee680aa157f9cc4e7064945a3475af718fdc.wasm", + "tx_init_validator.wasm": "tx_init_validator.60a9ebe9cc14728b6c66feabd5ce4c82cc0ae85960d928cdb1b8e21909641568.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.b5740242d6302a9bca1727c63db136f2498b79b0d1ae3291a7eb64c724e3f102.wasm", + "tx_transfer.wasm": "tx_transfer.da0495d2d9cfc61f934d98694d3213741c4d09b49fc7e73fd57b49ee536f9ebe.wasm", + "tx_unbond.wasm": "tx_unbond.df2401b134196a44119eece96f73e735dab1d85fc53ff420594286f9e3365a11.wasm", + "tx_update_vp.wasm": "tx_update_vp.a89f9cf8a55df402ef0ae882d79684ec9eb13bb0daa63fa6f068698cf6e86290.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.e764199b4abdd70415be0bc60afc3a6c5a43c5ed2d9d28fd64ee34400feec090.wasm", + "tx_withdraw.wasm": "tx_withdraw.75e86d2969ea3625858fc09529e19748987758332b767d96231edd3144c9aa8d.wasm", + "vp_implicit.wasm": "vp_implicit.27f761ce117a116e465d100382a54f30213ac1d2d8628726df0693668bf28ef1.wasm", + "vp_masp.wasm": "vp_masp.9946ace16dacb257518494e27268fea0af70be35edcbf9664bfde80cae3f3927.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.9e74c684f01beca216160823562d4e47217f45de1bacd0ecff3d56774d39f477.wasm", + "vp_token.wasm": "vp_token.6a84aebd68a5909c1e74b7a595a1d65a003d343c08dd8b6b6ad47e23689531b6.wasm", + "vp_user.wasm": "vp_user.cef8eac9f5bba515a3c088f9c56f02882da78c21fa1095fbb17f8c238cd84b9d.wasm", + "vp_validator.wasm": "vp_validator.8c17e1fa09b9c3d2a44d9c3b309a8576b3f8da9192322a78675dfb412abef4e6.wasm" } \ No newline at end of file From 1463a20d5bd324bc3420ab747d51523a42e8e245 Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Mon, 2 Jan 2023 17:45:39 +0100 Subject: [PATCH 156/166] genesis: added parameter to control wrapper tx fees amount --- apps/src/lib/config/genesis.rs | 8 ++++ apps/src/lib/node/ledger/shell/init_chain.rs | 3 ++ core/src/ledger/parameters/mod.rs | 47 ++++++++++++++++++++ core/src/ledger/parameters/storage.rs | 11 +++++ core/src/ledger/storage/mod.rs | 2 + 5 files changed, 71 insertions(+) diff --git a/apps/src/lib/config/genesis.rs b/apps/src/lib/config/genesis.rs index 3ab8e60b6f..4ea6c56a6b 100644 --- a/apps/src/lib/config/genesis.rs +++ b/apps/src/lib/config/genesis.rs @@ -267,6 +267,9 @@ pub mod genesis_config { pub pos_gain_p: Decimal, /// PoS gain d pub pos_gain_d: Decimal, + #[cfg(not(feature = "mainnet"))] + /// Fix wrapper tx fees + pub wrapper_tx_fees: Option, } #[derive(Clone, Debug, Deserialize, Serialize)] @@ -613,6 +616,7 @@ pub mod genesis_config { pos_gain_d: parameters.pos_gain_d, staked_ratio: Decimal::ZERO, pos_inflation_amount: 0, + wrapper_tx_fees: parameters.wrapper_tx_fees, }; let GovernanceParamsConfig { @@ -858,6 +862,9 @@ pub struct Parameters { pub staked_ratio: Decimal, /// PoS inflation amount from the last epoch (read + write for every epoch) pub pos_inflation_amount: u64, + /// Fixed Wrapper tx fees + #[cfg(not(feature = "mainnet"))] + pub wrapper_tx_fees: Option, } #[cfg(not(feature = "dev"))] @@ -918,6 +925,7 @@ pub fn genesis() -> Genesis { pos_gain_d: dec!(0.1), staked_ratio: dec!(0.0), pos_inflation_amount: 0, + wrapper_tx_fees: Some(token::Amount::whole(0)), }; let albert = EstablishedAccount { address: wallet::defaults::albert_address(), diff --git a/apps/src/lib/node/ledger/shell/init_chain.rs b/apps/src/lib/node/ledger/shell/init_chain.rs index 5e4415a0c9..c58a8bd4ac 100644 --- a/apps/src/lib/node/ledger/shell/init_chain.rs +++ b/apps/src/lib/node/ledger/shell/init_chain.rs @@ -78,6 +78,7 @@ where pos_gain_d, staked_ratio, pos_inflation_amount, + wrapper_tx_fees, } = genesis.parameters; // borrow necessary for release build, annoys clippy on dev build #[allow(clippy::needless_borrow)] @@ -131,6 +132,8 @@ where pos_inflation_amount, #[cfg(not(feature = "mainnet"))] faucet_account, + #[cfg(not(feature = "mainnet"))] + wrapper_tx_fees, }; parameters.init_storage(&mut self.storage); diff --git a/core/src/ledger/parameters/mod.rs b/core/src/ledger/parameters/mod.rs index 75c6d33d9f..2b17927fc7 100644 --- a/core/src/ledger/parameters/mod.rs +++ b/core/src/ledger/parameters/mod.rs @@ -12,6 +12,7 @@ use crate::types::address::{Address, InternalAddress}; use crate::types::chain::ProposalBytes; use crate::types::storage::Key; use crate::types::time::DurationSecs; +use crate::types::token; const ADDRESS: Address = Address::Internal(InternalAddress::Parameters); @@ -54,6 +55,9 @@ pub struct Parameters { #[cfg(not(feature = "mainnet"))] /// Faucet account for free token withdrawal pub faucet_account: Option
, + #[cfg(not(feature = "mainnet"))] + /// Fixed fees for a wrapper tx to be accepted + pub wrapper_tx_fees: Option, } /// Epoch duration. A new epoch begins as soon as both the `min_num_of_blocks` @@ -118,6 +122,8 @@ impl Parameters { pos_inflation_amount, #[cfg(not(feature = "mainnet"))] faucet_account, + #[cfg(not(feature = "mainnet"))] + wrapper_tx_fees, } = self; // write max proposal bytes parameter @@ -218,6 +224,18 @@ impl Parameters { genesis block, if any", ); } + + #[cfg(not(feature = "mainnet"))] + { + let wrapper_tx_fees_key = storage::get_wrapper_tx_fees_key(); + let wrapper_tx_fees_val = + encode(&wrapper_tx_fees.unwrap_or(token::Amount::whole(100))); + storage + .write(&wrapper_tx_fees_key, wrapper_tx_fees_val) + .expect( + "Wrapper tx fees must be initialized in the genesis block", + ); + } } } /// Update the max_expected_time_per_block parameter in storage. Returns the @@ -423,6 +441,25 @@ where Ok((address, gas_faucet_account)) } +#[cfg(not(feature = "mainnet"))] +/// Read the wrapper tx fees amount, if any +pub fn read_wrapper_tx_fees_parameter( + storage: &Storage, +) -> std::result::Result<(Option, u64), ReadError> +where + DB: ledger_storage::DB + for<'iter> ledger_storage::DBIter<'iter>, + H: ledger_storage::StorageHasher, +{ + let wrapper_tx_fees_key = storage::get_wrapper_tx_fees_key(); + let (value, gas_wrapper_tx_fees) = storage + .read(&wrapper_tx_fees_key) + .map_err(ReadError::StorageError)?; + let address: Option = value + .map(|value| decode(value).map_err(ReadError::StorageTypeError)) + .transpose()?; + Ok((address, gas_wrapper_tx_fees)) +} + // Read the all the parameters from storage. Returns the parameters and gas /// cost. pub fn read( @@ -532,6 +569,13 @@ where #[cfg(feature = "mainnet")] let gas_faucet_account = 0; + // read faucet account + #[cfg(not(feature = "mainnet"))] + let (wrapper_tx_fees, gas_wrapper_tx_fees) = + read_wrapper_tx_fees_parameter(storage)?; + #[cfg(feature = "mainnet")] + let gas_wrapper_tx_fees = 0; + let total_gas_cost = [ gas_epoch, gas_tx, @@ -545,6 +589,7 @@ where gas_reward, gas_proposal_bytes, gas_faucet_account, + gas_wrapper_tx_fees, ] .into_iter() .fold(0u64, |accum, gas| { @@ -568,6 +613,8 @@ where pos_inflation_amount, #[cfg(not(feature = "mainnet"))] faucet_account, + #[cfg(not(feature = "mainnet"))] + wrapper_tx_fees, }, total_gas_cost, )) diff --git a/core/src/ledger/parameters/storage.rs b/core/src/ledger/parameters/storage.rs index f2b5d1353d..178b0860eb 100644 --- a/core/src/ledger/parameters/storage.rs +++ b/core/src/ledger/parameters/storage.rs @@ -20,6 +20,7 @@ struct Keys { vp_whitelist: &'static str, max_proposal_bytes: &'static str, faucet_account: &'static str, + wrapper_tx_fees: &'static str, } /// Returns if the key is a parameter key. @@ -249,3 +250,13 @@ pub fn get_faucet_account_key() -> Key { ], } } + +/// Storage key used for staked ratio parameter. +pub fn get_wrapper_tx_fees_key() -> Key { + Key { + segments: vec![ + DbKeySeg::AddressSeg(ADDRESS), + DbKeySeg::StringSeg(Keys::VALUES.wrapper_tx_fees.to_string()), + ], + } +} diff --git a/core/src/ledger/storage/mod.rs b/core/src/ledger/storage/mod.rs index 8f0606bd70..45f145ec87 100644 --- a/core/src/ledger/storage/mod.rs +++ b/core/src/ledger/storage/mod.rs @@ -1242,6 +1242,8 @@ mod tests { pos_inflation_amount: 0, #[cfg(not(feature = "mainnet"))] faucet_account: None, + #[cfg(not(feature = "mainnet"))] + wrapper_tx_fees: None, }; parameters.init_storage(&mut storage); From a800b8a7834ddb188fea98ef978e785d737f953c Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Tue, 3 Jan 2023 11:09:28 +0100 Subject: [PATCH 157/166] ledger: use genesis fees --- apps/src/lib/client/signing.rs | 13 +++++++++++-- apps/src/lib/node/ledger/shell/finalize_block.rs | 9 +++++---- apps/src/lib/node/ledger/shell/mod.rs | 11 +++++++++++ core/src/types/token.rs | 7 +++++++ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/apps/src/lib/client/signing.rs b/apps/src/lib/client/signing.rs index c35f9aef6d..ec1641c1c4 100644 --- a/apps/src/lib/client/signing.rs +++ b/apps/src/lib/client/signing.rs @@ -2,6 +2,7 @@ //! wallet. use borsh::BorshSerialize; +use namada::ledger::parameters::storage as parameter_storage; use namada::proto::Tx; use namada::types::address::{Address, ImplicitAddress}; use namada::types::key::*; @@ -185,11 +186,19 @@ pub async fn sign_wrapper( keypair: &common::SecretKey, #[cfg(not(feature = "mainnet"))] requires_pow: bool, ) -> TxBroadcastData { - let fee_amount = Amount::from(MIN_FEE); + let client = HttpClient::new(args.ledger_address.clone()).unwrap(); + + let fee_amount = if cfg!(feature = "mainnet") { + Amount::from(MIN_FEE) + } else { + let wrapper_tx_fees_key = parameter_storage::get_wrapper_tx_fees_key(); + rpc::query_storage_value::(&client, &wrapper_tx_fees_key) + .await + .unwrap_or_default() + }; let fee_token = ctx.get(&args.fee_token); let source = Address::from(&keypair.ref_to()); let balance_key = token::balance_key(&fee_token, &source); - let client = HttpClient::new(args.ledger_address.clone()).unwrap(); let balance = rpc::query_storage_value::(&client, &balance_key) .await diff --git a/apps/src/lib/node/ledger/shell/finalize_block.rs b/apps/src/lib/node/ledger/shell/finalize_block.rs index 577a4ac003..8fbcdb3592 100644 --- a/apps/src/lib/node/ledger/shell/finalize_block.rs +++ b/apps/src/lib/node/ledger/shell/finalize_block.rs @@ -55,6 +55,8 @@ where execute_governance_proposals(self, &mut response)?; } + let wrapper_fees = self.get_wrapper_tx_fees(); + // Tracks the accepted transactions self.storage.block.results = BlockResults::default(); for (tx_index, processed_tx) in req.txs.iter().enumerate() { @@ -179,13 +181,12 @@ where } }; - let balance: u64 = balance.into(); - match balance.checked_sub(MIN_FEE) { - Some(v) => { + match balance.checked_sub(wrapper_fees) { + Some(amount) => { self.write_log .write( &balance_key, - Amount::from(v).try_to_vec().unwrap(), + amount.try_to_vec().unwrap(), ) .unwrap(); } diff --git a/apps/src/lib/node/ledger/shell/mod.rs b/apps/src/lib/node/ledger/shell/mod.rs index 3b5940f99c..3d11035c5c 100644 --- a/apps/src/lib/node/ledger/shell/mod.rs +++ b/apps/src/lib/node/ledger/shell/mod.rs @@ -719,6 +719,17 @@ where false } + #[cfg(not(feature = "mainnet"))] + /// Get fixed amount of fees for wrapper tx + fn get_wrapper_tx_fees(&self) -> token::Amount { + let (fees, _gas) = + namada::ledger::parameters::read_wrapper_tx_fees_parameter( + &self.storage, + ) + .expect("Must be able to read wrapper tx fees parameter"); + fees.unwrap_or_default() + } + #[cfg(not(feature = "mainnet"))] /// Check if the tx has a valid PoW solution and if so invalidate it to /// prevent replay. diff --git a/core/src/types/token.rs b/core/src/types/token.rs index 2bf95735ed..becbe323a3 100644 --- a/core/src/types/token.rs +++ b/core/src/types/token.rs @@ -71,6 +71,13 @@ impl Amount { Self { micro: u64::MAX } } + /// Checked subtraction + pub fn checked_sub(&self, amount: Amount) -> Option { + self.micro + .checked_sub(amount.micro) + .map(|result| Self { micro: result }) + } + /// Create amount from Change /// /// # Panics From 26f8443edab985ff37a71e099093603c92041415 Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Wed, 4 Jan 2023 13:17:20 +0100 Subject: [PATCH 158/166] ledger: remove/changed some logs --- apps/src/lib/client/signing.rs | 2 +- shared/src/ledger/queries/router.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/src/lib/client/signing.rs b/apps/src/lib/client/signing.rs index ec1641c1c4..9f897df0ed 100644 --- a/apps/src/lib/client/signing.rs +++ b/apps/src/lib/client/signing.rs @@ -219,7 +219,7 @@ pub async fn sign_wrapper( // If the address derived from the keypair doesn't have enough balance // to pay for the fee, allow to find a PoW solution instead. if requires_pow || balance < fee_amount { - println!("The transaction requires to a PoW challenge."); + println!("The transaction requires the completion of a PoW challenge."); // Obtain a PoW challenge for faucet withdrawal let challenge = rpc::get_testnet_pow_challenge( source, diff --git a/shared/src/ledger/queries/router.rs b/shared/src/ledger/queries/router.rs index f614396d27..9bf1116a5c 100644 --- a/shared/src/ledger/queries/router.rs +++ b/shared/src/ledger/queries/router.rs @@ -250,7 +250,7 @@ macro_rules! try_match_segments { $end = $request.path.len(); match $request.path[$start..$end].parse::<$arg_ty>() { Ok(parsed) => { - println!("Parsed {}", parsed); + // println!("Parsed {}", parsed); $arg = parsed }, Err(_) => From 49a1d3f8fd00348fc74ba58be28b7af3bffb9c51 Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Wed, 4 Jan 2023 14:09:51 +0100 Subject: [PATCH 159/166] chore: clippy/fmt --- apps/src/lib/client/signing.rs | 4 +++- apps/src/lib/node/ledger/shell/finalize_block.rs | 9 +++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/src/lib/client/signing.rs b/apps/src/lib/client/signing.rs index 9f897df0ed..0f893a0190 100644 --- a/apps/src/lib/client/signing.rs +++ b/apps/src/lib/client/signing.rs @@ -219,7 +219,9 @@ pub async fn sign_wrapper( // If the address derived from the keypair doesn't have enough balance // to pay for the fee, allow to find a PoW solution instead. if requires_pow || balance < fee_amount { - println!("The transaction requires the completion of a PoW challenge."); + println!( + "The transaction requires the completion of a PoW challenge." + ); // Obtain a PoW challenge for faucet withdrawal let challenge = rpc::get_testnet_pow_challenge( source, diff --git a/apps/src/lib/node/ledger/shell/finalize_block.rs b/apps/src/lib/node/ledger/shell/finalize_block.rs index 8fbcdb3592..b214c2b78a 100644 --- a/apps/src/lib/node/ledger/shell/finalize_block.rs +++ b/apps/src/lib/node/ledger/shell/finalize_block.rs @@ -265,7 +265,7 @@ where { Ok(result) => { if result.is_accepted() { - tracing::info!( + tracing::trace!( "all VPs accepted transaction {} storage \ modification {:#?}", tx_event["hash"], @@ -297,7 +297,7 @@ where } } } else { - tracing::info!( + tracing::trace!( "some VPs rejected transaction {} storage \ modification {:#?}", tx_event["hash"], @@ -326,6 +326,11 @@ where } response.events.push(tx_event); } + tracing::info!( + "Applied {} txs at height {}", + response.events.len(), + self.storage.last_height + ); if new_epoch { self.update_epoch(&mut response); From 2785ad0c14d26ebc4bab564469aa0ff95083eb4e Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Tue, 10 Jan 2023 03:49:41 -0500 Subject: [PATCH 160/166] changelog: add #972 --- .changelog/unreleased/improvements/972-genesis-wrapper-fees.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/972-genesis-wrapper-fees.md diff --git a/.changelog/unreleased/improvements/972-genesis-wrapper-fees.md b/.changelog/unreleased/improvements/972-genesis-wrapper-fees.md new file mode 100644 index 0000000000..63579d9141 --- /dev/null +++ b/.changelog/unreleased/improvements/972-genesis-wrapper-fees.md @@ -0,0 +1,2 @@ +- Add genesis parameter to control wrapper transaction fees. + ([#972](https://github.com/anoma/namada/pull/972)) \ No newline at end of file From e961d94ce935c3e65cb35a451437b1f26696a01c Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Wed, 4 Jan 2023 15:57:53 +0100 Subject: [PATCH 161/166] ledger: add some blocks statistics logs --- .../lib/node/ledger/shell/finalize_block.rs | 19 +++++++++++++++---- apps/src/lib/node/ledger/shell/mod.rs | 1 + .../src/vm/wasm/compilation_cache/common.rs | 10 ++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/finalize_block.rs b/apps/src/lib/node/ledger/shell/finalize_block.rs index b214c2b78a..785264b937 100644 --- a/apps/src/lib/node/ledger/shell/finalize_block.rs +++ b/apps/src/lib/node/ledger/shell/finalize_block.rs @@ -12,6 +12,7 @@ use super::governance::execute_governance_proposals; use super::*; use crate::facade::tendermint_proto::abci::Misbehavior as Evidence; use crate::facade::tendermint_proto::crypto::PublicKey as TendermintPublicKey; +use crate::node::ledger::shell::stats::InternalStats; impl Shell where @@ -56,6 +57,7 @@ where } let wrapper_fees = self.get_wrapper_tx_fees(); + let mut stats = InternalStats::default(); // Tracks the accepted transactions self.storage.block.results = BlockResults::default(); @@ -271,6 +273,7 @@ where tx_event["hash"], result ); + stats.increment_successful_txs(); self.write_log.commit_tx(); if !tx_event.contains_key("code") { tx_event["code"] = ErrorCodes::Ok.into(); @@ -303,6 +306,7 @@ where tx_event["hash"], result.vps_result.rejected_vps ); + stats.increment_rejected_txs(); self.write_log.drop_tx(); tx_event["code"] = ErrorCodes::InvalidTx.into(); } @@ -315,6 +319,7 @@ where tx_event["hash"], msg ); + stats.increment_errored_txs(); self.write_log.drop_tx(); tx_event["gas_used"] = self .gas_meter @@ -326,12 +331,18 @@ where } response.events.push(tx_event); } - tracing::info!( - "Applied {} txs at height {}", - response.events.len(), - self.storage.last_height + + stats.set_tx_cache_size( + self.tx_wasm_cache.get_size(), + self.tx_wasm_cache.get_cache_size(), + ); + stats.set_vp_cache_size( + self.vp_wasm_cache.get_size(), + self.vp_wasm_cache.get_cache_size(), ); + tracing::info!("{}", stats); + if new_epoch { self.update_epoch(&mut response); } diff --git a/apps/src/lib/node/ledger/shell/mod.rs b/apps/src/lib/node/ledger/shell/mod.rs index 3d11035c5c..1e25325834 100644 --- a/apps/src/lib/node/ledger/shell/mod.rs +++ b/apps/src/lib/node/ledger/shell/mod.rs @@ -11,6 +11,7 @@ mod init_chain; mod prepare_proposal; mod process_proposal; mod queries; +mod stats; use std::collections::HashSet; use std::convert::{TryFrom, TryInto}; diff --git a/shared/src/vm/wasm/compilation_cache/common.rs b/shared/src/vm/wasm/compilation_cache/common.rs index c4beb9d095..2c231c303c 100644 --- a/shared/src/vm/wasm/compilation_cache/common.rs +++ b/shared/src/vm/wasm/compilation_cache/common.rs @@ -116,6 +116,16 @@ impl Cache { } } + /// Get the current number of items in the cache + pub fn get_size(&self) -> usize { + self.in_memory.read().unwrap().len() + } + + /// Get the current weight of the cache + pub fn get_cache_size(&self) -> usize { + self.in_memory.read().unwrap().weight() + } + /// Get a WASM module from LRU cache, from a file or compile it and cache /// it. Updates the position in the LRU cache. fn get_or_compile( From 8f19882108a4b49fad0add9deb2cfcdc82393229 Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Wed, 4 Jan 2023 16:15:47 +0100 Subject: [PATCH 162/166] chore: missing file --- apps/src/lib/node/ledger/shell/stats.rs | 50 +++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 apps/src/lib/node/ledger/shell/stats.rs diff --git a/apps/src/lib/node/ledger/shell/stats.rs b/apps/src/lib/node/ledger/shell/stats.rs new file mode 100644 index 0000000000..9f28fbf820 --- /dev/null +++ b/apps/src/lib/node/ledger/shell/stats.rs @@ -0,0 +1,50 @@ +use std::fmt::Display; + +#[derive(Debug, Default)] +pub struct InternalStats { + successful_tx: u64, + rejected_txs: u64, + errored_txs: u64, + vp_cache_size: (usize, usize), + tx_cache_size: (usize, usize), +} + +impl InternalStats { + pub fn increment_successful_txs(&mut self) { + self.successful_tx += 1; + } + + pub fn increment_rejected_txs(&mut self) { + self.rejected_txs += 1; + } + + pub fn increment_errored_txs(&mut self) { + self.errored_txs += 1; + } + + pub fn set_vp_cache_size(&mut self, keys: usize, weight: usize) { + self.vp_cache_size = (keys, weight); + } + + pub fn set_tx_cache_size(&mut self, keys: usize, weight: usize) { + self.tx_cache_size = (keys, weight); + } +} + +impl Display for InternalStats { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Applied {} transactions, successful txs: {}, rejected txs: {}, \ + errored txs: {}: vp cache size: {} - {}, tx cache size {} - {}", + self.successful_tx + self.rejected_txs + self.errored_txs, + self.successful_tx, + self.rejected_txs, + self.errored_txs, + self.vp_cache_size.0, + self.vp_cache_size.1, + self.tx_cache_size.0, + self.tx_cache_size.1 + ) + } +} From 3afd012de97789a22a51c85944030ccf3448316f Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Wed, 4 Jan 2023 17:49:28 +0100 Subject: [PATCH 163/166] misc: change log level --- core/src/ledger/gas.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/ledger/gas.rs b/core/src/ledger/gas.rs index 99eb606b7b..e51c9f78ef 100644 --- a/core/src/ledger/gas.rs +++ b/core/src/ledger/gas.rs @@ -77,7 +77,7 @@ impl BlockGasMeter { /// Add the base transaction fee and the fee per transaction byte that's /// charged the moment we try to apply the transaction. pub fn add_base_transaction_fee(&mut self, bytes_len: usize) -> Result<()> { - tracing::info!("add_base_transaction_fee {}", bytes_len); + tracing::trace!("add_base_transaction_fee {}", bytes_len); self.add(BASE_TRANSACTION_FEE) } From 6ac34adfee9b67c2ad1e72588fce1bbc8b6dbd5d Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli <> Date: Wed, 4 Jan 2023 18:07:13 +0100 Subject: [PATCH 164/166] misc: change log level --- shared/src/vm/wasm/compilation_cache/common.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/vm/wasm/compilation_cache/common.rs b/shared/src/vm/wasm/compilation_cache/common.rs index 2c231c303c..9f25d573c4 100644 --- a/shared/src/vm/wasm/compilation_cache/common.rs +++ b/shared/src/vm/wasm/compilation_cache/common.rs @@ -136,7 +136,7 @@ impl Cache { let mut in_memory = self.in_memory.write().unwrap(); if let Some(module) = in_memory.get(&hash) { - tracing::info!( + tracing::trace!( "{} found {} in cache.", N::name(), hash.to_string() From 39a5c7fe0b7af87e9674ab3a29292ebd6257cc1c Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Tue, 10 Jan 2023 05:43:05 -0500 Subject: [PATCH 165/166] finalize_block: remove unused import --- apps/src/lib/node/ledger/shell/finalize_block.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/finalize_block.rs b/apps/src/lib/node/ledger/shell/finalize_block.rs index 785264b937..784c7e96e0 100644 --- a/apps/src/lib/node/ledger/shell/finalize_block.rs +++ b/apps/src/lib/node/ledger/shell/finalize_block.rs @@ -6,7 +6,6 @@ use namada::ledger::storage::write_log::StorageModification; use namada::ledger::storage_api::StorageRead; use namada::types::storage::{BlockHash, BlockResults, Header}; use namada::types::token::Amount; -use namada::types::transaction::MIN_FEE; use super::governance::execute_governance_proposals; use super::*; @@ -435,7 +434,7 @@ where #[cfg(test)] mod test_finalize_block { use namada::types::storage::Epoch; - use namada::types::transaction::{EncryptionKey, Fee, WrapperTx}; + use namada::types::transaction::{EncryptionKey, Fee, WrapperTx, MIN_FEE}; use super::*; use crate::node::ledger::shell::test_utils::*; From 5da82f093f10c0381865accba99f60c557360c51 Mon Sep 17 00:00:00 2001 From: "Raymond E. Pasco" Date: Tue, 10 Jan 2023 03:55:19 -0500 Subject: [PATCH 166/166] Namada 0.13.0 --- ...65-fix-validator-commission-change-test.md | 0 .../bugs/912-remove-prefix-iter.md | 0 .../features/973-namada-start-time.md | 0 .../features/974-resize-block.md | 0 .../improvements/900-no-send-async-traits.md | 0 .../903-fix-ledger-params-match.md | 0 .../improvements/909-fix-queries-rustdoc.md | 0 .../926-storage-keys-procmacro.md | 0 .../improvements/962-basic-fee.md | 0 .../966-gats-lifetimes-refactor.md | 0 .../improvements/968-logging-fmt.md | 0 .../improvements/969-testnet-pow.md | 0 .../improvements/972-genesis-wrapper-fees.md | 0 .../improvements/975-max-block-size.md | 0 .../667-tendermint-v0.1.4-abciplus.md | 0 .changelog/v0.13.0/summary.md | 1 + .../testing/876-faster-epoch-test.md | 0 .../911-fix-ledger-txs-and-queries-args.md | 0 CHANGELOG.md | 62 ++++++++++++++++++ Cargo.lock | 20 +++--- apps/Cargo.toml | 2 +- core/Cargo.toml | 2 +- encoding_spec/Cargo.toml | 2 +- macros/Cargo.toml | 2 +- proof_of_stake/Cargo.toml | 2 +- shared/Cargo.toml | 2 +- tests/Cargo.toml | 2 +- tx_prelude/Cargo.toml | 2 +- vm_env/Cargo.toml | 2 +- vp_prelude/Cargo.toml | 2 +- wasm/Cargo.lock | 22 +++---- wasm/checksums.json | 36 +++++----- wasm/tx_template/Cargo.toml | 2 +- wasm/vp_template/Cargo.toml | 2 +- wasm/wasm_source/Cargo.toml | 2 +- wasm_for_tests/tx_memory_limit.wasm | Bin 133419 -> 133398 bytes wasm_for_tests/tx_mint_tokens.wasm | Bin 356170 -> 352856 bytes wasm_for_tests/tx_no_op.wasm | Bin 25554 -> 25554 bytes wasm_for_tests/tx_proposal_code.wasm | Bin 205677 -> 203888 bytes wasm_for_tests/tx_read_storage_key.wasm | Bin 152457 -> 152564 bytes wasm_for_tests/tx_write_storage_key.wasm | Bin 228613 -> 226642 bytes wasm_for_tests/vp_always_false.wasm | Bin 156524 -> 156489 bytes wasm_for_tests/vp_always_true.wasm | Bin 156524 -> 156489 bytes wasm_for_tests/vp_eval.wasm | Bin 157461 -> 157426 bytes wasm_for_tests/vp_memory_limit.wasm | Bin 158972 -> 158937 bytes wasm_for_tests/vp_read_storage_key.wasm | Bin 168172 -> 170817 bytes wasm_for_tests/wasm_source/Cargo.lock | 18 ++--- wasm_for_tests/wasm_source/Cargo.toml | 2 +- 48 files changed, 125 insertions(+), 62 deletions(-) rename .changelog/{unreleased => v0.13.0}/bug-fixes/965-fix-validator-commission-change-test.md (100%) rename .changelog/{unreleased => v0.13.0}/bugs/912-remove-prefix-iter.md (100%) rename .changelog/{unreleased => v0.13.0}/features/973-namada-start-time.md (100%) rename .changelog/{unreleased => v0.13.0}/features/974-resize-block.md (100%) rename .changelog/{unreleased => v0.13.0}/improvements/900-no-send-async-traits.md (100%) rename .changelog/{unreleased => v0.13.0}/improvements/903-fix-ledger-params-match.md (100%) rename .changelog/{unreleased => v0.13.0}/improvements/909-fix-queries-rustdoc.md (100%) rename .changelog/{unreleased => v0.13.0}/improvements/926-storage-keys-procmacro.md (100%) rename .changelog/{unreleased => v0.13.0}/improvements/962-basic-fee.md (100%) rename .changelog/{unreleased => v0.13.0}/improvements/966-gats-lifetimes-refactor.md (100%) rename .changelog/{unreleased => v0.13.0}/improvements/968-logging-fmt.md (100%) rename .changelog/{unreleased => v0.13.0}/improvements/969-testnet-pow.md (100%) rename .changelog/{unreleased => v0.13.0}/improvements/972-genesis-wrapper-fees.md (100%) rename .changelog/{unreleased => v0.13.0}/improvements/975-max-block-size.md (100%) rename .changelog/{unreleased => v0.13.0}/miscellaneous/667-tendermint-v0.1.4-abciplus.md (100%) create mode 100644 .changelog/v0.13.0/summary.md rename .changelog/{unreleased => v0.13.0}/testing/876-faster-epoch-test.md (100%) rename .changelog/{unreleased => v0.13.0}/testing/911-fix-ledger-txs-and-queries-args.md (100%) diff --git a/.changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md b/.changelog/v0.13.0/bug-fixes/965-fix-validator-commission-change-test.md similarity index 100% rename from .changelog/unreleased/bug-fixes/965-fix-validator-commission-change-test.md rename to .changelog/v0.13.0/bug-fixes/965-fix-validator-commission-change-test.md diff --git a/.changelog/unreleased/bugs/912-remove-prefix-iter.md b/.changelog/v0.13.0/bugs/912-remove-prefix-iter.md similarity index 100% rename from .changelog/unreleased/bugs/912-remove-prefix-iter.md rename to .changelog/v0.13.0/bugs/912-remove-prefix-iter.md diff --git a/.changelog/unreleased/features/973-namada-start-time.md b/.changelog/v0.13.0/features/973-namada-start-time.md similarity index 100% rename from .changelog/unreleased/features/973-namada-start-time.md rename to .changelog/v0.13.0/features/973-namada-start-time.md diff --git a/.changelog/unreleased/features/974-resize-block.md b/.changelog/v0.13.0/features/974-resize-block.md similarity index 100% rename from .changelog/unreleased/features/974-resize-block.md rename to .changelog/v0.13.0/features/974-resize-block.md diff --git a/.changelog/unreleased/improvements/900-no-send-async-traits.md b/.changelog/v0.13.0/improvements/900-no-send-async-traits.md similarity index 100% rename from .changelog/unreleased/improvements/900-no-send-async-traits.md rename to .changelog/v0.13.0/improvements/900-no-send-async-traits.md diff --git a/.changelog/unreleased/improvements/903-fix-ledger-params-match.md b/.changelog/v0.13.0/improvements/903-fix-ledger-params-match.md similarity index 100% rename from .changelog/unreleased/improvements/903-fix-ledger-params-match.md rename to .changelog/v0.13.0/improvements/903-fix-ledger-params-match.md diff --git a/.changelog/unreleased/improvements/909-fix-queries-rustdoc.md b/.changelog/v0.13.0/improvements/909-fix-queries-rustdoc.md similarity index 100% rename from .changelog/unreleased/improvements/909-fix-queries-rustdoc.md rename to .changelog/v0.13.0/improvements/909-fix-queries-rustdoc.md diff --git a/.changelog/unreleased/improvements/926-storage-keys-procmacro.md b/.changelog/v0.13.0/improvements/926-storage-keys-procmacro.md similarity index 100% rename from .changelog/unreleased/improvements/926-storage-keys-procmacro.md rename to .changelog/v0.13.0/improvements/926-storage-keys-procmacro.md diff --git a/.changelog/unreleased/improvements/962-basic-fee.md b/.changelog/v0.13.0/improvements/962-basic-fee.md similarity index 100% rename from .changelog/unreleased/improvements/962-basic-fee.md rename to .changelog/v0.13.0/improvements/962-basic-fee.md diff --git a/.changelog/unreleased/improvements/966-gats-lifetimes-refactor.md b/.changelog/v0.13.0/improvements/966-gats-lifetimes-refactor.md similarity index 100% rename from .changelog/unreleased/improvements/966-gats-lifetimes-refactor.md rename to .changelog/v0.13.0/improvements/966-gats-lifetimes-refactor.md diff --git a/.changelog/unreleased/improvements/968-logging-fmt.md b/.changelog/v0.13.0/improvements/968-logging-fmt.md similarity index 100% rename from .changelog/unreleased/improvements/968-logging-fmt.md rename to .changelog/v0.13.0/improvements/968-logging-fmt.md diff --git a/.changelog/unreleased/improvements/969-testnet-pow.md b/.changelog/v0.13.0/improvements/969-testnet-pow.md similarity index 100% rename from .changelog/unreleased/improvements/969-testnet-pow.md rename to .changelog/v0.13.0/improvements/969-testnet-pow.md diff --git a/.changelog/unreleased/improvements/972-genesis-wrapper-fees.md b/.changelog/v0.13.0/improvements/972-genesis-wrapper-fees.md similarity index 100% rename from .changelog/unreleased/improvements/972-genesis-wrapper-fees.md rename to .changelog/v0.13.0/improvements/972-genesis-wrapper-fees.md diff --git a/.changelog/unreleased/improvements/975-max-block-size.md b/.changelog/v0.13.0/improvements/975-max-block-size.md similarity index 100% rename from .changelog/unreleased/improvements/975-max-block-size.md rename to .changelog/v0.13.0/improvements/975-max-block-size.md diff --git a/.changelog/unreleased/miscellaneous/667-tendermint-v0.1.4-abciplus.md b/.changelog/v0.13.0/miscellaneous/667-tendermint-v0.1.4-abciplus.md similarity index 100% rename from .changelog/unreleased/miscellaneous/667-tendermint-v0.1.4-abciplus.md rename to .changelog/v0.13.0/miscellaneous/667-tendermint-v0.1.4-abciplus.md diff --git a/.changelog/v0.13.0/summary.md b/.changelog/v0.13.0/summary.md new file mode 100644 index 0000000000..709a0a7f09 --- /dev/null +++ b/.changelog/v0.13.0/summary.md @@ -0,0 +1 @@ +Namada 0.13.0 is a scheduled minor release. diff --git a/.changelog/unreleased/testing/876-faster-epoch-test.md b/.changelog/v0.13.0/testing/876-faster-epoch-test.md similarity index 100% rename from .changelog/unreleased/testing/876-faster-epoch-test.md rename to .changelog/v0.13.0/testing/876-faster-epoch-test.md diff --git a/.changelog/unreleased/testing/911-fix-ledger-txs-and-queries-args.md b/.changelog/v0.13.0/testing/911-fix-ledger-txs-and-queries-args.md similarity index 100% rename from .changelog/unreleased/testing/911-fix-ledger-txs-and-queries-args.md rename to .changelog/v0.13.0/testing/911-fix-ledger-txs-and-queries-args.md diff --git a/CHANGELOG.md b/CHANGELOG.md index e5e37c9b0e..09fa1610b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,67 @@ # CHANGELOG +## v0.13.0 + +Namada 0.13.0 is a scheduled minor release. + +### BUG FIXES + +- Fix the commission rate change wasm test, which failed because an arbitrary + value for a new rate was allowed that could be equal to the previous rate. + ([#965](https://github.com/anoma/namada/pull/965)) + +### BUGS + +- Removed 'rev_iter_prefix' from storage API as its implementation + depends on RocksDB and it doesn't work as expected. + ([#912](https://github.com/anoma/namada/pull/912)) + +### FEATURES + +- Add a --time argument to the node to specify the time the node should start. + ([#973](https://github.com/anoma/namada/pull/973)) +- Reduce the block size for transactions to 5 MiB. + ([#974](https://github.com/anoma/namada/pull/974)) + +### IMPROVEMENTS + +- Disable 'Send' on async traits that don't need 'Send' + futures. This allows to use them with 'wasm-bindgen'. + ([#900](https://github.com/anoma/namada/pull/900)) +- Binary search ledger storage keys to match faster. + ([#903](https://github.com/anoma/namada/pull/903)) +- Make queries data structures public for inclusion in rustdoc. + ([#909](https://github.com/anoma/namada/pull/909)) +- Add a macro to derive storage keys from a struct. + ([#926](https://github.com/anoma/namada/pull/926)) +- Added a basic fee implementation for testnet. + ([#962](https://github.com/anoma/namada/pull/962)) +- Hide the explicit lifetime from StorageRead trait. + ([#966](https://github.com/anoma/namada/pull/966)) +- Allow to set the tracing format with NAMADA_LOG_FMT env var to either full + (default), json or pretty. ([#968](https://github.com/anoma/namada/pull/968)) +- Added an optional PoW challenge to the wrapper transactions for testnets, + to allow to submit transactions without having enough balance to cover + the minimum transaction fee and to withdraw tokens from a faucet account. + ([#969](https://github.com/anoma/namada/pull/969)) +- Add genesis parameter to control wrapper transaction fees. + ([#972](https://github.com/anoma/namada/pull/972)) +- Add a max_proposal_bytes parameter to the ledger. + ([#975](https://github.com/anoma/namada/pull/975)) + +### MISCELLANEOUS + +- Update tendermint to v0.1.4-abciplus. + ([#667](https://github.com/anoma/namada/pull/667)) + +### TESTING + +- Run fewer cases on update_epoch_after_its_duration, for a faster test suite. + ([#876](https://github.com/anoma/namada/pull/876)) +- Use the correct options (--gas-amount, --gas- + token) in the ledger_txs_and_queries E2E test. + ([#911](https://github.com/anoma/namada/pull/911)) + ## v0.12.2 Namada 0.12.2 is a hotfix release, limiting transactions included in a diff --git a/Cargo.lock b/Cargo.lock index 1bbdf7b3c1..cae497c282 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3635,7 +3635,7 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "namada" -version = "0.12.2" +version = "0.13.0" dependencies = [ "assert_matches", "async-trait", @@ -3692,7 +3692,7 @@ dependencies = [ [[package]] name = "namada_apps" -version = "0.12.2" +version = "0.13.0" dependencies = [ "ark-serialize", "ark-std", @@ -3778,7 +3778,7 @@ dependencies = [ [[package]] name = "namada_core" -version = "0.12.2" +version = "0.13.0" dependencies = [ "ark-bls12-381", "ark-ec", @@ -3832,7 +3832,7 @@ dependencies = [ [[package]] name = "namada_encoding_spec" -version = "0.12.2" +version = "0.13.0" dependencies = [ "borsh", "itertools", @@ -3843,7 +3843,7 @@ dependencies = [ [[package]] name = "namada_macros" -version = "0.12.2" +version = "0.13.0" dependencies = [ "proc-macro2", "quote", @@ -3852,7 +3852,7 @@ dependencies = [ [[package]] name = "namada_proof_of_stake" -version = "0.12.2" +version = "0.13.0" dependencies = [ "borsh", "derivative", @@ -3866,7 +3866,7 @@ dependencies = [ [[package]] name = "namada_tests" -version = "0.12.2" +version = "0.13.0" dependencies = [ "assert_cmd", "borsh", @@ -3910,7 +3910,7 @@ dependencies = [ [[package]] name = "namada_tx_prelude" -version = "0.12.2" +version = "0.13.0" dependencies = [ "borsh", "masp_primitives", @@ -3925,7 +3925,7 @@ dependencies = [ [[package]] name = "namada_vm_env" -version = "0.12.2" +version = "0.13.0" dependencies = [ "borsh", "hex", @@ -3936,7 +3936,7 @@ dependencies = [ [[package]] name = "namada_vp_prelude" -version = "0.12.2" +version = "0.13.0" dependencies = [ "borsh", "namada_core", diff --git a/apps/Cargo.toml b/apps/Cargo.toml index d39c4c13c4..514f51e503 100644 --- a/apps/Cargo.toml +++ b/apps/Cargo.toml @@ -6,7 +6,7 @@ license = "GPL-3.0" name = "namada_apps" readme = "../README.md" resolver = "2" -version = "0.12.2" +version = "0.13.0" default-run = "namada" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/core/Cargo.toml b/core/Cargo.toml index a101f4c3b9..32894f1656 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_core" resolver = "2" -version = "0.12.2" +version = "0.13.0" [features] default = [] diff --git a/encoding_spec/Cargo.toml b/encoding_spec/Cargo.toml index 6f9b17a5dd..fce4480951 100644 --- a/encoding_spec/Cargo.toml +++ b/encoding_spec/Cargo.toml @@ -6,7 +6,7 @@ license = "GPL-3.0" name = "namada_encoding_spec" readme = "../README.md" resolver = "2" -version = "0.12.2" +version = "0.13.0" [features] default = ["abciplus"] diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 1307a5bfd3..fd115ee6de 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_macros" resolver = "2" -version = "0.12.2" +version = "0.13.0" [lib] proc-macro = true diff --git a/proof_of_stake/Cargo.toml b/proof_of_stake/Cargo.toml index a27f508935..5d265cd2c2 100644 --- a/proof_of_stake/Cargo.toml +++ b/proof_of_stake/Cargo.toml @@ -6,7 +6,7 @@ license = "GPL-3.0" name = "namada_proof_of_stake" readme = "../README.md" resolver = "2" -version = "0.12.2" +version = "0.13.0" [features] default = ["abciplus"] diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 6fd22f6a06..3a9c15984d 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada" resolver = "2" -version = "0.12.2" +version = "0.13.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 1b5b2b50f6..241a28b721 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_tests" resolver = "2" -version = "0.12.2" +version = "0.13.0" [features] default = ["abciplus", "wasm-runtime"] diff --git a/tx_prelude/Cargo.toml b/tx_prelude/Cargo.toml index 447867ac7d..0d711c15ee 100644 --- a/tx_prelude/Cargo.toml +++ b/tx_prelude/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_tx_prelude" resolver = "2" -version = "0.12.2" +version = "0.13.0" [features] default = ["abciplus"] diff --git a/vm_env/Cargo.toml b/vm_env/Cargo.toml index 11be9ef2e1..e33f253c96 100644 --- a/vm_env/Cargo.toml +++ b/vm_env/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_vm_env" resolver = "2" -version = "0.12.2" +version = "0.13.0" [features] default = ["abciplus"] diff --git a/vp_prelude/Cargo.toml b/vp_prelude/Cargo.toml index 8ea87a3426..6a147124d6 100644 --- a/vp_prelude/Cargo.toml +++ b/vp_prelude/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_vp_prelude" resolver = "2" -version = "0.12.2" +version = "0.13.0" [features] default = ["abciplus"] diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index ca26d09c42..e6c79aed78 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -2456,7 +2456,7 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "namada" -version = "0.12.2" +version = "0.13.0" dependencies = [ "async-trait", "bellman", @@ -2500,7 +2500,7 @@ dependencies = [ [[package]] name = "namada_core" -version = "0.12.2" +version = "0.13.0" dependencies = [ "ark-bls12-381", "ark-serialize", @@ -2542,7 +2542,7 @@ dependencies = [ [[package]] name = "namada_macros" -version = "0.12.2" +version = "0.13.0" dependencies = [ "proc-macro2", "quote", @@ -2551,7 +2551,7 @@ dependencies = [ [[package]] name = "namada_proof_of_stake" -version = "0.12.2" +version = "0.13.0" dependencies = [ "borsh", "derivative", @@ -2565,7 +2565,7 @@ dependencies = [ [[package]] name = "namada_tests" -version = "0.12.2" +version = "0.13.0" dependencies = [ "chrono", "concat-idents", @@ -2594,7 +2594,7 @@ dependencies = [ [[package]] name = "namada_tx_prelude" -version = "0.12.2" +version = "0.13.0" dependencies = [ "borsh", "masp_primitives", @@ -2609,7 +2609,7 @@ dependencies = [ [[package]] name = "namada_vm_env" -version = "0.12.2" +version = "0.13.0" dependencies = [ "borsh", "hex", @@ -2620,7 +2620,7 @@ dependencies = [ [[package]] name = "namada_vp_prelude" -version = "0.12.2" +version = "0.13.0" dependencies = [ "borsh", "namada_core", @@ -2633,7 +2633,7 @@ dependencies = [ [[package]] name = "namada_wasm" -version = "0.12.2" +version = "0.13.0" dependencies = [ "borsh", "getrandom 0.2.8", @@ -4603,7 +4603,7 @@ dependencies = [ [[package]] name = "tx_template" -version = "0.12.2" +version = "0.13.0" dependencies = [ "borsh", "getrandom 0.2.8", @@ -4740,7 +4740,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "vp_template" -version = "0.12.2" +version = "0.13.0" dependencies = [ "borsh", "getrandom 0.2.8", diff --git a/wasm/checksums.json b/wasm/checksums.json index ae9693b08c..a137f5818f 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,20 +1,20 @@ { - "tx_bond.wasm": "tx_bond.fb562d319764625cd87e370267fab1f554a60000bcfc027f878a4af2ccf39f73.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.4ab089a82e3a074a8f7ac7d50f9fff1566cbdce529ce9b1523a5c3f6e326a969.wasm", - "tx_ibc.wasm": "tx_ibc.af169e534ad8ed379e7d7166ab486b32aa372f3a06fa1e26e775417adeacb1ab.wasm", - "tx_init_account.wasm": "tx_init_account.792905665629c310061dabef65b5ac638ee35bea03307a6199ca690b89046a80.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.52eb5ce8eb1b8a104d4316a7ee35ee680aa157f9cc4e7064945a3475af718fdc.wasm", - "tx_init_validator.wasm": "tx_init_validator.60a9ebe9cc14728b6c66feabd5ce4c82cc0ae85960d928cdb1b8e21909641568.wasm", - "tx_reveal_pk.wasm": "tx_reveal_pk.b5740242d6302a9bca1727c63db136f2498b79b0d1ae3291a7eb64c724e3f102.wasm", - "tx_transfer.wasm": "tx_transfer.da0495d2d9cfc61f934d98694d3213741c4d09b49fc7e73fd57b49ee536f9ebe.wasm", - "tx_unbond.wasm": "tx_unbond.df2401b134196a44119eece96f73e735dab1d85fc53ff420594286f9e3365a11.wasm", - "tx_update_vp.wasm": "tx_update_vp.a89f9cf8a55df402ef0ae882d79684ec9eb13bb0daa63fa6f068698cf6e86290.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.e764199b4abdd70415be0bc60afc3a6c5a43c5ed2d9d28fd64ee34400feec090.wasm", - "tx_withdraw.wasm": "tx_withdraw.75e86d2969ea3625858fc09529e19748987758332b767d96231edd3144c9aa8d.wasm", - "vp_implicit.wasm": "vp_implicit.27f761ce117a116e465d100382a54f30213ac1d2d8628726df0693668bf28ef1.wasm", - "vp_masp.wasm": "vp_masp.9946ace16dacb257518494e27268fea0af70be35edcbf9664bfde80cae3f3927.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.9e74c684f01beca216160823562d4e47217f45de1bacd0ecff3d56774d39f477.wasm", - "vp_token.wasm": "vp_token.6a84aebd68a5909c1e74b7a595a1d65a003d343c08dd8b6b6ad47e23689531b6.wasm", - "vp_user.wasm": "vp_user.cef8eac9f5bba515a3c088f9c56f02882da78c21fa1095fbb17f8c238cd84b9d.wasm", - "vp_validator.wasm": "vp_validator.8c17e1fa09b9c3d2a44d9c3b309a8576b3f8da9192322a78675dfb412abef4e6.wasm" + "tx_bond.wasm": "tx_bond.75681aeb49d87cb7b23da8d4edfd2906338e338c8ff7ad4549e961d086b845de.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.de0ce89e60eb91fafb944686a0452d567d2e675b056359547460215f2c69cabb.wasm", + "tx_ibc.wasm": "tx_ibc.822f648393de5e018586ef215edf8b168bebc50091fc4b3e25903ea1d419d418.wasm", + "tx_init_account.wasm": "tx_init_account.f5ca0c0d33d07ac846fc08597d362e1004f43cbe6a06f01ce6f1a3d189a23893.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.f93779f403ef0888773597f6caa518de6c6230a2416c9a32e6382c7789019daf.wasm", + "tx_init_validator.wasm": "tx_init_validator.77f0716c61bd6047928f1d52a216015afc2f85f33061d9cff012464e93b81475.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.a526d636870213fc0ec1fab845e3ff5ad9122a57434307ef77f9b7513a06fe99.wasm", + "tx_transfer.wasm": "tx_transfer.ef9b2f772aaa41220c42750e449b11d664041908a1be490b462351acdf3ea072.wasm", + "tx_unbond.wasm": "tx_unbond.09aefb73697ddfe49ca69ada14eb495935b9cf18dc66104c23ed6ebcc7db983e.wasm", + "tx_update_vp.wasm": "tx_update_vp.c6d94a3a10b4efd7a0197dae2449922618245aa2c2e0287810fb1683a4321ec0.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.b0b6ca1f923bc36693d6e295f7b847af7d6642c3395e5c27ba78332702db8acf.wasm", + "tx_withdraw.wasm": "tx_withdraw.6bd82759a0a344ea09b4a2d2d7df4d77122ab74eb597c9acd70e521bc6082f93.wasm", + "vp_implicit.wasm": "vp_implicit.17a42ba3e9698cdbfe7248e4467ccb376e820c9a87acf14a1b7e401426c470e0.wasm", + "vp_masp.wasm": "vp_masp.b7864b58f5110ea2d6c4d8e4976da9b78cdbbeb790b0d68170b798838b1507d2.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.f86bc96e2e6c247dc4d0565aba318e4e4811bf7d944ff0fa4dd07634b4c70689.wasm", + "vp_token.wasm": "vp_token.bbefbef1bf7d8c206a06bc873c1236053f8d9be769061abacfcc74044f1750c2.wasm", + "vp_user.wasm": "vp_user.16d5bec0072281156279a36eeb94a0b6500bf8ceae85c8b68ccf7aca7f0ac33e.wasm", + "vp_validator.wasm": "vp_validator.704fbc03c617e824363b753cd1f9cf7c3c39c8db10e93480feb11baa8efa6533.wasm" } \ No newline at end of file diff --git a/wasm/tx_template/Cargo.toml b/wasm/tx_template/Cargo.toml index 515a8adfe7..1f603a5294 100644 --- a/wasm/tx_template/Cargo.toml +++ b/wasm/tx_template/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "tx_template" resolver = "2" -version = "0.12.2" +version = "0.13.0" [lib] crate-type = ["cdylib"] diff --git a/wasm/vp_template/Cargo.toml b/wasm/vp_template/Cargo.toml index d8f3383d9c..e0eb328691 100644 --- a/wasm/vp_template/Cargo.toml +++ b/wasm/vp_template/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "vp_template" resolver = "2" -version = "0.12.2" +version = "0.13.0" [lib] crate-type = ["cdylib"] diff --git a/wasm/wasm_source/Cargo.toml b/wasm/wasm_source/Cargo.toml index 043cea9684..f9e4d8ed5a 100644 --- a/wasm/wasm_source/Cargo.toml +++ b/wasm/wasm_source/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "GPL-3.0" name = "namada_wasm" resolver = "2" -version = "0.12.2" +version = "0.13.0" [lib] crate-type = ["cdylib"] diff --git a/wasm_for_tests/tx_memory_limit.wasm b/wasm_for_tests/tx_memory_limit.wasm index 09fcaea999799c8f256d0c2ba28b73dd249e8409..9c4ea2abccbcef666288b7ccb0a12e07dd9d4c27 100755 GIT binary patch delta 2133 zcmah~Yiv|S6rMBp?%lh+yWNYSuidsgyKU+A1zR3l+CtmulkzBuihqb$P!zT(0ZSqp zTaZU$P=Ov(t&+C1pazWuub>8%Y7iuW#AxFyQItmviBU8n2^#gxEg=4KlY3^)bI$qB znb}wS%>F)e*W8)Br-yZVdex70LND}mGS;ap7J56i9(OSm>+ZbnX7{>ii>bA>YTN|S z!Qwt$2L^s_Fb1IMJPouo9!U3c4S)ml0%^hH@de@LPcyvW+5JTXUfX@OJzi88o-uQF zb+D#(4pik%&d8jV6$oaB{5g5?(z5c3sf|s|bqz9Y7p{V1u*ZpW3OS4kEdhIQxwe3_ zdHA|^Dl$Ac#-=e=%b4KOOv&eoFJY|8<#!EYzn+8(ct+n&4$czK35f35H^$zLWMC^K;<9)F57Cx$3QaK48=l&#Tez3?#Ns`mbo0e-qKw{uO+D z)H&m?2U;;bJ>S?mM8OMidis9tV!*;l;mP<@x@`%n#*S$c+SZ{JY~!p0?+hNH#qrw} zhGJ_oFTpe{%BqKivoh-wfJ#i}tbj^qASX@N+5zyDycrn^3A;6Cf~^pB9xaSRj&ezITRuzqlJ9hE~aC=)*rt%FBET9u_kcF{Qq)MQ;$qWXp?N zso_5m5x%hGQWHMBqjWL&aI~~2WLi`J)UYgCW~StEGNX!xN0@l7v?DKOCV4`bE@E-& zwMR|fAr+9@ai^m!4D1jxsY(?ohcWvojfFZWaW`S|j*L70xM ziCW+EphbwkWNP?SqIqi65MH^7r^*?V$9fkA$jgwMc`D`=&>rA~&Su^vjJAMIS$X>^ zGouQ{s3G0)WWq=(>l@ynjIgTmP=-ch30+ZYvC=inQ-L}DUD>3jv3a`Wl~WX?6rTyN z(Ctcoe}CrhyP7;6b=q_$J?3_%=cEXmXzpq76`{Po9%$@lP7O(gia z3gV@pWS(Z1;MJPv;2URW?L}3>hPjE{>!-N>bc($0z@$aiAI#kWL%68!rkR_kpUn2t z<(CSn0GSQcoei>%7z?XL*%7)FI{r}~!oyRR5I9%s*Z=QD!6zH`@WZ3Hvngckrz)h4 zy)qM?#bq)K+wf5t=D&~NV=`o17$NO#O3ObR!Fxz@Qc3(uV!W@mK3v<9eZq9Mz1N8 z`;>4W>aEd?;R%&w^XM+Xg7xbIjNaNG=e1ex>!}F+4b`=8{15+O`(4f(t#i1kQ`aq> zNvvso1Y`5>=4?K0o`0INg}8XZ61BXv;C^eg5a^xUG{&p}%v#vO$0s?<7XC#4CX<|w zjzNFl(!$d5bem-}#&YNj(Wmxd`a0Hji{)$9h!q>VS3WG(uUvi~&RMzw9&q+9?c(^` Q-KATS%ic;ZgDVIA0kS|e1poj5 delta 2071 zcmahKYiv|i`h4f!xxLdnk1IkSb6e)jFoh}YlqtfLKA=5qr-jm1LQ?;*HigxVo#G2i zq8K_5Up1OY`Lb133kAwUCBClNm1v}Hc73zEs9A}cpzES2YB0w5_@RF1QX2i`{qcS0 zd!Fxk?)Yx=@!jUGl_kEs`q%&;8DRsEhmirs2K0P>><^{dfHpFAb1duEIy*G(2hhRd zrmh2n05=!|0IiURg9Tgz;J^xiB;fOzA(DX33yG~h%>ZA)*t=19YV5l;$(Sf!l3r0C zZfIyzprh$8z9eds{D!~OBKTIh^T;tmZQuhv&P*o%3lS} z^Z0Bu1r~l3-R_Qy7h#@P9VUFzpCe_tNN7WL84kwZf^uwHa2>%z3-Saj5_dwm`&c3g zrOG73Z2_%N$8`a+D#ObNP2u^9|AB-5TDTd?uyN6lD2uTGw*-?rK<>JWa-PqAL%A<6 z8U~n;jg=Pwv3hZJm8t5$;)Vi#so$K{TLcj$^6Z_|)lUfs(~(?i!o)ikUkN6@y|^Oc zwWs|jk+s*!jE&Rdgo_&ngnLfD@=kqstEbC^2qIkyS=I$Ab}58-$F2) z`q)ausC3fKC78gUqHFMcb+LPOO&34}k1i3R2qmFQAuo(mMiKn)lD$xaThonJP1vGR zA2W5x?y?&|WwQ*+eHP9g6URMP0Z`{42 zhX&`v6*to0tgF9);EDQ(H!b{EvxD128TN~E{JcI3A7i>9wc+euYNAd#mgS^rS9py} zHn6Z@@|{bfa8CM31ahtfTaUABP$RLOlc#9MlZ<5;ZJ(Nm*NC2ZahQAwpKFMQPb(*? zhNNC-SKucN55gIDr17kZ`kIyLvYA^vd%8u=7%*v(_ERhGgM-+#YF5pQGeByO(hDGc z(&0ZIz?_W0Iowagy9cmWMvONOPyhkEK^7T*S4Y1(!ZUbTs{=affx8s}Kj1{GV|=;)k}3aSzj6kz#_yZ}1ec&w20^eo4ZAD&fVrj?W$`BH8ZneUmCdJ~oM=wuo`pC2=u6-R{sloFtXg z`>>`p!XNSwyn(T-!>2vMc-||ym*x}1zZ^%i>zrf9=sE?|gF~A_&n1&b74s;5la0-r zx+s$QZrTr6yJbs|F$?#sxz+9KY~onek+r-RQ~~VD<+`L(A zx^4K{Tf~-YH(rB#dKU6?A$+N)2rD;i(ij_b@82-QG2A}~zrMQUj#&TSV*T*#W4{37 C>>nxs diff --git a/wasm_for_tests/tx_mint_tokens.wasm b/wasm_for_tests/tx_mint_tokens.wasm index e3bd3e5724de626414d994fe376b8bd934b16aec..d61c8804c7bd20824070403fd17cbb9ccf57a3a0 100755 GIT binary patch delta 66812 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 WerzdpuF$6->(sez1E=VT_WuI?ptVE* diff --git a/wasm_for_tests/tx_no_op.wasm b/wasm_for_tests/tx_no_op.wasm index 3e0b1ef9970ebb8846c675a59676c86aed95bd39..105a68cd1b7b12afd3382e087fea275772fba9a7 100755 GIT binary patch delta 248 zcmca~obl3e#tF(wb#)90O!f5)35@lObqTEXAi!A9%*(^V%E-pZ#LmDx(KVfolZ%^` zonzuAZ6*efiT7=}H#8n#a6ADd1lT64Gp3{PXEHjAKLAT9G4nDgFexxOa%3s6DliGK zPX5ejzy^_*{m##ybK-+jE;=n zMMb;}4BV6BINc#uf$Rrby@9h5g>S+YwpoSUhKYlPL4lE*g~4(18n%kbQ@CzU4&~O` JJe}J*0sxSCMNt3% delta 253 zcmca~obl3e#tF(w_4N!1Om%e(39R)Xz*wKaSkG9;%*(^d!pP3Z#K6op(KVfom5rT~ zi+kcGZKiskiT7=}A2c3daNGbS1UM$EGp3{PXEHjAp8!iKG4nDgFexxOa%3s6DliFf zPX5ejzy^_@V*+3WY*830} z74b4Ka8H)us@Qyk-G*uMIyP5`ogjw*-SCgC5{2Ky9>&SSpuot@!r;g-c{10n$*tT% Oll{3RHc#iajsO4|rb*TS diff --git a/wasm_for_tests/tx_proposal_code.wasm b/wasm_for_tests/tx_proposal_code.wasm index 2124f281201c5e2012436d61d4b7c06b3065587f..b34dd56b1c70a7b1cc33cce91cbc378ae4fcf46c 100755 GIT binary patch delta 42348 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 a2+UT3ABfRh4etPeT*~r&UiXnx>t{sVXfk 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 delta 42984 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 U@{!~k*o}v=uXm5>#v_gY3k5&y`~Uy| delta 14572 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�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 TeQ1_%$`N0mZS1P(?$-YT;rvhD diff --git a/wasm_for_tests/vp_always_false.wasm b/wasm_for_tests/vp_always_false.wasm index 3ce1549f15bc2255ceecaaa33f03a5287561c048..ed21184fe30e8b2042101bb54144fe1c9080def9 100755 GIT binary patch delta 1976 zcmb6aX-t$?@Xhoo?^q$Ubl(}GdIrbn8pHH|@AOd1ngV{4n(rnI4rZM2Oc(au{jkzmvGOJ?THn|X8Z z?C>Sa!Tnq8giElwI;oI<)@{`Sq z%{5bSkWa8`EREY8iU3~+4sjo6RhXrGKt%sV$uLS96IN=lcAmPxL^mP(d|VN+Y7BoX zqBQz+NaRp#Oye3C=72^Ado||UGmVdA`f7WE!dbb#C-PlIsQ|#D=$t4GNUb4GYHLa$ zmzxE%qP`<~0C0Y6h8~Rlm_w&t5dW(}BuUGY7O=_LDh*w9UR7W}?n_O7-Xhar4x>b7 zp>}vww?<5ixUrq$zDY>4Och)xngxea=Ya+D(~`lAOVVNpZ%nH)In22{Q#0#>Y4Z$9 zzgfY=>1E3kjhabx@<2Lc;(X9=V^+;5UgrUaNrMU-*MOLI&FHhKnn5$=^2y;~r4!Ie zQkKi@LRK!(D3}y6%@~mHAKL@@48NRyCQ6~AL3<(R64;{mZS$8Ed%sv6d*f+bI5BH+CsFr_z z6yGlTM2Z#_pOYlcog&Au#QitFa}*1ON0P0gQEGlCyw1KJ8oE5H!Z$1+c2Z@;gS%CQ z@eu^Xz?jsnVkZPNtDKP{JlB{7rFf@t1Pb-xMYIhB<}Pj}e0XsXgdW$FCa+4D)DZ4k zauQ1P;-y=`#QYj<2tN)q=YiPYLTkW}%UiPPMR&_h`C@(R0%8VQ!&ETqU$1O5fLG62 zl?;?z{c0Dv+_Cx&xN*}O7vYm@>cFi(T=TOEC0M*PURO4(2>FO0ANtx?QfWK;^+Owf z=cKmtHHQT}_}(^GtcS92x7)p%)1x_r>LX-r7kpj^-rIIfcJ;~|i)2?*wr@7c4cfa) zH`-XaoW06*>uiix+>|cgqa7;O1MSqdu2;wK!(Dayw>XQNRT^2V$^^cMo6vu-UuHaV zuvU_q?&ES@-|r@_O0PbYD8t2<4@;qbU> z1Okmfo)Zb4)O8T=BuK)EeUaGKpJaLR#`#pc4HN&5-Ou_C+V0YeO7e2m!k7gs`VtJ) wlk6-G&z$n$gZ?)$vrm2Y$*3M@kQwz>% delta 2077 zcmaJ>Yiv|i5I%G6y}Nh2EM0l@MYXqEpsTcOAGj?ok3DU--O`2D(g!6KS_%}lP#z*L zBgHVvi2|FdC|p&eRcRwv4J_8JR~MvtJ>$x>;P?px z`bIl52D%0h8Jg-ABVHe=XrssQqP+Z3fzpaMDyyn%qShb7`H%>mxCyFhy$jzc_Z@Z= zl`;4=@9PlEU~cYoDFR9c;g7t8hsU8uIZn*HucTWfkBKVO?45_dVqzsN&WSiZdhRpw zt?0towus54IGDi=F7%K=8)p@Iof(#Hn>ojsr0{Ui+|>V5MGFFiIp)P?$Jh;^lamsp zgQ0}HTo=r~-CP}e7B~;%xcGFin@i$9=g?_pCjO)lOEhw1B&<$pk^#R+xugK%hSaoS zx_l0ES>$39>H@#&Gf0RNH`dYpZ_;Aug9I0fq2mv!<)CARdq{%KZfFAXSS+y-A#sw9 zc{wvQ!-n(R6Lc@nAcGz0NP1TS)4*5n`{wGn&@^R>Hl{;kZyQt_>ovEfeI}y zC7BymY4rtUG6mOp3MB;RJ!Kp$7?YI-cd#()Q9KV*FfE-i7l^n;BJORMD%b=EOTdb3 zBnaVk3_6uc75!Oq-b$i({ber)uvq}^kOUoVnH3L6|fxdUJ2&TI*;o~+P4 z316yJucfEg!oNaxvN0 z#&>mKm#>iQCiCH9aQWb zLhL#ViDSD-*s_N@S0cuRuf+goE_M}7l{pgqGKcw=KOSWC&BggL`i0^@`K@-mSmKwg zf1oFNdE7IRAGZG!8S_RK^Id!JcKkrCG}78TM<%5{|L)#;{RZA1Ig0=bwbRsJelY}dpC5r}+MaX78| z0ik79)L0^_ikcW~t)-p|;)dF%{8&4#pA?kryGd`#x@6atr1l_Z7bhVkF8+%g)x<8| zhY+oL$eDxfb(v6rSL>carg?cXVd=y8`X*Z6tq+6G{G;A2RYRv#(zooA2&bdQ?Ug>T1 zP~MrXzra|mo#&zTy?He-*8G0neU*}&S=5~*nv$61i&JTK2h62Qe&%$fdAZ95#kg^e zXHYRc!`I^U8!3LnCG0JNm(z%K36-Ynw`;D-j@!R>vc$w!HPDP(*KCy&cGU-_#SsqD zxPY>S3muHv@yPb2=G<+gI2NM6d)Uf3LBkhu*)wwNwi=tt46v)z6X@P?SU&vvj%vv~ zZF}WBzt&bQv!s8NEN_h!JEhUwzjK-b8D`Wcw;kHcjImcRbSNbp*^v}YBtIbPPgLDH zW9j@EO^aqsHx@T8oZZ;E$e7(aea6x}gE93bCrh9+gNXVNsYFTtk&Pamo6aWF-bIu` zB=>`fdVKpvoD)gWeWgo>b~sLxOBrb{*%-57-l5ct7X{Dl*L!eW^>G2-{A_*tiySlh i_u^=7K5QyjceG#Zvv9mdcNs>MwkCA+MCd5o?)(e?wIF>EY&0nuWQ`DnwT+B5inXC>b7)#Eu!Kh2UyZAK_kFyG#C_W}({3_DSO2&p2o9ye3oMy6vm~#d$idZ~E zzZOv(b2Maf2?x`;&ZRY=)4*AUxy}spBb%|rnIJeTHMT~6C`1_m7Q|#l=|Icsm}u55avcwhXH1?7`W?)!o8{X);IimY=HNPz(yE(%4ox@dmTW#M9PBg# z8Y#)Lxl^jlC7LBuCZ?MMYX4(AP}}h0gkw>Hk_N4blmumSm#U*U?o2OMfnG^3=U~CH znd9L)R%iYlqnpwgbAgOqA!Ap%G|4Kopw3L#l!cV0J6ZXh3JSP6H$Ev-WyYE)LWO3O z{Q#tD)AMZIl(2xDOP4E(?=XFzbxHUH_5}d;z@L^tpI12)A`Ezhmj+ZvSHQj>? zyd_B;U6g87e`k228t8#!rZc-2AV?Js6$!WHMvohYIovH~{~E2n7V@UexBox9!3Cv0 z-qD4JOEZn5w)11PSO2oUzsY_SnzRUmIi}}){#Ckbft^8hklX|-8isewO z-?D(*MDfeh`{#@ z$nhBIofJ0&{U>$QAi8n4bfLh^>C*qdZ1OwxG zwTAnulc505SO2AM*5@-1g*<7P6^p@|0dmS%Tx$+Zt*lE|&K;<`&yRLtcfDVUTlEbp z?5f$mltIVr@>2-Nz9C`TB2IrQWuX3uRV-Z?i2(ui+JRa3?D zs)@JHI|M~W;r#VrVSb(3fFJuBb3pEBqPOnHg-w~Xqoe7n+OeW}CMkW*VH#MCZ(f;g z0*^6q@mPQYqi%@~;KtQU(}^EiS_^LD;nH6;D8j<|V+^r!Q3yVQ;EiRkr%?Cx8@pHi z!D-p1H(WOG;^7VHabEJ>-Rkt{NgmxLH6Jm1tK^k!cxS_9RmThO%u#h5xA9Gj>X7?3 z8)gS9rFH=2%a=PCwXo=R-=iL>omi9G6^nvzT<2#(fts2w8t}%%(<7)Kp>Q%ws z-&LbTb;o|yj_-AlR$)}_PE_vVYn{qyT(Bx$;Oxs%X$(_ xRnItCJRUpZ!3VwXVn&bl{F7cijvyoQDJL1nju-;{$6wg6<@hICj>EO1{{mRP`o#bM delta 2042 zcmaJ>Yiv|i5I%G6y}Nh2EL~dYi$ZU=Kv!wm(&BDuLH4xWc4?QkmOdy!XekxgLU~wu z8Cl*65rhnZS`)(?B9#;_0hC1i(GU;>6hj~oF+e0S#2-o^L5jJ@&N%=F&a41rw^(!s(9#qxPbt!-Dm)5oilVB~s`QaX1B-Rr)kPUzPidJJnp8fp zf3!1ekZaiR5$W#nV_q4nXs`PDguMK5!HJcxRaMv2Mr}Bb3n3Z0a5K~pzYE_e_Z@Z= zRdM(=@9z-IU~cYoDFR9c!7b283~p8u47 zE4nbgy~pKJ9L(Sb7kb#Bjk6lP&MZr>&z$E>QFtU|ZjSv#(Lw+bj(PDpadrdfR#(H}HO=5;VSa6{jI{uJe0Xk;6hbP(Wh9)47#giBl7N_W# zmoq~%Y`DN(u6ubFIrOmE?XJ)?Q&%B^aifZ6yYy6xVHK-*ID;{9CK7TmyP=EKJnXU< zFwwycAf?67OB^aCvv~Qyen3|lKszbv7N?NNrdkA(E_z*9#{ZoUWEh?qbu`{ephAmF zN#%xBdi_CpnS$#*g%X0VJY^g#7?+&^cd#(~Q6i5}GA)xa7l?#5k?@vF6|CIBlCUxd z3Br3h`5d2&yP$M~f>%O5?8+^M(Ku~V02{rlX!qC=(2Hb|A_hlK?x2^rGe?4}rz-SL z!k23G+|pe^x33Yhag%SatY2nsV$8FFSeKh(9?hQ!cx(Iter_MGd-b6dD<&L(Tuk-1 z^Id!Jw7-U*+JiCTv~*n-Ur6ym!3bIUlLe3Yy*=1f7?9#|VZA)r8cf1@MHy+o@1bJ* z2(jxdEROFbW$QlbT!|PL{uTqAxp=y0hP)#=An!2W3?zcgzNI){X1`GUC%?5DFO~$P zhz<5-uSj?*^TXZ$WX8O)#eCO3yq!2mo7mIZ9b;3{pZ)IV_4*CGJ$4QO7R=lKKY+#O zzacM((30vw{OAmG+hLLZ}$?Lw%Y#q%wuW zBOF>O%=?qPT={j*Fd78KxV~xx_^`9;7uiX>CLiiS!e5<$Gix3YC}w4?rN>lR8;7lR z)LJ3jSoa%0z8g182}$wYl-DKvIrSy!eE`|TDF};;{{lqN+r@hjCa#B_K67_{CctR( z@>D{r028M*5r1b|1PaVQrn#kQ#PllS%cmcLBGWZv4Ok&a{}u%CaD$H=cN>~GDZ$2U z3VFNnrVOcTnoP>!rYKdjrRs*wJTbdogJRP;e>i~8^tKuR0_zrdh`+m_7KHizg8M4v zKik%uKbrEJ6-&}-FbB+S|bP1J4 z=eKLG%62-qZmLAWUp>f7SU=k;$LH$zO^YKEqFDfCix)c>v*Xbn%gp)P$8jvgK<^}# zLx3hL;_|2T`0ceel^I}Hso?0|c|?Bm^_?|Rc-r^NVSTN=M&6S7VXAyJR(43Id9Y)q z0$FC%$G08Y5XRV040onQdUm8m6UhZcu|zek&C3=xH?=j-GL|$hp4-^kX3TA!)x0dv zU`!q0WJz>pFi}4ul_=#uy3uEI)7ezoyNJ?=o1mv3Dp1q diff --git a/wasm_for_tests/vp_eval.wasm b/wasm_for_tests/vp_eval.wasm index 3bf4ac8028c7b69e88e88bf82be1bab63575a551..a01f70ac4ee055311fad365ed265697574a19547 100755 GIT binary patch delta 2037 zcmb7Fc}$c?6rVTq?Y9>TA6gXAmXAe*dVy$J0TBjV76e&EP{9jCj4r7asx2m#wHhmF z(nx(?MPs}}OjX)Xt;R%cV_HosjsNtBJ#4K)wjI58&5h#t`=F=IQUuc&mL$2NEx+HgNq z64&@SamnMx%>wth!Bv{}^yei8(J)2A|EOJbc$bTP3@z*>AadFT+Q z+6MFLiaDg#=-2X0Qex$ot7zTliJ8v+l1pJa(U}qiCsw5-fdj)SvBWo}l-a$G44!5> ztZOMjo7m?Nm_K}6eS&V<<#HYx%9uP6F7+_CsmoV+$ZI#D*uzaArNPt#9?i6w_6+`1 z1h`28k`%HGZb;R+1YI&^Vx}Ha@elHW3d3KAzY`;tMSjH~#YLb;{VUyW##Ym(!^%<4TbqNrr4AI3gN!%Ez z+T%zN_fMNqqaSZOZuG2xY>bQa!&y9)SqsnMpsbx3RopN7v1rUHj>j9m<>bH5=f~lL z$MH=&@Y5kNqL7aDXdr&jVPWT zt9S#yx&!Bpzo?+3Bum|k)g|L_)|fr&7d_{uf;%~TU@Yz&yNUm@3v+TS`Kj%=F87!+ zP0Bm2AX*Mmp_%eeetkQp=lc~b&973P*9+tDTK>?)w|CMd^3e%>!9uci2Pr3a(MyO_ zXC(6)Ofbe`PQh$dV{3t`Vcja|2P(Va&sNzd`0w#`JF%?LuV8&)PxfH!Bbk3tWx6w4 zXG&HIoZ}nc)8YZXLM#pTXak(gWRflya|;IU2$tXe{i(ms9Q$OG-TeoC7nGJP&*0XD zU_2LB8wS!-&&Re39Y3fT2swDA;)c3Y=PNq^uHy05KG;6>w;pNRwBLKAj;c7d@KaT{ zdFKv%zq(XG)byFEEeodyl6w~Jl1CsUPe0NUmu!WQ>7p566Kc5n7cvpU?aZ1`g3*gb*0MS9iV9yZ76PZLxP9S>N*GqaL(LkaoBJ}}L zZ~VJ6+4-*(_Z~=;563;IF)jLk)WGV_jU#VTLsax(gZWUO*weecWNczDgT*nnF*gXA_{KYJscKtKT1Hy$CoZEq@as;OwdUOxfwv9~ OUgfM7?zY#bPnxko%BHG`i{){WU-*p z#W^r=3LOMzCIjFAT9Oz!!XbnJ5FnTX$O8<+bOSv)=R&!uFyKiXoEjIJ=FyaqVs$Va z>(8}MDafn3&8V)KlalNib<4QSNjGH$CYJ?6MVc`yEXs>#-dZ`k_Kvyp=HHog5xZd` z4B#H9qgCS{i0|Dl{L(oNPxFy($t)J&9>0(f9ghwX<%vq1Bl?Nirj}zU9!e_JT?2at znCzy-Q-@v24_=}FkzAU(d&uM$Zf0?dOEYef;F*W>J$c5k&0gn87d%mA?-}!w(5nCv z92--oj&oT+o((<~V2OB;o07RU+S^kH35Eo=rR9Lj-jueV!+>2o;U__CrWI0|@R7_G zmGDI7aRG=gWo1t>)p3~LP>WM)?GY_(k>Zt~cG3Hvpv5xBOD=_FA_Qu{#M=Xtd`_38 zODJTi#HPjNK5`3kX6cp_y93o`kmr%XjN9J^YIL1&fdqzbE^GCh8HVMMD|tMdG5L0) z%FSGsDOd5h->{&<%`G6M%`&5IjglEbK6V69DGNwaoT_-FLN>#YOquBI;wt`fK2Tx! z#m#$D9Rw=0`9%h|9LgGwsbT_m<(4W4e$JiE!N5>{HhhKm=ATdF2}-8tFy;s8eOP*z z`!&g`-OPvWQ;{IlrxkI$SbP*etS-lr>PpDRb=47Z5ClSX2tOz&AKt;$!IdO=M@Gyt zb!7>Q*+qnD9`CSvV@{!y_emeBU`#8O7yBzBiv3Y>DYFlkRZjO_k^Nln-`TNo zMmgWQV}mb6uNZ3n12fXIuEye8U&E&x3hyTj7Z>jQ9}EkM77eE#=cJEXst$IIU?rQs zI{4e+1IIQwaByaiIz#iVU%LkByg{z1TDU6a#nxHWFjcsER+;@yJ2Tnlkp&A4XCq$Lxn z2Z+X?Yj1kJHp;_%q>U#UL8K9-|3|kj?FGm;gJeHZCXteFB>H#k1k#7=w)XY74^qTz z+BxoI%!wbpnw4|C+y$erksEXO9=&cv-k57eyxJGBA9$@(AnzZI$KLR+8QcHn*naq| F?=RuvD(wIO diff --git a/wasm_for_tests/vp_memory_limit.wasm b/wasm_for_tests/vp_memory_limit.wasm index a7e901a067daf49e3dbca6fbc1572a4a5d845934..424e288ae33a7bcf2dc7b1af2cfdd046c0cb8df0 100755 GIT binary patch delta 2764 zcma)8eNa@_6~E`cw_hv^&kw*|zTPhKq4K35DyVSz+C?^?MKCHTh{UicQKTJhD~pLS zF)9;0$w-VE6*0ud#N=T@w9}YsYwSepv`$Am(=k(F4o9cqtX?UnL{$EWeLrC zH)X7_E2|p96$Kbrxe2(!Yz#mF9tLU{cSKk?=KvfyvjFLU*=&mh`WPoA;#DvywA)I1 z6jjw!DWg@B1U!=^HwiMW7Zd0fs0aR_Q*5X1NkNW?roz`t-{ zQ*w-x7x5yUrE#k#On_I;G><~FO&Ft^BHPB?ah_;M$O7th9VMuEpmC+))>NzKyvJ4t`w5RaEq z?!i7BPEB{%B(lt7mc)u9snJ$jtl&b?Z5WwW4K`ezmh7_H$xX;-F*M``#6dD7PtT-V z@o-vIyvLfyvvq3-i)2F3MEHqaq$IeOY=ljV2S~=W>6?ijoPHaUjqVvk08X5pp+`8$ zUsdR0_;qsLiOm^@Aq#nCfh{Z2PFS9@D(K5B4Z6*`MRfB(I%DGFpx;5e%wjtacq}?p zIJgePwCQHALnW^)d3kk2~MOpfHPCM4i)vtUxhbaO!NfAl{X+xAHJ+TM_^$)3mK zXbl}%`=b;}3}|!HLCal5KIsI?EBe*&-F;`$rYwsbXCh_cJcLF1i}nr5=TY4 znLrAO2&C))O*ylFj$3D4ijbSF1jUY*35W!&%5f9g8H{;AOz9L;zVA^5t5SnHGvSLl zl~gO&bEZKOev=bVX%Uy3PV|N0h-8{Az9!%)z>O{aEO8PIzoL27HO=nbS@Bs}`5x zuJTge-H*R6k5bC1NbZy;raZRgaf8hMJIwMvO?LXc1OL^|Q)7R|Z!6;A5@!2jup!?~ z1rf~OLOGH~!`e2P1BgpA$~4{$~iMoBsCcv3573 zY#T*_MM^Ke+d{s>;ie}ZLMgUad5HE_y-QS7mk@ovx(Dw(g3e}>-CVW>85w^SIHmwYbylQp$4f{AtQP=q~o_hmQQxol8|Xk;%}L!o9bkHX3oBQk0^ty$@k zkw3Gtf+GKD<$JuZAJ^CW<#4vXL89wy@TQJM9wvq%AWrxHCvv+UCSHU9QENae!WSB5 zLLq+C@K0E1oLNN;yac~p-AuH(F-Y`w}Oif`$2Y>imA}T|0+#FR!Iu>&MKNS;RE8)W^yur;)~&p^c$J zj~-sLA7lay|+wWt$A@?QI94*r@1Q z1{BZHV6_T~#>jI=|Brak*f|V7WBm)exy*nEyAHd2bdFRzT7{lerhA0yC1P(Aym}KF zFJ(aj-hSyFSv^bYqi}F{namE#Aw%8M#vuha_PB`d?pXyX#@(Ku@`x1ilamCXMQ6gH zrQlHSuW0FkTryE9MAFipeYYZ6m50U3p02s*qE+#)=)x85TB@PD*zvzF-ygqn+~iZWx$C?}+xHEc}b1 zp*S-YZ9{SRFC#o8IZu)cIrS4YR>>H}EIN+f5(~c|vFikU(x8n=E+)2?Y`wpgg)uHGy`9 z!oX5XF)fOu$2ycp2!ymyJ0ShGg@UCiFwk0bqN8JQbf{FvYSm)LfmX5Oxf{@C)M?#6 z&OPTlkG;Qh&OP^DyJo#}&AO+|Yl_Mr>r~|e(N2iMwob-6`L=DWx6{d$ZN1%jOB0pl z9d<dg{!KjN-a5? zz?{(g$@=E|CT5J!FPK?a+0bZiYHpd3tc{yiu9|~$l^SQ}q{-QVDfbu8o>N*@SHEyk z>*5EN*oH6gj(GslOeXY*pJg$f32#`iVlKH6j6o}mppEB1Iu`Rm<#!G{YHdyrFX!bt z3vi3yCZI-;ae!-ng?JA-lo}qLk8R3pv=~Who>_`zw%@~4%(l;i9AmA07$6r*94jH$ z*zfo)*hfwdF>#ED)`q*19~mPnT4m}`T;*3BOy@cmmatBYwir9KLi4E3Ky9MJqxD8? z{7Z_do-lD-ky_-m>p+(6Y0^Pg!o}PonEgA(@zl40^C)(^^T3XM?oYvG98Y@_Cd7Bb zbd#`#$y{XXNw`SB<#j;)x zPAj{LCrY-%bS#)vjRzf)%Sfs=RmD4VX>nTijQ9caDFlJaOwIORTXh&aXRd%EyfAYh zkG2QWSdDx7l}H`61$pYA{bw-zR>?%Tf`6({MIGIk-e57gs4Z0tG%UbBlzOODpDXRk zx!bCIOskHSRMLfMG~kct9^>B|#4YpwDwpo^7ho2;#9l|wzz|K0^7zrzF(a6UKNp3( ze*mo&=cMK3it}>WSvgtu{E5m+@Z-mo2ERIhFIH8{<RH{X*wTWltUf&CUnT7>cL!uNm<%*(B~6ayPxHfzkHt&qTQ&g$OFoj-^euB@!P1+fY=JE7f@L8p?15#c_<zv^kP~!Gye-u_c5QM(wejJ~ zuR#LT()5E`eDtB2Wc%_%t2hbcR!=9PYIVCu&Q*;pK8QP#V4**W3tl|8`YD>eV$Cne z*1L8g(XO>Y@EE7pUQ|q0pGCJCTOxVfM}tj#;|XfpfQZo|2c5Vid?!JrGXnAy;8i(lAQ^r8V z4_A7PflX`TFp~+Up>58l=Sr#$TBt|ONf7%{F7UUy($ED?h-Z+tb!G;Dm;Yg#`} zqf73jkqvurOYEW}H$`K0jIkeC8MET}ST>$FT)aO87rpj?5qothJ$j7f({&1NIGci{ QXI)S3ID2}>S!jLbpIbc!a{vGU diff --git a/wasm_for_tests/vp_read_storage_key.wasm b/wasm_for_tests/vp_read_storage_key.wasm index 703a144bfffc9dd7fa6ea2b0d834ff2e91dab9dc..714f33edf132a310d268003280e52d03a56ce976 100755 GIT binary patch delta 33233 zcmchA349bq_J39N+>>M`=j4J+0=Y>@I06BL4EKEr2nd866G#Y2NP>WX10EdeD%xt} z0Rcrt1O=l6MG;*OP*l9}TETT)Jb$bw>hALYzV7KsM__di|IMd6^{QUI_v*b@ua2%B zzS!z`YOiBM?;;-Hm(4W?=;DF7rr=*KgUuC}U8X*O!;xZau5=k8-Y_TbhSgaCr{u4@ zB&x1#VOeEa=_L)NjsCLA(uPJq3!?&$v7l*jZF6b);;JftBMX-n)mpO0g}^P2 zPkEkvwQ~^9Z+*del=JTL?cwEkmRxYTyeeWvm#{Q3EL`#mujDnk7bemlA9sg`31^te z>E%d=$tkWW^4!RosT=-y5DZz72qPi9+$(%xHNHbnL)hbZxU1y%A{Q1K;8e-!qe@

h|ZkhJ|zA#w#FiPc$>D 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 z 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 delta 31755 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 sajozPd7Ro+5uL