diff --git a/.changelog/v0.15.4/bug-fixes/1405-bugfix-replay-prepare.md b/.changelog/v0.15.4/bug-fixes/1405-bugfix-replay-prepare.md
new file mode 100644
index 0000000000..a32b40e2b3
--- /dev/null
+++ b/.changelog/v0.15.4/bug-fixes/1405-bugfix-replay-prepare.md
@@ -0,0 +1,3 @@
+- Fixed a bug in `prepare_proposal` causing the creation
+ of blocks containing already applied transactions.
+ ([#1405](https://github.com/anoma/namada/pull/1405))
\ No newline at end of file
diff --git a/.changelog/v0.15.4/improvements/1399-consensus_params.md b/.changelog/v0.15.4/improvements/1399-consensus_params.md
new file mode 100644
index 0000000000..5e2ee441c0
--- /dev/null
+++ b/.changelog/v0.15.4/improvements/1399-consensus_params.md
@@ -0,0 +1,2 @@
+- Make Tendermint consensus paramenters configurable via Namada configuration.
+ ([#1399](https://github.com/anoma/namada/pull/1399))
\ No newline at end of file
diff --git a/.changelog/v0.15.4/improvements/1407-tx-validation-log.md b/.changelog/v0.15.4/improvements/1407-tx-validation-log.md
new file mode 100644
index 0000000000..5d74828736
--- /dev/null
+++ b/.changelog/v0.15.4/improvements/1407-tx-validation-log.md
@@ -0,0 +1,2 @@
+- Improved error logs in `process_proposal` and added more info to
+ `InternalStats` ([#1407](https://github.com/anoma/namada/pull/1407))
\ No newline at end of file
diff --git a/.changelog/v0.15.4/summary.md b/.changelog/v0.15.4/summary.md
new file mode 100644
index 0000000000..c5f4bc8610
--- /dev/null
+++ b/.changelog/v0.15.4/summary.md
@@ -0,0 +1,2 @@
+Namada 0.15.4 is a maintenance release addressing the invalid creation of blocks due to missing replay protection checks during prepare
+proposal.
diff --git a/.changelog/v0.16.0/improvements/925-shared-sdk-integration.md b/.changelog/v0.16.0/improvements/925-shared-sdk-integration.md
new file mode 100644
index 0000000000..49514ba8f7
--- /dev/null
+++ b/.changelog/v0.16.0/improvements/925-shared-sdk-integration.md
@@ -0,0 +1,3 @@
+- Provide Namada SDK (in particular, the `namada`
+crate may now be usefully linked into user
+applications). ([#925](https://github.com/anoma/namada/pull/925))
diff --git a/.changelog/v0.17.1/bug-fixes/1455-persist-epoch-update-delay.md b/.changelog/v0.17.1/bug-fixes/1455-persist-epoch-update-delay.md
new file mode 100644
index 0000000000..7560aa3f4c
--- /dev/null
+++ b/.changelog/v0.17.1/bug-fixes/1455-persist-epoch-update-delay.md
@@ -0,0 +1,3 @@
+- Persists a newly added storage field for epoch update blocks delay to be
+ available after node restart when not `None` which may break consensus.
+ ([\#1455](https://github.com/anoma/namada/pull/1455))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/bug-fixes/1456-fix-max-wait-tries.md b/.changelog/v0.17.1/bug-fixes/1456-fix-max-wait-tries.md
new file mode 100644
index 0000000000..fdf18ff5ec
--- /dev/null
+++ b/.changelog/v0.17.1/bug-fixes/1456-fix-max-wait-tries.md
@@ -0,0 +1,2 @@
+- Client: Fixed an off-by-one error to stop waiting for start or catch-up when
+ max tries are reached. ([\#1456](https://github.com/anoma/namada/pull/1456))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/bug-fixes/1474-fix-sdk-tx-with-hash.md b/.changelog/v0.17.1/bug-fixes/1474-fix-sdk-tx-with-hash.md
new file mode 100644
index 0000000000..991a67f952
--- /dev/null
+++ b/.changelog/v0.17.1/bug-fixes/1474-fix-sdk-tx-with-hash.md
@@ -0,0 +1,2 @@
+- Include the wasm tx hash instead of the wasm blob when constructing a
+ transaction ([#1474](https://github.com/anoma/namada/pull/1474))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/bug-fixes/1534-fix-block-query.md b/.changelog/v0.17.1/bug-fixes/1534-fix-block-query.md
new file mode 100644
index 0000000000..8bfe764e11
--- /dev/null
+++ b/.changelog/v0.17.1/bug-fixes/1534-fix-block-query.md
@@ -0,0 +1,2 @@
+- Fix a client block query to avoid seeing pre-committed blocks.
+ ([\#1534](https://github.com/anoma/namada/pull/1534))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/docs/889-gas-and-fee-specs.md b/.changelog/v0.17.1/docs/889-gas-and-fee-specs.md
new file mode 100644
index 0000000000..e6a4021cf8
--- /dev/null
+++ b/.changelog/v0.17.1/docs/889-gas-and-fee-specs.md
@@ -0,0 +1 @@
+- Adds specs for gas and fee ([#889](https://github.com/anoma/namada/pull/889))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/features/1110-wallet-deterministic.md b/.changelog/v0.17.1/features/1110-wallet-deterministic.md
new file mode 100644
index 0000000000..d9551b5ea6
--- /dev/null
+++ b/.changelog/v0.17.1/features/1110-wallet-deterministic.md
@@ -0,0 +1,2 @@
+- Implements HD wallet derivation / recovery from a given mnemonic code
+ ([\#1110](https://github.com/anoma/namada/pull/1110))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/features/1344-find-validator-by-tm.md b/.changelog/v0.17.1/features/1344-find-validator-by-tm.md
new file mode 100644
index 0000000000..f0e923c31a
--- /dev/null
+++ b/.changelog/v0.17.1/features/1344-find-validator-by-tm.md
@@ -0,0 +1,3 @@
+- PoS: Added a client command `find-validator --tm-address
`
+ to find validator's Namada address by Tendermint address.
+ ([\#1344](https://github.com/anoma/namada/pull/1344))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/features/892-cubic-slashing.md b/.changelog/v0.17.1/features/892-cubic-slashing.md
new file mode 100644
index 0000000000..cdd079bfc3
--- /dev/null
+++ b/.changelog/v0.17.1/features/892-cubic-slashing.md
@@ -0,0 +1,5 @@
+- The implementation of the cubic slashing system that touches virtually all
+ parts of the proof-of-stake system. Slashes tokens are currently kept in the
+ PoS address rather than being transferred to the Slash Pool address. This PR
+ also includes significant testing infrastructure, highlighted by the PoS state
+ machine test with slashing. ([#892](https://github.com/anoma/namada/pull/892))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/improvements/1093-signable-txs.md b/.changelog/v0.17.1/improvements/1093-signable-txs.md
new file mode 100644
index 0000000000..e1e244bd0f
--- /dev/null
+++ b/.changelog/v0.17.1/improvements/1093-signable-txs.md
@@ -0,0 +1,2 @@
+- Make Namada transactions signable on hardware constrained wallets by making
+ them smaller. ([#1093](https://github.com/anoma/namada/pull/1093))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/improvements/1238-optinal-multicore-feature.md b/.changelog/v0.17.1/improvements/1238-optinal-multicore-feature.md
new file mode 100644
index 0000000000..ee1a0c1ba1
--- /dev/null
+++ b/.changelog/v0.17.1/improvements/1238-optinal-multicore-feature.md
@@ -0,0 +1,4 @@
+- Added `multicore` feature flag to the namada and namada_core
+ crate that can be switched off for JS WASM build.
+ Additionally, changed the `trait ShieldedUtils` to be async.
+ ([\#1238](https://github.com/anoma/namada/pull/1238))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/improvements/1425-wallet-zeroize.md b/.changelog/v0.17.1/improvements/1425-wallet-zeroize.md
new file mode 100644
index 0000000000..ab32b10f65
--- /dev/null
+++ b/.changelog/v0.17.1/improvements/1425-wallet-zeroize.md
@@ -0,0 +1,2 @@
+- Zeroizes memory containing passphrases in wallet.
+ ([\#1425](https://github.com/anoma/namada/issues/1425))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/improvements/1432-missing-args-def.md b/.changelog/v0.17.1/improvements/1432-missing-args-def.md
new file mode 100644
index 0000000000..9c49f92e49
--- /dev/null
+++ b/.changelog/v0.17.1/improvements/1432-missing-args-def.md
@@ -0,0 +1,2 @@
+- Added some missing cli option for cli wallet
+ ([#1432](https://github.com/anoma/namada/pull/1432))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/improvements/1434-improve-cli-commission-rate.md b/.changelog/v0.17.1/improvements/1434-improve-cli-commission-rate.md
new file mode 100644
index 0000000000..e5adfe06db
--- /dev/null
+++ b/.changelog/v0.17.1/improvements/1434-improve-cli-commission-rate.md
@@ -0,0 +1,2 @@
+- Improve logging error when submiting an invalid validator commission change tx
+ ([#1434](https://github.com/anoma/namada/pull/1434))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/improvements/1435-fix-err-typos.md b/.changelog/v0.17.1/improvements/1435-fix-err-typos.md
new file mode 100644
index 0000000000..60e80421e5
--- /dev/null
+++ b/.changelog/v0.17.1/improvements/1435-fix-err-typos.md
@@ -0,0 +1,2 @@
+- Correct a typo in the error change commission error handling
+ ([#1435](https://github.com/anoma/namada/pull/1435))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/improvements/1436-rename-tx-reveal-arg.md b/.changelog/v0.17.1/improvements/1436-rename-tx-reveal-arg.md
new file mode 100644
index 0000000000..3cb5fdc29b
--- /dev/null
+++ b/.changelog/v0.17.1/improvements/1436-rename-tx-reveal-arg.md
@@ -0,0 +1,2 @@
+- Improve the reveal tx naming in cli
+ ([#1436](https://github.com/anoma/namada/pull/1436))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/improvements/1444-cse-in-inflation.md b/.changelog/v0.17.1/improvements/1444-cse-in-inflation.md
new file mode 100644
index 0000000000..f5a89ac9b2
--- /dev/null
+++ b/.changelog/v0.17.1/improvements/1444-cse-in-inflation.md
@@ -0,0 +1,2 @@
+- Improve computations readability when calculating inflations
+ ([#1444](https://github.com/anoma/namada/pull/1444))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/improvements/1449-rm-abciplus-cargo-deps.md b/.changelog/v0.17.1/improvements/1449-rm-abciplus-cargo-deps.md
new file mode 100644
index 0000000000..91527ebfb2
--- /dev/null
+++ b/.changelog/v0.17.1/improvements/1449-rm-abciplus-cargo-deps.md
@@ -0,0 +1 @@
+- Remove abci++ dependencies ([#1449](https://github.com/anoma/namada/pull/1449))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/improvements/1462-restructure-tx-draft.md b/.changelog/v0.17.1/improvements/1462-restructure-tx-draft.md
new file mode 100644
index 0000000000..7fc3dca855
--- /dev/null
+++ b/.changelog/v0.17.1/improvements/1462-restructure-tx-draft.md
@@ -0,0 +1,2 @@
+- Reorganize the structure of transactions
+ ([#1462](https://github.com/anoma/namada/pull/1462))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/improvements/1509-improve-pos-logging.md b/.changelog/v0.17.1/improvements/1509-improve-pos-logging.md
new file mode 100644
index 0000000000..010d881000
--- /dev/null
+++ b/.changelog/v0.17.1/improvements/1509-improve-pos-logging.md
@@ -0,0 +1,2 @@
+- Improved log entries related to PoS system.
+ ([\#1509](https://github.com/anoma/namada/pull/1509))
\ No newline at end of file
diff --git a/.changelog/v0.17.1/summary.md b/.changelog/v0.17.1/summary.md
new file mode 100644
index 0000000000..0491959a0a
--- /dev/null
+++ b/.changelog/v0.17.1/summary.md
@@ -0,0 +1,2 @@
+Namada 0.17.0 is a scheduled minor release featuring several improvements to the slashing mechanism,
+wallet address derivation, transaction structure and the ledger stability.
diff --git a/.changelog/v0.17.2/bug-fixes/1504-wallet-address-add-fix.md b/.changelog/v0.17.2/bug-fixes/1504-wallet-address-add-fix.md
new file mode 100644
index 0000000000..18420800a1
--- /dev/null
+++ b/.changelog/v0.17.2/bug-fixes/1504-wallet-address-add-fix.md
@@ -0,0 +1,2 @@
+- Do not add address if it already exists in the wallet.
+ ([\#1504](https://github.com/anoma/namada/issues/1504))
diff --git a/.changelog/v0.17.2/bug-fixes/1520-fix-sum-post-bonds-slashing.md b/.changelog/v0.17.2/bug-fixes/1520-fix-sum-post-bonds-slashing.md
new file mode 100644
index 0000000000..bed4b5f534
--- /dev/null
+++ b/.changelog/v0.17.2/bug-fixes/1520-fix-sum-post-bonds-slashing.md
@@ -0,0 +1,5 @@
+- When processing slashes, bonds and unbonds that became active after
+ the infraction epoch must be properly accounted in order to properly
+ deduct stake that accounts for the precise slash amount. A bug
+ is fixed in the procedure that properly performs this accounting.
+ ([#1520](https://github.com/anoma/namada/pull/1520))
\ No newline at end of file
diff --git a/.changelog/v0.17.2/bug-fixes/1522-client-fix-wait-msg.md b/.changelog/v0.17.2/bug-fixes/1522-client-fix-wait-msg.md
new file mode 100644
index 0000000000..0a082cd560
--- /dev/null
+++ b/.changelog/v0.17.2/bug-fixes/1522-client-fix-wait-msg.md
@@ -0,0 +1,2 @@
+- Fix the message when a client is waiting for a node to sync on queries or
+ transactions. ([\#1522](https://github.com/anoma/namada/pull/1522))
\ No newline at end of file
diff --git a/.changelog/v0.17.2/bug-fixes/1524-fix-dry-run-header-and-prover.md b/.changelog/v0.17.2/bug-fixes/1524-fix-dry-run-header-and-prover.md
new file mode 100644
index 0000000000..d1baea14a6
--- /dev/null
+++ b/.changelog/v0.17.2/bug-fixes/1524-fix-dry-run-header-and-prover.md
@@ -0,0 +1,2 @@
+- This change will enable usage of the Namada SDK to create MASP transactions
+ from non-CLI clients. ([\#1524](https://github.com/anoma/namada/pull/1524))
\ No newline at end of file
diff --git a/.changelog/v0.17.2/bug-fixes/1528-balances-fix-issue-758.md b/.changelog/v0.17.2/bug-fixes/1528-balances-fix-issue-758.md
new file mode 100644
index 0000000000..3ab09e8210
--- /dev/null
+++ b/.changelog/v0.17.2/bug-fixes/1528-balances-fix-issue-758.md
@@ -0,0 +1,2 @@
+- Fixing how token balances are displayed in case of missing --token option.
+ ([#1528](https://github.com/anoma/namada/pull/1528))
\ No newline at end of file
diff --git a/.changelog/v0.17.2/bug-fixes/1533-fix-slashing-client-query.md b/.changelog/v0.17.2/bug-fixes/1533-fix-slashing-client-query.md
new file mode 100644
index 0000000000..24b3646264
--- /dev/null
+++ b/.changelog/v0.17.2/bug-fixes/1533-fix-slashing-client-query.md
@@ -0,0 +1,3 @@
+- The slashed token amounts contained inside the bond and unbond information
+ returned by the PoS library fn bonds_and_unbonds are fixed and properly
+ computed. ([#1533](https://github.com/anoma/namada/pull/1533))
\ No newline at end of file
diff --git a/.changelog/v0.17.2/bug-fixes/1549-fix-init-validator-tm-mode.md b/.changelog/v0.17.2/bug-fixes/1549-fix-init-validator-tm-mode.md
new file mode 100644
index 0000000000..33000a423d
--- /dev/null
+++ b/.changelog/v0.17.2/bug-fixes/1549-fix-init-validator-tm-mode.md
@@ -0,0 +1,3 @@
+- PoS: Fixed the client to change configuration to validator
+ mode after a successful `init-validator` transaction.
+ ([\#1549](https://github.com/anoma/namada/pull/1549))
\ No newline at end of file
diff --git a/.changelog/v0.17.2/bug-fixes/1553-fix-is-validator-fn.md b/.changelog/v0.17.2/bug-fixes/1553-fix-is-validator-fn.md
new file mode 100644
index 0000000000..c66e587913
--- /dev/null
+++ b/.changelog/v0.17.2/bug-fixes/1553-fix-is-validator-fn.md
@@ -0,0 +1,3 @@
+- PoS: fixed a check for whether a given address belongs to a
+ validator account to work properly with newly created accounts.
+ ([\#1553](https://github.com/anoma/namada/pull/1553))
\ No newline at end of file
diff --git a/.changelog/v0.17.2/bug-fixes/1558-fix-slash-logging.md b/.changelog/v0.17.2/bug-fixes/1558-fix-slash-logging.md
new file mode 100644
index 0000000000..3b3df8cce3
--- /dev/null
+++ b/.changelog/v0.17.2/bug-fixes/1558-fix-slash-logging.md
@@ -0,0 +1,3 @@
+- Fixes the slash rate output in the query_slashes client
+ command and some redundancy in misbehavior reporting logs.
+ ([#1558](https://github.com/anoma/namada/pull/1558))
\ No newline at end of file
diff --git a/.changelog/v0.17.2/improvements/1491-utils-base-dir.md b/.changelog/v0.17.2/improvements/1491-utils-base-dir.md
new file mode 100644
index 0000000000..6ec06cb49a
--- /dev/null
+++ b/.changelog/v0.17.2/improvements/1491-utils-base-dir.md
@@ -0,0 +1,4 @@
+- Add a command, `namadac utils default-base-dir`, to
+ print the default base directory the command
+ line would use were one not provided by the user.
+ ([#1491](https://github.com/anoma/namada/pull/1491))
diff --git a/.changelog/v0.17.2/improvements/1510-established-addr-bytes.md b/.changelog/v0.17.2/improvements/1510-established-addr-bytes.md
new file mode 100644
index 0000000000..4f25dfff9f
--- /dev/null
+++ b/.changelog/v0.17.2/improvements/1510-established-addr-bytes.md
@@ -0,0 +1,3 @@
+- Improve the established address in-memory representation
+ and use a full SHA-256 digest for their generation.
+ ([\#1510](https://github.com/anoma/namada/pull/1510))
\ No newline at end of file
diff --git a/.changelog/v0.17.2/improvements/1512-implicit-addr-bytes.md b/.changelog/v0.17.2/improvements/1512-implicit-addr-bytes.md
new file mode 100644
index 0000000000..250aa01d77
--- /dev/null
+++ b/.changelog/v0.17.2/improvements/1512-implicit-addr-bytes.md
@@ -0,0 +1,2 @@
+- Improve the implicit address and PKH in-memory representation.
+ ([\#1512](https://github.com/anoma/namada/pull/1512))
\ No newline at end of file
diff --git a/.changelog/v0.17.2/improvements/1514-wallet-message-fix.md b/.changelog/v0.17.2/improvements/1514-wallet-message-fix.md
new file mode 100644
index 0000000000..b50a9149f6
--- /dev/null
+++ b/.changelog/v0.17.2/improvements/1514-wallet-message-fix.md
@@ -0,0 +1,2 @@
+- Improve help message for address add command
+ ([\#1514](https://github.com/anoma/namada/issues/1514))
\ No newline at end of file
diff --git a/.changelog/v0.17.2/improvements/1518-pos-bonds-query-reuse.md b/.changelog/v0.17.2/improvements/1518-pos-bonds-query-reuse.md
new file mode 100644
index 0000000000..84f7a75e63
--- /dev/null
+++ b/.changelog/v0.17.2/improvements/1518-pos-bonds-query-reuse.md
@@ -0,0 +1,2 @@
+- PoS: make a re-usable bonds and unbonds details query.
+ ([\#1518](https://github.com/anoma/namada/pull/1518))
\ No newline at end of file
diff --git a/.changelog/v0.17.2/summary.md b/.changelog/v0.17.2/summary.md
new file mode 100644
index 0000000000..858698bd0b
--- /dev/null
+++ b/.changelog/v0.17.2/summary.md
@@ -0,0 +1,2 @@
+Namada 0.17.2 is a minor release featuring improvements to the client stability.
+
diff --git a/.changelog/v0.17.3/bug-fixes/1345-key-parsing-fix.md b/.changelog/v0.17.3/bug-fixes/1345-key-parsing-fix.md
new file mode 100644
index 0000000000..e7d8f19ee8
--- /dev/null
+++ b/.changelog/v0.17.3/bug-fixes/1345-key-parsing-fix.md
@@ -0,0 +1,2 @@
+- Correctly handle parsing storage key if they are empty.
+ ([#1345](https://github.com/anoma/namada/pull/1345))
\ No newline at end of file
diff --git a/.changelog/v0.17.3/features/1570-tendermint-config.md b/.changelog/v0.17.3/features/1570-tendermint-config.md
new file mode 100644
index 0000000000..888fda8928
--- /dev/null
+++ b/.changelog/v0.17.3/features/1570-tendermint-config.md
@@ -0,0 +1,2 @@
+- Enable users to change any tendermint config options via namada config.
+ ([#1570](https://github.com/anoma/namada/pull/1570))
\ No newline at end of file
diff --git a/.changelog/v0.17.3/improvements/1404-ibc-event-query.md b/.changelog/v0.17.3/improvements/1404-ibc-event-query.md
new file mode 100644
index 0000000000..8e1c096f11
--- /dev/null
+++ b/.changelog/v0.17.3/improvements/1404-ibc-event-query.md
@@ -0,0 +1,2 @@
+- Added query endpoint for IBC events replacing Tendermint index.
+ ([\#1404](https://github.com/anoma/namada/pull/1404))
\ No newline at end of file
diff --git a/.changelog/v0.17.3/miscellaneous/1476-cometbft.md b/.changelog/v0.17.3/miscellaneous/1476-cometbft.md
new file mode 100644
index 0000000000..a1a23432ac
--- /dev/null
+++ b/.changelog/v0.17.3/miscellaneous/1476-cometbft.md
@@ -0,0 +1,2 @@
+- Switch from unreleased Tendermint fork to an official CometBFT release
+ v0.37.1. ([\#1476](https://github.com/anoma/namada/pull/1476))
\ No newline at end of file
diff --git a/.changelog/v0.17.3/summary.md b/.changelog/v0.17.3/summary.md
new file mode 100644
index 0000000000..2bfbb16476
--- /dev/null
+++ b/.changelog/v0.17.3/summary.md
@@ -0,0 +1 @@
+Namada 0.17.3 is a minor release switching from tendermint to cometbft.
diff --git a/.changelog/v0.17.4/bug-fixes/1588-fix-masp-missing-await.md b/.changelog/v0.17.4/bug-fixes/1588-fix-masp-missing-await.md
new file mode 100644
index 0000000000..79a6f32b21
--- /dev/null
+++ b/.changelog/v0.17.4/bug-fixes/1588-fix-masp-missing-await.md
@@ -0,0 +1,2 @@
+- Fix missing async awaits in MASP load and save calls.
+ ([\#1588](https://github.com/anoma/namada/pull/1588))
\ No newline at end of file
diff --git a/.changelog/v0.17.4/summary.md b/.changelog/v0.17.4/summary.md
new file mode 100644
index 0000000000..f2074f1311
--- /dev/null
+++ b/.changelog/v0.17.4/summary.md
@@ -0,0 +1 @@
+Namada 0.17.4 is a minor release improving the codebase by bumping the rust toolchain.
diff --git a/.changelog/v0.17.5/improvements/1619-masp-checked.md b/.changelog/v0.17.5/improvements/1619-masp-checked.md
new file mode 100644
index 0000000000..c862efa193
--- /dev/null
+++ b/.changelog/v0.17.5/improvements/1619-masp-checked.md
@@ -0,0 +1,2 @@
+- Check MASP parameters are correct in the ledger node.
+ ([#1619](https://github.com/anoma/namada/pull/1619))
\ No newline at end of file
diff --git a/.changelog/v0.17.5/summary.md b/.changelog/v0.17.5/summary.md
new file mode 100644
index 0000000000..f05b6a2973
--- /dev/null
+++ b/.changelog/v0.17.5/summary.md
@@ -0,0 +1,2 @@
+Namada 0.17.5 is a maintenance release chiefly addressing MASP
+parameter validation.
diff --git a/.github/workflows/build-and-test-bridge.yml b/.github/workflows/build-and-test-bridge.yml
index 6520413e92..c6bf2ead2f 100644
--- a/.github/workflows/build-and-test-bridge.yml
+++ b/.github/workflows/build-and-test-bridge.yml
@@ -36,7 +36,7 @@ jobs:
matrix:
os: [ubuntu-20.04]
wasm_cache_version: ["v2"]
- mold_version: [1.7.0]
+ mold_version: [1.11.0]
steps:
- name: Checkout repo
@@ -78,7 +78,7 @@ jobs:
matrix:
os: [ubuntu-20.04]
wasm_cache_version: ["v2"]
- mold_version: [1.7.0]
+ mold_version: [1.11.0]
steps:
- name: Checkout repo
@@ -144,14 +144,13 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-20.04]
- nightly_version: [nightly-2022-11-03]
- mold_version: [1.7.0]
+ nightly_version: [nightly-2023-06-01]
+ mold_version: [1.11.0]
make:
- name: ABCI
suffix: ''
cache_key: namada
cache_version: v2
- tendermint_artifact: tendermint-unreleased-v0.1.4-abciplus
env:
CARGO_INCREMENTAL: 0
@@ -251,7 +250,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-20.04]
- mold_version: [1.7.0]
+ mold_version: [1.11.0]
make:
- name: ABCI Release build
suffix: ''
@@ -324,7 +323,7 @@ jobs:
- name: Build
run: make build-release${{ matrix.make.suffix }}
env:
- RUSTFLAGS: "-C linker=clang -C link-arg=-fuse-ld=/usr/local/bin/mold"
+ RUSTFLAGS: "-C linker=clang -C debug_assertions=true -C link-arg=-fuse-ld=/usr/local/bin/mold"
- name: Upload target binaries
uses: actions/upload-artifact@v3
with:
@@ -357,22 +356,20 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-20.04]
- nightly_version: [nightly-2022-11-03]
- mold_version: [1.7.0]
+ nightly_version: [nightly-2023-06-01]
+ mold_version: [1.11.0]
make:
- name: e2e
suffix: ''
index: 0
cache_key: namada
cache_version: v2
- 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-v0.1.4-abciplus
wait_for: namada-release-eth (ubuntu-20.04, 1.7.0, ABCI Release build, namada-e2e-release, v2)
env:
@@ -443,20 +440,6 @@ jobs:
run: |
wget -q -O- https://github.com/rui314/mold/releases/download/v${{ matrix.mold_version }}/mold-${{ matrix.mold_version }}-x86_64-linux.tar.gz | tar -xz
mv mold-${{ matrix.mold_version }}-x86_64-linux/bin/mold /usr/local/bin
- - name: Download tendermint binaries
- uses: dawidd6/action-download-artifact@v2
- with:
- github_token: ${{secrets.GITHUB_TOKEN}}
- workflow: build-tendermint.yml
- workflow_conclusion: success
- name: ${{ matrix.make.tendermint_artifact }}
- path: /usr/local/bin
- - name: Download masp parameters
- run: |
- mkdir /home/runner/work/masp
- curl -o /home/runner/work/masp/masp-spend.params -sLO https://github.com/anoma/masp/blob/ef0ef75e81696ff4428db775c654fbec1b39c21f/masp-spend.params?raw=true
- curl -o /home/runner/work/masp/masp-output.params -sLO https://github.com/anoma/masp/blob/ef0ef75e81696ff4428db775c654fbec1b39c21f/masp-output.params?raw=true
- curl -o /home/runner/work/masp/masp-convert.params -sLO https://github.com/anoma/masp/blob/ef0ef75e81696ff4428db775c654fbec1b39c21f/masp-convert.params?raw=true
- name: Build
run: make build
env:
@@ -483,6 +466,14 @@ jobs:
with:
name: binaries${{ matrix.make.suffix }}-${{ github.event.pull_request.head.sha || github.sha }}
path: ./target/release/
+ - name: Download tendermint & cometbft
+ run: |
+ curl -o cometbft.tar.gz -LO https://github.com/cometbft/cometbft/releases/download/v0.37.2/cometbft_0.37.2_linux_amd64.tar.gz
+ tar -xvzf cometbft.tar.gz
+ mv cometbft /usr/local/bin
+ curl -o tendermint.tar.gz -LO https://github.com/heliaxdev/tendermint/releases/download/v0.1.4-abciplus/tendermint_0.1.4-abciplus_linux_amd64.tar.gz
+ tar -xvzf tendermint.tar.gz
+ mv tendermint /usr/local/bin
- name: Change permissions
run: |
chmod +x target/release/namada
@@ -490,15 +481,22 @@ jobs:
chmod +x target/release/namadan
chmod +x target/release/namadac
chmod +x /usr/local/bin/tendermint
+ chmod +x /usr/local/bin/cometbft
- name: Run e2e test
- run: python3 .github/workflows/scripts/schedule-e2e.py
+ run: |
+ mkdir -p /home/runner/work/masp-params
+ curl -o /home/runner/work/masp-params/masp-spend.params -LO https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup/masp-spend.params?raw=true
+ curl -o /home/runner/work/masp-params/masp-output.params -LO https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup/masp-output.params?raw=true
+ curl -o /home/runner/work/masp-params/masp-convert.params -LO https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup/masp-convert.params?raw=true
+ ls -l /home/runner/work/masp-params
+ shasum /home/runner/work/masp-params/*.params
+ python3 .github/workflows/scripts/schedule-e2e.py
env:
- NAMADA_TENDERMINT_WEBSOCKET_TIMEOUT: 20
NAMADA_E2E_USE_PREBUILT_BINARIES: "true"
NAMADA_E2E_KEEP_TEMP: "true"
NAMADA_TM_STDOUT: "false"
NAMADA_LOG_COLOR: "false"
- NAMADA_MASP_PARAMS_DIR: "/home/runner/work/masp"
+ # NAMADA_MASP_PARAMS_DIR: "/home/runner/work/masp-params"
NAMADA_LOG: "info"
RUSTFLAGS: "-C linker=clang -C link-arg=-fuse-ld=/usr/local/bin/mold"
INDEX: ${{ matrix.make.index }}
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index b07e2212e9..783509d291 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -37,7 +37,7 @@ jobs:
matrix:
os: [ubuntu-20.04]
wasm_cache_version: ["v2"]
- mold_version: [1.7.0]
+ mold_version: [1.11.0]
steps:
- name: Checkout repo
@@ -79,7 +79,8 @@ jobs:
matrix:
os: [ubuntu-20.04]
wasm_cache_version: ["v2"]
- mold_version: [1.7.0]
+ nightly_version: [nightly-2023-06-01]
+ mold_version: [1.11.0]
steps:
- name: Checkout repo
@@ -103,6 +104,11 @@ jobs:
path: ./wasm
env:
RUSTFLAGS: "-C linker=clang -C link-arg=-fuse-ld=/usr/local/bin/mold"
+ - name: Setup rust nightly
+ uses: oxidecomputer/actions-rs_toolchain@ad3f86084a8a5acf2c09cb691421b31cf8af7a36
+ with:
+ toolchain: ${{ matrix.nightly_version }}
+ profile: default
- name: Test Wasm
run: make test-wasm
- name: Check wasm up-to-date
@@ -146,8 +152,8 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-20.04]
- nightly_version: [nightly-2022-11-03]
- mold_version: [1.7.0]
+ nightly_version: [nightly-2023-06-01]
+ mold_version: [1.11.0]
make:
- name: ABCI
suffix: ''
@@ -235,6 +241,8 @@ jobs:
name: wasm-${{ github.event.pull_request.head.sha|| github.sha }}
path: ./wasm
- uses: taiki-e/install-action@cargo-llvm-cov
+ - name: Check crates build with default features
+ run: make check-crates
- name: Run unit test
run: make test-unit-coverage${{ matrix.make.suffix }}
env:
@@ -259,7 +267,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-20.04]
- mold_version: [1.7.0]
+ mold_version: [1.11.0]
make:
- name: ABCI Release build
suffix: ''
@@ -338,7 +346,7 @@ jobs:
- name: Build
run: make build-release${{ matrix.make.suffix }}
env:
- RUSTFLAGS: "-C linker=clang -C link-arg=-fuse-ld=/usr/local/bin/mold"
+ RUSTFLAGS: "-C linker=clang -C debug_assertions=true -C link-arg=-fuse-ld=/usr/local/bin/mold"
- name: Upload target binaries
uses: actions/upload-artifact@v3
with:
@@ -366,12 +374,12 @@ jobs:
namada-e2e:
runs-on: ${{ matrix.os }}
- timeout-minutes: 80
+ # timeout-minutes: 80
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04]
- nightly_version: [nightly-2022-11-03]
+ nightly_version: [nightly-2023-06-01]
mold_version: [1.7.0]
make:
- name: e2e
@@ -380,14 +388,21 @@ jobs:
cache_key: namada
cache_version: v2
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)
+ wait_for: namada-release (ubuntu-20.04, 1.11.0, ABCI Release build, namada-e2e-release, v2)
- name: e2e
suffix: ''
index: 1
cache_key: namada
cache_version: v2
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)
+ wait_for: namada-release (ubuntu-20.04, 1.11.0, ABCI Release build, namada-e2e-release, v2)
+ - name: e2e
+ suffix: ''
+ index: 2
+ cache_key: namada
+ cache_version: v2
+ tendermint_artifact: tendermint-unreleased-v0.1.4-abciplus
+ wait_for: namada-release (ubuntu-20.04, 1.11.0, ABCI Release build, namada-e2e-release, v2)
env:
CARGO_INCREMENTAL: 0
@@ -463,20 +478,6 @@ jobs:
run: |
wget -q -O- https://github.com/rui314/mold/releases/download/v${{ matrix.mold_version }}/mold-${{ matrix.mold_version }}-x86_64-linux.tar.gz | tar -xz
mv mold-${{ matrix.mold_version }}-x86_64-linux/bin/mold /usr/local/bin
- - name: Download tendermint binaries
- uses: dawidd6/action-download-artifact@v2
- with:
- github_token: ${{secrets.GITHUB_TOKEN}}
- workflow: build-tendermint.yml
- workflow_conclusion: success
- name: ${{ matrix.make.tendermint_artifact }}
- path: /usr/local/bin
- - name: Download masp parameters
- run: |
- mkdir /home/runner/work/masp
- curl -o /home/runner/work/masp/masp-spend.params -sLO https://github.com/anoma/masp/blob/ef0ef75e81696ff4428db775c654fbec1b39c21f/masp-spend.params?raw=true
- curl -o /home/runner/work/masp/masp-output.params -sLO https://github.com/anoma/masp/blob/ef0ef75e81696ff4428db775c654fbec1b39c21f/masp-output.params?raw=true
- curl -o /home/runner/work/masp/masp-convert.params -sLO https://github.com/anoma/masp/blob/ef0ef75e81696ff4428db775c654fbec1b39c21f/masp-convert.params?raw=true
- name: Build
run: make build
env:
@@ -503,6 +504,14 @@ jobs:
with:
name: binaries${{ matrix.make.suffix }}-${{ github.event.pull_request.head.sha || github.sha }}
path: ./target/release/
+ - name: Download tendermint & cometbft
+ run: |
+ curl -o cometbft.tar.gz -LO https://github.com/cometbft/cometbft/releases/download/v0.37.2/cometbft_0.37.2_linux_amd64.tar.gz
+ tar -xvzf cometbft.tar.gz
+ mv cometbft /usr/local/bin
+ curl -o tendermint.tar.gz -LO https://github.com/heliaxdev/tendermint/releases/download/v0.1.4-abciplus/tendermint_0.1.4-abciplus_linux_amd64.tar.gz
+ tar -xvzf tendermint.tar.gz
+ mv tendermint /usr/local/bin
- name: Change permissions
run: |
chmod +x target/release/namada
@@ -510,15 +519,23 @@ jobs:
chmod +x target/release/namadan
chmod +x target/release/namadac
chmod +x /usr/local/bin/tendermint
+ chmod +x /usr/local/bin/cometbft
- name: Run e2e test
- run: python3 .github/workflows/scripts/schedule-e2e.py
+ run: |
+ mkdir -p /home/runner/work/masp-params
+ curl -o /home/runner/work/masp-params/masp-spend.params -LO https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup/masp-spend.params?raw=true
+ curl -o /home/runner/work/masp-params/masp-output.params -LO https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup/masp-output.params?raw=true
+ curl -o /home/runner/work/masp-params/masp-convert.params -LO https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup/masp-convert.params?raw=true
+ ls -l /home/runner/work/masp-params
+ shasum /home/runner/work/masp-params/*.params
+ python3 .github/workflows/scripts/schedule-e2e.py
env:
NAMADA_TENDERMINT_WEBSOCKET_TIMEOUT: 20
NAMADA_E2E_USE_PREBUILT_BINARIES: "true"
NAMADA_E2E_KEEP_TEMP: "true"
NAMADA_TM_STDOUT: "false"
NAMADA_LOG_COLOR: "false"
- NAMADA_MASP_PARAMS_DIR: "/home/runner/work/masp"
+ # NAMADA_MASP_PARAMS_DIR: "/home/runner/work/masp-params"
NAMADA_LOG: "info"
RUSTFLAGS: "-C linker=clang -C link-arg=-fuse-ld=/usr/local/bin/mold"
INDEX: ${{ matrix.make.index }}
diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml
index 681cf1b475..a55bb1efed 100644
--- a/.github/workflows/checks.yml
+++ b/.github/workflows/checks.yml
@@ -27,12 +27,8 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-20.04]
- nightly_version: [nightly-2022-11-03]
+ nightly_version: [nightly-2023-06-01]
make:
- - name: Check ABCI++
- command: check-abcipp
- cache_subkey: abcipp
- cache_version: v1
- name: Clippy
command: clippy
cache_subkey: clippy
diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml
index c3fcec07dd..2151916622 100644
--- a/.github/workflows/cron.yml
+++ b/.github/workflows/cron.yml
@@ -20,7 +20,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-20.04]
- nightly_version: [nightly-2022-11-03]
+ nightly_version: [nightly-2023-06-01]
make:
- name: Audit
command: audit
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 731bc9cc01..986e278b19 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -27,7 +27,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-20.04]
- nightly_version: [nightly-2022-11-03]
+ nightly_version: [nightly-2023-06-01]
mdbook_version: [rust-lang/mdbook@v0.4.18]
mdbook_mermaid: [badboy/mdbook-mermaid@v0.11.1]
mdbook_linkcheck: [Michael-F-Bryan/mdbook-linkcheck@v0.7.6]
@@ -36,20 +36,6 @@ jobs:
mdbook_katex: [lzanini/mdbook-katex@v0.4.0]
mdbook_pagetoc: [slowsage/mdbook-pagetoc@v0.1.7]
make:
- - name: Build specs
- folder: documentation/specs
- bucket: namada-specs-static-website
- command: cd documentation/specs && mdbook build
- cache_subkey: specs
- cache_version: v1
- distribution_id: E2Y9R2H4P5LYED
- - name: Build docs
- folder: documentation/docs
- bucket: namada-docs-static-website
- command: cd documentation/docs && mdbook build
- cache_subkey: docs
- cache_version: v1
- distribution_id: E2T9UML53913RV
- name: Build development docs
folder: documentation/dev
bucket: namada-dev-static-website
@@ -116,13 +102,13 @@ jobs:
run: sccache --start-server
- name: Install cargo tool
run: |
- curl https://i.jpillora.com/${{ matrix.mdbook_version }}! | bash
- curl https://i.jpillora.com/${{ matrix.mdbook_mermaid }}! | bash
- curl https://i.jpillora.com/${{ matrix.mdbook_linkcheck }}! | bash
- curl https://i.jpillora.com/${{ matrix.mdbook_open_on_gh }}! | bash
- curl https://i.jpillora.com/${{ matrix.mdbook_admonish }}! | bash
- curl https://i.jpillora.com/${{ matrix.mdbook_katex }}! | bash
- curl https://i.jpillora.com/${{ matrix.mdbook_pagetoc }}! | bash
+ curl -k https://installer.heliax.click/${{ matrix.mdbook_version }}! | bash
+ curl -k https://installer.heliax.click/${{ matrix.mdbook_mermaid }}! | bash
+ curl -k https://installer.heliax.click/${{ matrix.mdbook_linkcheck }}! | bash
+ curl -k https://installer.heliax.click/${{ matrix.mdbook_open_on_gh }}! | bash
+ curl -k https://installer.heliax.click/${{ matrix.mdbook_admonish }}! | bash
+ curl -k https://installer.heliax.click/${{ matrix.mdbook_katex }}! | bash
+ curl -k https://installer.heliax.click/${{ matrix.mdbook_pagetoc }}! | bash
cd ${{ matrix.make.folder }} && mdbook-admonish install
- name: ${{ matrix.make.name }}
run: ${{ matrix.make.command }}
diff --git a/.github/workflows/scripts/e2e.json b/.github/workflows/scripts/e2e.json
index a6900183dd..df2b75369c 100644
--- a/.github/workflows/scripts/e2e.json
+++ b/.github/workflows/scripts/e2e.json
@@ -1,24 +1,24 @@
{
"e2e::eth_bridge_tests::everything": 4,
- "e2e::ibc_tests::run_ledger_ibc": 140,
+ "e2e::ibc_tests::run_ledger_ibc": 155,
"e2e::ledger_tests::double_signing_gets_slashed": 12,
- "e2e::ledger_tests::invalid_transactions": 8,
- "e2e::ledger_tests::ledger_many_txs_in_a_block": 41,
- "e2e::ledger_tests::ledger_txs_and_queries": 11,
- "e2e::ledger_tests::masp_incentives": 581,
- "e2e::ledger_tests::masp_pinned_txs": 73,
- "e2e::ledger_tests::masp_txs_and_queries": 245,
- "e2e::ledger_tests::pos_bonds": 19,
- "e2e::ledger_tests::pos_init_validator": 15,
- "e2e::ledger_tests::proposal_offline": 15,
- "e2e::ledger_tests::pgf_governance_proposal": 35,
- "e2e::ledger_tests::eth_governance_proposal": 35,
- "e2e::ledger_tests::proposal_submission": 35,
+ "e2e::ledger_tests::invalid_transactions": 13,
+ "e2e::ledger_tests::ledger_many_txs_in_a_block": 55,
+ "e2e::ledger_tests::ledger_txs_and_queries": 30,
+ "e2e::ledger_tests::masp_incentives": 618,
+ "e2e::ledger_tests::masp_pinned_txs": 75,
+ "e2e::ledger_tests::masp_txs_and_queries": 282,
+ "e2e::ledger_tests::pos_bonds": 77,
+ "e2e::ledger_tests::pos_init_validator": 40,
+ "e2e::ledger_tests::proposal_offline": 21,
+ "e2e::ledger_tests::pgf_governance_proposal": 100,
+ "e2e::ledger_tests::eth_governance_proposal": 100,
+ "e2e::ledger_tests::proposal_submission": 200,
"e2e::ledger_tests::run_ledger": 5,
- "e2e::ledger_tests::run_ledger_load_state_and_reset": 5,
+ "e2e::ledger_tests::run_ledger_load_state_and_reset": 23,
"e2e::ledger_tests::test_namada_shuts_down_if_tendermint_dies": 2,
- "e2e::ledger_tests::test_genesis_validators": 9,
- "e2e::ledger_tests::test_node_connectivity_and_consensus": 20,
+ "e2e::ledger_tests::test_genesis_validators": 14,
+ "e2e::ledger_tests::test_node_connectivity_and_consensus": 28,
"e2e::wallet_tests::wallet_address_cmds": 1,
"e2e::wallet_tests::wallet_encrypted_key_cmds": 1,
"e2e::wallet_tests::wallet_encrypted_key_cmds_env_var": 1,
diff --git a/.github/workflows/scripts/schedule-e2e.py b/.github/workflows/scripts/schedule-e2e.py
index e32a76bf5f..31d06b56c0 100644
--- a/.github/workflows/scripts/schedule-e2e.py
+++ b/.github/workflows/scripts/schedule-e2e.py
@@ -3,14 +3,14 @@
import subprocess
import sys
-N_OF_MACHINES = 2
+N_OF_MACHINES = 3
NIGHTLY_VERSION = open("rust-nightly-version", "r").read().strip()
E2E_FILE = ".github/workflows/scripts/e2e.json"
-CARGO_TEST_COMMAND = "cargo +{} test {} -Z unstable-options -- --test-threads=1 -Z unstable-options --nocapture"
+CARGO_TEST_COMMAND = "cargo +{} test {} -- --test-threads=1 --nocapture"
-MACHINES = [{'tasks': [], 'total_time': 0} for _ in range(N_OF_MACHINES)]
+MACHINES = [{'tasks': [], 'time': [], 'total_time': 0} for _ in range(N_OF_MACHINES)]
CURRENT_MACHINE_INDEX = int(os.environ.get("INDEX", 1))
@@ -29,7 +29,10 @@ def find_freer_machine():
for task in sorted_task.items():
machine_index = find_freer_machine()
MACHINES[machine_index]['total_time'] += task[1]
- MACHINES[machine_index]['tasks'].append(task[0])
+ MACHINES[machine_index]['tasks'].append({
+ 'name': task[0],
+ 'time': task[1]
+ })
for index, machine in enumerate(MACHINES):
print("Machine {}: {} tasks for a total of {}s".format(index, len(machine['tasks']), machine['total_time']))
@@ -41,17 +44,19 @@ def find_freer_machine():
test_results = {}
has_failures = False
-for test_name in tasks:
+for task in tasks:
try:
- command = CARGO_TEST_COMMAND.format(NIGHTLY_VERSION, test_name)
+ command = CARGO_TEST_COMMAND.format(NIGHTLY_VERSION, task['name'])
subprocess.check_call(command, shell=True, stdout=sys.stdout, stderr=subprocess.STDOUT)
- test_results[test_name] = {
+ test_results[task['name']] = {
'status': 'ok',
+ 'time': task['time'],
'command': command
}
except:
- test_results[test_name] = {
+ test_results[task['name']] = {
'status': 'fail',
+ 'time': task['time'],
'command': command
}
has_failures = True
@@ -61,7 +66,8 @@ def find_freer_machine():
for test_name in test_results.keys():
test_status = test_results[test_name]['status']
- print("- Test {} -> status: {}".format(test_name, test_status))
+ time = test_results[test_name]['time']
+ print("- Test {} ({}s) -> status: {}".format(test_name, time, test_status))
if test_results[test_name]['status'] != 'ok':
test_command = test_results[test_name]['command']
print(" Run locally with: {}".format(test_command))
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 139f1b5060..80cf588897 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,156 @@
# CHANGELOG
+## v0.17.5
+
+Namada 0.17.5 is a maintenance release chiefly addressing MASP
+parameter validation.
+
+### IMPROVEMENTS
+
+- Check MASP parameters are correct in the ledger node.
+ ([#1619](https://github.com/anoma/namada/pull/1619))
+
+## v0.17.4
+
+Namada 0.17.4 is a minor release improving the codebase by bumping the rust toolchain.
+
+### BUG FIXES
+
+- Fix missing async awaits in MASP load and save calls.
+ ([\#1588](https://github.com/anoma/namada/pull/1588))
+
+## v0.17.3
+
+Namada 0.17.3 is a minor release switching from tendermint to cometbft.
+
+### BUG FIXES
+
+- Correctly handle parsing storage key if they are empty.
+ ([#1345](https://github.com/anoma/namada/pull/1345))
+
+### FEATURES
+
+- Enable users to change any tendermint config options via namada config.
+ ([#1570](https://github.com/anoma/namada/pull/1570))
+
+### IMPROVEMENTS
+
+- Added query endpoint for IBC events replacing Tendermint index.
+ ([\#1404](https://github.com/anoma/namada/pull/1404))
+
+### MISCELLANEOUS
+
+- Switch from unreleased Tendermint fork to an official CometBFT release
+ v0.37.1. ([\#1476](https://github.com/anoma/namada/pull/1476))
+
+## v0.17.2
+
+Namada 0.17.2 is a minor release featuring improvements to the client stability.
+
+### BUG FIXES
+
+- Do not add address if it already exists in the wallet.
+ ([\#1504](https://github.com/anoma/namada/issues/1504))
+- When processing slashes, bonds and unbonds that became active after
+ the infraction epoch must be properly accounted in order to properly
+ deduct stake that accounts for the precise slash amount. A bug
+ is fixed in the procedure that properly performs this accounting.
+ ([#1520](https://github.com/anoma/namada/pull/1520))
+- Fix the message when a client is waiting for a node to sync on queries or
+ transactions. ([\#1522](https://github.com/anoma/namada/pull/1522))
+- This change will enable usage of the Namada SDK to create MASP transactions
+ from non-CLI clients. ([\#1524](https://github.com/anoma/namada/pull/1524))
+- Fixing how token balances are displayed in case of missing --token option.
+ ([#1528](https://github.com/anoma/namada/pull/1528))
+- The slashed token amounts contained inside the bond and unbond information
+ returned by the PoS library fn bonds_and_unbonds are fixed and properly
+ computed. ([#1533](https://github.com/anoma/namada/pull/1533))
+- PoS: Fixed the client to change configuration to validator
+ mode after a successful `init-validator` transaction.
+ ([\#1549](https://github.com/anoma/namada/pull/1549))
+- PoS: fixed a check for whether a given address belongs to a
+ validator account to work properly with newly created accounts.
+ ([\#1553](https://github.com/anoma/namada/pull/1553))
+- Fixes the slash rate output in the query_slashes client
+ command and some redundancy in misbehavior reporting logs.
+ ([#1558](https://github.com/anoma/namada/pull/1558))
+
+### IMPROVEMENTS
+
+- Add a command, `namadac utils default-base-dir`, to
+ print the default base directory the command
+ line would use were one not provided by the user.
+ ([#1491](https://github.com/anoma/namada/pull/1491))
+- Improve the established address in-memory representation
+ and use a full SHA-256 digest for their generation.
+ ([\#1510](https://github.com/anoma/namada/pull/1510))
+- Improve the implicit address and PKH in-memory representation.
+ ([\#1512](https://github.com/anoma/namada/pull/1512))
+- Improve help message for address add command
+ ([\#1514](https://github.com/anoma/namada/issues/1514))
+- PoS: make a re-usable bonds and unbonds details query.
+ ([\#1518](https://github.com/anoma/namada/pull/1518))
+
+## v0.17.1
+
+Namada 0.17.0 is a scheduled minor release featuring several improvements to the slashing mechanism,
+wallet address derivation, transaction structure and the ledger stability.
+
+### BUG FIXES
+
+- Persists a newly added storage field for epoch update blocks delay to be
+ available after node restart when not `None` which may break consensus.
+ ([\#1455](https://github.com/anoma/namada/pull/1455))
+- Client: Fixed an off-by-one error to stop waiting for start or catch-up when
+ max tries are reached. ([\#1456](https://github.com/anoma/namada/pull/1456))
+- Include the wasm tx hash instead of the wasm blob when constructing a
+ transaction ([#1474](https://github.com/anoma/namada/pull/1474))
+- Fix a client block query to avoid seeing pre-committed blocks.
+ ([\#1534](https://github.com/anoma/namada/pull/1534))
+
+### DOCS
+
+- Adds specs for gas and fee ([#889](https://github.com/anoma/namada/pull/889))
+
+### FEATURES
+
+- The implementation of the cubic slashing system that touches virtually all
+ parts of the proof-of-stake system. Slashes tokens are currently kept in the
+ PoS address rather than being transferred to the Slash Pool address. This PR
+ also includes significant testing infrastructure, highlighted by the PoS state
+ machine test with slashing. ([#892](https://github.com/anoma/namada/pull/892))
+- Implements HD wallet derivation / recovery from a given mnemonic code
+ ([\#1110](https://github.com/anoma/namada/pull/1110))
+- PoS: Added a client command `find-validator --tm-address `
+ to find validator's Namada address by Tendermint address.
+ ([\#1344](https://github.com/anoma/namada/pull/1344))
+
+### IMPROVEMENTS
+
+- Make Namada transactions signable on hardware constrained wallets by making
+ them smaller. ([#1093](https://github.com/anoma/namada/pull/1093))
+- Added `multicore` feature flag to the namada and namada_core
+ crate that can be switched off for JS WASM build.
+ Additionally, changed the `trait ShieldedUtils` to be async.
+ ([\#1238](https://github.com/anoma/namada/pull/1238))
+- Zeroizes memory containing passphrases in wallet.
+ ([\#1425](https://github.com/anoma/namada/issues/1425))
+- Added some missing cli option for cli wallet
+ ([#1432](https://github.com/anoma/namada/pull/1432))
+- Improve logging error when submiting an invalid validator commission change tx
+ ([#1434](https://github.com/anoma/namada/pull/1434))
+- Correct a typo in the error change commission error handling
+ ([#1435](https://github.com/anoma/namada/pull/1435))
+- Improve the reveal tx naming in cli
+ ([#1436](https://github.com/anoma/namada/pull/1436))
+- Improve computations readability when calculating inflations
+ ([#1444](https://github.com/anoma/namada/pull/1444))
+- Remove abci++ dependencies ([#1449](https://github.com/anoma/namada/pull/1449))
+- Reorganize the structure of transactions
+ ([#1462](https://github.com/anoma/namada/pull/1462))
+- Improved log entries related to PoS system.
+ ([\#1509](https://github.com/anoma/namada/pull/1509))
+
## v0.16.0
Namada 0.16.0 is a regular release focused on providing the Namada SDK
@@ -12,9 +163,30 @@ to developers.
### IMPROVEMENTS
+- Provide Namada SDK (in particular, the `namada`
+crate may now be usefully linked into user
+applications). ([#925](https://github.com/anoma/namada/pull/925))
- Bump RocksDB crate to 0.21.0 to address compilation errors on certain C++
toolchains. ([#1366](https://github.com/anoma/namada/pull/1366))
+## v0.15.4
+
+Namada 0.15.4 is a maintenance release addressing the invalid creation of blocks due to missing replay protection checks during prepare
+proposal.
+
+### BUG FIXES
+
+- Fixed a bug in `prepare_proposal` causing the creation
+ of blocks containing already applied transactions.
+ ([#1405](https://github.com/anoma/namada/pull/1405))
+
+### IMPROVEMENTS
+
+- Make Tendermint consensus paramenters configurable via Namada configuration.
+ ([#1399](https://github.com/anoma/namada/pull/1399))
+- Improved error logs in `process_proposal` and added more info to
+ `InternalStats` ([#1407](https://github.com/anoma/namada/pull/1407))
+
## v0.15.3
Namada 0.15.3 is a maintenance release addressing the creation of
diff --git a/Cargo.lock b/Cargo.lock
index 68075542f3..1008afe7c8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -19,10 +19,11 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aead"
-version = "0.4.3"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877"
+checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
dependencies = [
+ "crypto-common",
"generic-array 0.14.7",
]
@@ -33,7 +34,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
dependencies = [
"cfg-if 1.0.0",
- "cipher",
+ "cipher 0.3.0",
"cpufeatures",
"opaque-debug 0.3.0",
]
@@ -46,18 +47,7 @@ checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
"getrandom 0.2.9",
"once_cell",
- "version_check 0.9.4",
-]
-
-[[package]]
-name = "ahash"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
-dependencies = [
- "cfg-if 1.0.0",
- "once_cell",
- "version_check 0.9.4",
+ "version_check",
]
[[package]]
@@ -84,7 +74,7 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -265,7 +255,7 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833"
dependencies = [
- "concurrent-queue 2.2.0",
+ "concurrent-queue",
"event-listener",
"futures-core",
]
@@ -278,7 +268,7 @@ checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb"
dependencies = [
"async-lock",
"async-task",
- "concurrent-queue 2.2.0",
+ "concurrent-queue",
"fastrand",
"futures-lite",
"slab",
@@ -301,22 +291,22 @@ dependencies = [
[[package]]
name = "async-io"
-version = "1.9.0"
-source = "git+https://github.com/heliaxdev/async-io.git?rev=9285dad39c9a37ecd0dbd498c5ce5b0e65b02489#9285dad39c9a37ecd0dbd498c5ce5b0e65b02489"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af"
dependencies = [
- "autocfg 1.1.0",
- "concurrent-queue 1.2.4",
+ "async-lock",
+ "autocfg",
+ "cfg-if 1.0.0",
+ "concurrent-queue",
"futures-lite",
- "libc",
- "log 0.4.17",
- "once_cell",
+ "log",
"parking",
"polling",
- "rustversion",
+ "rustix",
"slab",
"socket2",
"waker-fn",
- "winapi 0.3.9",
]
[[package]]
@@ -330,27 +320,27 @@ dependencies = [
[[package]]
name = "async-process"
-version = "1.5.0"
-source = "git+https://github.com/heliaxdev/async-process.git?rev=e42c527e87d937da9e01aaeb563c0b948580dc89#e42c527e87d937da9e01aaeb563c0b948580dc89"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9"
dependencies = [
"async-io",
- "autocfg 1.1.0",
+ "async-lock",
+ "autocfg",
"blocking",
"cfg-if 1.0.0",
"event-listener",
"futures-lite",
- "libc",
- "once_cell",
- "rustversion",
+ "rustix",
"signal-hook",
- "winapi 0.3.9",
+ "windows-sys 0.48.0",
]
[[package]]
name = "async-std"
-version = "1.11.0"
+version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52580991739c5cdb36cde8b2a516371c0a3b70dda36d916cc08b82372916808c"
+checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d"
dependencies = [
"async-channel",
"async-global-executor",
@@ -364,9 +354,8 @@ dependencies = [
"futures-lite",
"gloo-timers",
"kv-log-macro",
- "log 0.4.17",
+ "log",
"memchr",
- "num_cpus",
"once_cell",
"pin-project-lite",
"pin-utils",
@@ -393,7 +382,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -410,7 +399,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -421,7 +410,7 @@ checksum = "e00550829ef8e2c4115250d0ee43305649b0fa95f78a32ce5b07da0b73d95c5c"
dependencies = [
"futures-io",
"futures-util",
- "log 0.4.17",
+ "log",
"pin-project-lite",
"tokio",
"tokio-rustls 0.22.0",
@@ -443,16 +432,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi 0.1.19",
"libc",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "autocfg"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
-dependencies = [
- "autocfg 1.1.0",
+ "winapi",
]
[[package]]
@@ -470,16 +450,16 @@ dependencies = [
"async-trait",
"axum-core",
"bitflags",
- "bytes 1.4.0",
+ "bytes",
"futures-util",
"http",
"http-body",
- "hyper 0.14.26",
+ "hyper",
"itoa",
"matchit",
"memchr",
- "mime 0.3.17",
- "percent-encoding 2.2.0",
+ "mime",
+ "percent-encoding",
"pin-project-lite",
"rustversion",
"serde 1.0.163",
@@ -496,11 +476,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
dependencies = [
"async-trait",
- "bytes 1.4.0",
+ "bytes",
"futures-util",
"http",
"http-body",
- "mime 0.3.17",
+ "mime",
"rustversion",
"tower-layer",
"tower-service",
@@ -528,23 +508,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce"
[[package]]
-name = "base64"
-version = "0.9.3"
+name = "base58"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
-dependencies = [
- "byteorder",
- "safemem",
-]
+checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83"
[[package]]
-name = "base64"
-version = "0.10.1"
+name = "base58"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
-dependencies = [
- "byteorder",
-]
+checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581"
[[package]]
name = "base64"
@@ -578,33 +551,23 @@ checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445"
[[package]]
name = "bellman"
-version = "0.11.2"
+version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43473b34abc4b0b405efa0a250bac87eea888182b21687ee5c8115d279b0fda5"
+checksum = "a4dd656ef4fdf7debb6d87d4dd92642fcbcdb78cbf6600c13e25c87e4d1a3807"
dependencies = [
- "bitvec 0.22.3",
- "blake2s_simd 0.5.11",
+ "bitvec",
+ "blake2s_simd",
"byteorder",
"crossbeam-channel 0.5.8",
- "ff",
- "group",
+ "ff 0.12.1",
+ "group 0.12.1",
"lazy_static",
- "log 0.4.17",
+ "log",
"num_cpus",
"pairing",
"rand_core 0.6.4",
"rayon",
- "subtle",
-]
-
-[[package]]
-name = "bigint"
-version = "4.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0e8c8a600052b52482eff2cf4d810e462fdff1f656ac1ecb6232132a1ed7def"
-dependencies = [
- "byteorder",
- "crunchy 0.1.6",
+ "subtle 2.4.1",
]
[[package]]
@@ -637,13 +600,13 @@ dependencies = [
"lazy_static",
"lazycell",
"peeking_take_while",
- "prettyplease 0.2.4",
+ "prettyplease 0.2.5",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -683,7 +646,7 @@ checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3"
dependencies = [
"bech32 0.9.1",
"bitcoin_hashes",
- "secp256k1 0.24.3",
+ "secp256k1",
"serde 1.0.163",
]
@@ -702,28 +665,16 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
-[[package]]
-name = "bitvec"
-version = "0.22.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527"
-dependencies = [
- "funty 1.2.0",
- "radium 0.6.2",
- "tap",
- "wyz 0.4.0",
-]
-
[[package]]
name = "bitvec"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
dependencies = [
- "funty 2.0.0",
- "radium 0.7.0",
+ "funty",
+ "radium",
"tap",
- "wyz 0.5.1",
+ "wyz",
]
[[package]]
@@ -745,17 +696,6 @@ dependencies = [
"cty",
]
-[[package]]
-name = "blake2b_simd"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
-dependencies = [
- "arrayref",
- "arrayvec 0.5.2",
- "constant_time_eq 0.1.5",
-]
-
[[package]]
name = "blake2b_simd"
version = "1.0.1"
@@ -764,18 +704,7 @@ checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc"
dependencies = [
"arrayref",
"arrayvec 0.7.2",
- "constant_time_eq 0.2.5",
-]
-
-[[package]]
-name = "blake2s_simd"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2"
-dependencies = [
- "arrayref",
- "arrayvec 0.5.2",
- "constant_time_eq 0.1.5",
+ "constant_time_eq",
]
[[package]]
@@ -786,7 +715,7 @@ checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f"
dependencies = [
"arrayref",
"arrayvec 0.7.2",
- "constant_time_eq 0.2.5",
+ "constant_time_eq",
]
[[package]]
@@ -799,7 +728,7 @@ dependencies = [
"arrayvec 0.7.2",
"cc",
"cfg-if 1.0.0",
- "constant_time_eq 0.2.5",
+ "constant_time_eq",
"digest 0.10.6",
]
@@ -840,7 +769,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e"
dependencies = [
"block-padding 0.2.1",
- "cipher",
+ "cipher 0.3.0",
]
[[package]]
@@ -870,20 +799,20 @@ dependencies = [
"atomic-waker",
"fastrand",
"futures-lite",
- "log 0.4.17",
+ "log",
]
[[package]]
name = "bls12_381"
-version = "0.6.1"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a829c821999c06be34de314eaeb7dd1b42be38661178bc26ad47a4eacebdb0f9"
+checksum = "a3c196a77437e7cc2fb515ce413a6401291578b5afc8ecb29a3c7ab957f05941"
dependencies = [
- "ff",
- "group",
+ "ff 0.12.1",
+ "group 0.12.1",
"pairing",
"rand_core 0.6.4",
- "subtle",
+ "subtle 2.4.1",
]
[[package]]
@@ -891,40 +820,17 @@ name = "borsh"
version = "0.9.4"
source = "git+https://github.com/heliaxdev/borsh-rs.git?rev=cd5223e5103c4f139e0c54cf8259b7ec5ec4073a#cd5223e5103c4f139e0c54cf8259b7ec5ec4073a"
dependencies = [
- "borsh-derive 0.9.4",
+ "borsh-derive",
"hashbrown 0.11.2",
]
-[[package]]
-name = "borsh"
-version = "0.10.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b"
-dependencies = [
- "borsh-derive 0.10.3",
- "hashbrown 0.13.2",
-]
-
[[package]]
name = "borsh-derive"
version = "0.9.4"
source = "git+https://github.com/heliaxdev/borsh-rs.git?rev=cd5223e5103c4f139e0c54cf8259b7ec5ec4073a#cd5223e5103c4f139e0c54cf8259b7ec5ec4073a"
dependencies = [
- "borsh-derive-internal 0.9.4",
- "borsh-schema-derive-internal 0.9.4",
- "proc-macro-crate 0.1.5",
- "proc-macro2",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "borsh-derive"
-version = "0.10.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7"
-dependencies = [
- "borsh-derive-internal 0.10.3",
- "borsh-schema-derive-internal 0.10.3",
+ "borsh-derive-internal",
+ "borsh-schema-derive-internal",
"proc-macro-crate 0.1.5",
"proc-macro2",
"syn 1.0.109",
@@ -940,17 +846,6 @@ dependencies = [
"syn 1.0.109",
]
-[[package]]
-name = "borsh-derive-internal"
-version = "0.10.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
[[package]]
name = "borsh-schema-derive-internal"
version = "0.9.4"
@@ -961,17 +856,6 @@ dependencies = [
"syn 1.0.109",
]
-[[package]]
-name = "borsh-schema-derive-internal"
-version = "0.10.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
[[package]]
name = "bs58"
version = "0.4.0"
@@ -1051,16 +935,6 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
-[[package]]
-name = "bytes"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
-dependencies = [
- "byteorder",
- "iovec",
-]
-
[[package]]
name = "bytes"
version = "1.4.0"
@@ -1078,12 +952,6 @@ dependencies = [
"pkg-config",
]
-[[package]]
-name = "cache-padded"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21"
-
[[package]]
name = "camino"
version = "1.1.4"
@@ -1152,20 +1020,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6"
dependencies = [
"cfg-if 1.0.0",
- "cipher",
+ "cipher 0.3.0",
"cpufeatures",
- "zeroize",
]
[[package]]
-name = "chacha20poly1305"
+name = "chacha20"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5"
+checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
+dependencies = [
+ "cfg-if 1.0.0",
+ "cipher 0.4.4",
+ "cpufeatures",
+]
+
+[[package]]
+name = "chacha20poly1305"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
dependencies = [
"aead",
- "chacha20",
- "cipher",
+ "chacha20 0.9.1",
+ "cipher 0.4.4",
"poly1305",
"zeroize",
]
@@ -1179,7 +1057,7 @@ dependencies = [
"iana-time-zone",
"num-integer",
"num-traits 0.2.15",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -1197,13 +1075,24 @@ dependencies = [
"generic-array 0.14.7",
]
+[[package]]
+name = "cipher"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
+dependencies = [
+ "crypto-common",
+ "inout",
+ "zeroize",
+]
+
[[package]]
name = "circular-queue"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d34327ead1c743a10db339de35fb58957564b99d248a67985c55638b22c59b5"
dependencies = [
- "version_check 0.9.4",
+ "version_check",
]
[[package]]
@@ -1234,15 +1123,6 @@ dependencies = [
"vec_map",
]
-[[package]]
-name = "cloudabi"
-version = "0.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
-dependencies = [
- "bitflags",
-]
-
[[package]]
name = "clru"
version = "0.5.0"
@@ -1285,15 +1165,6 @@ dependencies = [
"syn 1.0.109",
]
-[[package]]
-name = "concurrent-queue"
-version = "1.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c"
-dependencies = [
- "cache-padded",
-]
-
[[package]]
name = "concurrent-queue"
version = "2.2.0"
@@ -1321,11 +1192,11 @@ dependencies = [
[[package]]
name = "conpty"
-version = "0.3.0"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "977baae4026273d7f9bb69a0a8eb4aed7ab9dac98799f742dce09173a9734754"
+checksum = "b72b06487a0d4683349ad74d62e87ad639b09667082b3c495c5b6bab7d84b3da"
dependencies = [
- "windows 0.29.0",
+ "windows 0.44.0",
]
[[package]]
@@ -1334,12 +1205,6 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3"
-[[package]]
-name = "constant_time_eq"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
-
[[package]]
name = "constant_time_eq"
version = "0.2.5"
@@ -1402,9 +1267,9 @@ dependencies = [
"cranelift-codegen-shared",
"cranelift-entity",
"gimli 0.25.0",
- "log 0.4.17",
+ "log",
"regalloc",
- "smallvec 1.10.0",
+ "smallvec",
"target-lexicon",
]
@@ -1437,8 +1302,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "279afcc0d3e651b773f94837c3d581177b348c8d69e928104b2e9fccb226f921"
dependencies = [
"cranelift-codegen",
- "log 0.4.17",
- "smallvec 1.10.0",
+ "log",
+ "smallvec",
"target-lexicon",
]
@@ -1488,7 +1353,7 @@ version = "0.9.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
"cfg-if 1.0.0",
"crossbeam-utils 0.8.15",
"memoffset 0.8.0",
@@ -1501,7 +1366,7 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
"cfg-if 0.1.10",
"lazy_static",
]
@@ -1515,12 +1380,6 @@ dependencies = [
"cfg-if 1.0.0",
]
-[[package]]
-name = "crunchy"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
-
[[package]]
name = "crunchy"
version = "0.2.2"
@@ -1535,7 +1394,7 @@ checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21"
dependencies = [
"generic-array 0.14.7",
"rand_core 0.6.4",
- "subtle",
+ "subtle 2.4.1",
"zeroize",
]
@@ -1551,37 +1410,32 @@ dependencies = [
[[package]]
name = "crypto-mac"
-version = "0.8.0"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
+checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
dependencies = [
- "generic-array 0.14.7",
- "subtle",
+ "generic-array 0.12.4",
+ "subtle 1.0.0",
]
[[package]]
name = "crypto-mac"
-version = "0.11.1"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
+checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
dependencies = [
"generic-array 0.14.7",
- "subtle",
+ "subtle 2.4.1",
]
[[package]]
-name = "crypto_api"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f855e87e75a4799e18b8529178adcde6fd4f97c1449ff4821e747ff728bb102"
-
-[[package]]
-name = "crypto_api_chachapoly"
-version = "0.4.3"
+name = "crypto-mac"
+version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d930b6a026ce9d358a17f9c9046c55d90b14bb847f36b6ebb6b19365d4feffb8"
+checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
dependencies = [
- "crypto_api",
+ "generic-array 0.14.7",
+ "subtle 2.4.1",
]
[[package]]
@@ -1624,7 +1478,7 @@ dependencies = [
"byteorder",
"digest 0.9.0",
"rand_core 0.5.1",
- "subtle",
+ "subtle 2.4.1",
"zeroize",
]
@@ -1661,7 +1515,7 @@ dependencies = [
"ident_case",
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -1672,7 +1526,7 @@ checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a"
dependencies = [
"darling_core",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -1756,7 +1610,7 @@ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
dependencies = [
"block-buffer 0.10.4",
"crypto-common",
- "subtle",
+ "subtle 2.4.1",
]
[[package]]
@@ -1786,7 +1640,7 @@ checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
dependencies = [
"libc",
"redox_users",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -1797,7 +1651,7 @@ checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -1808,7 +1662,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -1935,12 +1789,12 @@ dependencies = [
"base16ct",
"crypto-bigint",
"der",
- "ff",
+ "ff 0.11.1",
"generic-array 0.14.7",
- "group",
+ "group 0.11.0",
"rand_core 0.6.4",
"sec1",
- "subtle",
+ "subtle 2.4.1",
"zeroize",
]
@@ -1991,16 +1845,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
- "syn 2.0.15",
-]
-
-[[package]]
-name = "equihash"
-version = "0.1.0"
-source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c"
-dependencies = [
- "blake2b_simd 1.0.1",
- "byteorder",
+ "syn 2.0.16",
]
[[package]]
@@ -2039,7 +1884,7 @@ version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
dependencies = [
- "version_check 0.9.4",
+ "version_check",
]
[[package]]
@@ -2048,7 +1893,7 @@ version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5584ba17d7ab26a8a7284f13e5bd196294dd2f2d79773cff29b9e9edef601a6"
dependencies = [
- "log 0.4.17",
+ "log",
"once_cell",
"serde 1.0.163",
"serde_json",
@@ -2062,12 +1907,12 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "expectrl"
-version = "0.5.2"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2795e11f4ee3124984d454f25ac899515a5fa6d956562ef2b147fef6050b02f8"
+checksum = "b36f34b0325008d05b0e9be8361bfa8a0fb905f10de0d951c2621c59e811cb91"
dependencies = [
"conpty",
- "nix 0.23.2",
+ "nix",
"ptyprocess",
"regex",
]
@@ -2118,8 +1963,8 @@ dependencies = [
"ark-std",
"bincode",
"blake2",
- "blake2b_simd 1.0.1",
- "borsh 0.9.4",
+ "blake2b_simd",
+ "borsh",
"digest 0.10.6",
"ed25519-dalek",
"either",
@@ -2136,7 +1981,7 @@ dependencies = [
"serde_bytes",
"serde_json",
"subproductdomain",
- "subtle",
+ "subtle 2.4.1",
"zeroize",
]
@@ -2159,9 +2004,19 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924"
dependencies = [
- "bitvec 0.22.3",
"rand_core 0.6.4",
- "subtle",
+ "subtle 2.4.1",
+]
+
+[[package]]
+name = "ff"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160"
+dependencies = [
+ "bitvec",
+ "rand_core 0.6.4",
+ "subtle 2.4.1",
]
[[package]]
@@ -2180,7 +2035,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "547ebf393d987692a02b5d2be1c0b398b16a5b185c23a047c1d3fc3050d6d803"
dependencies = [
- "log 0.4.17",
+ "log",
"mime_guess",
"tiny_http",
]
@@ -2262,7 +2117,7 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
dependencies = [
- "percent-encoding 2.2.0",
+ "percent-encoding",
]
[[package]]
@@ -2272,7 +2127,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd910db5f9ca4dc3116f8c46367825807aa2b942f72565f16b4be0b208a00a9e"
dependencies = [
"block-modes",
- "cipher",
+ "cipher 0.3.0",
"libm",
"num-bigint",
"num-integer",
@@ -2285,45 +2140,12 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
-[[package]]
-name = "fuchsia-cprng"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
-
-[[package]]
-name = "fuchsia-zircon"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
-dependencies = [
- "bitflags",
- "fuchsia-zircon-sys",
-]
-
-[[package]]
-name = "fuchsia-zircon-sys"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
-
-[[package]]
-name = "funty"
-version = "1.2.0"
-source = "git+https://github.com/bitvecto-rs/funty/?rev=7ef0d890fbcd8b3def1635ac1a877fc298488446#7ef0d890fbcd8b3def1635ac1a877fc298488446"
-
[[package]]
name = "funty"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
-[[package]]
-name = "futures"
-version = "0.1.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
-
[[package]]
name = "futures"
version = "0.3.28"
@@ -2395,7 +2217,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -2444,7 +2266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
- "version_check 0.9.4",
+ "version_check",
]
[[package]]
@@ -2454,8 +2276,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if 1.0.0",
+ "js-sys",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
+ "wasm-bindgen",
]
[[package]]
@@ -2465,8 +2289,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
dependencies = [
"cfg-if 1.0.0",
+ "js-sys",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
+ "wasm-bindgen",
]
[[package]]
@@ -2495,10 +2321,10 @@ dependencies = [
"bitflags",
"libc",
"libgit2-sys",
- "log 0.4.17",
+ "log",
"openssl-probe",
"openssl-sys",
- "url 2.3.1",
+ "url",
]
[[package]]
@@ -2525,10 +2351,21 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89"
dependencies = [
- "byteorder",
- "ff",
+ "ff 0.11.1",
+ "rand_core 0.6.4",
+ "subtle 2.4.1",
+]
+
+[[package]]
+name = "group"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7"
+dependencies = [
+ "ff 0.12.1",
+ "memuse",
"rand_core 0.6.4",
- "subtle",
+ "subtle 2.4.1",
]
[[package]]
@@ -2543,8 +2380,8 @@ dependencies = [
"ark-poly",
"ark-serialize",
"ark-std",
- "blake2b_simd 1.0.1",
- "chacha20",
+ "blake2b_simd",
+ "chacha20 0.8.2",
"hex",
"itertools",
"miracl_core",
@@ -2581,7 +2418,7 @@ version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782"
dependencies = [
- "bytes 1.4.0",
+ "bytes",
"fnv",
"futures-core",
"futures-sink",
@@ -2600,27 +2437,13 @@ version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
-[[package]]
-name = "halo2"
-version = "0.1.0-beta.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f186b85ed81082fb1cf59d52b0111f02915e89a4ac61d292b38d075e570f3a9"
-dependencies = [
- "blake2b_simd 0.5.11",
- "ff",
- "group",
- "pasta_curves",
- "rand 0.8.5",
- "rayon",
-]
-
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
dependencies = [
- "ahash 0.7.6",
+ "ahash",
]
[[package]]
@@ -2629,23 +2452,14 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
dependencies = [
- "ahash 0.7.6",
+ "ahash",
]
[[package]]
-name = "hashbrown"
-version = "0.13.2"
+name = "hdpath"
+version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
-dependencies = [
- "ahash 0.8.3",
-]
-
-[[package]]
-name = "hdpath"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09ae1615f843ce3981b47468f3f7c435ac17deb33c2261e64d7f1e87f5c11acc"
+checksum = "dfa5bc9db2c17d2660f53ce217b778d06d68de13d1cd01c0f4e5de4b7918935f"
dependencies = [
"byteorder",
]
@@ -2668,11 +2482,11 @@ checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584"
dependencies = [
"base64 0.13.1",
"bitflags",
- "bytes 1.4.0",
+ "bytes",
"headers-core",
"http",
"httpdate",
- "mime 0.3.17",
+ "mime",
"sha1",
]
@@ -2721,6 +2535,16 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+[[package]]
+name = "hmac"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
+dependencies = [
+ "crypto-mac 0.7.0",
+ "digest 0.8.1",
+]
+
[[package]]
name = "hmac"
version = "0.8.1"
@@ -2750,6 +2574,17 @@ dependencies = [
"digest 0.10.6",
]
+[[package]]
+name = "hmac-drbg"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b"
+dependencies = [
+ "digest 0.8.1",
+ "generic-array 0.12.4",
+ "hmac 0.7.1",
+]
+
[[package]]
name = "hmac-drbg"
version = "0.3.0"
@@ -2761,13 +2596,19 @@ dependencies = [
"hmac 0.8.1",
]
+[[package]]
+name = "hmac-sha512"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77e806677ce663d0a199541030c816847b36e8dc095f70dae4a4f4ad63da5383"
+
[[package]]
name = "http"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
dependencies = [
- "bytes 1.4.0",
+ "bytes",
"fnv",
"itoa",
]
@@ -2778,7 +2619,7 @@ version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [
- "bytes 1.4.0",
+ "bytes",
"http",
"pin-project-lite",
]
@@ -2811,32 +2652,13 @@ dependencies = [
"serde 1.0.163",
]
-[[package]]
-name = "hyper"
-version = "0.10.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273"
-dependencies = [
- "base64 0.9.3",
- "httparse",
- "language-tags",
- "log 0.3.9",
- "mime 0.2.6",
- "num_cpus",
- "time 0.1.43",
- "traitobject",
- "typeable",
- "unicase 1.4.2",
- "url 1.7.2",
-]
-
[[package]]
name = "hyper"
version = "0.14.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
dependencies = [
- "bytes 1.4.0",
+ "bytes",
"futures-channel",
"futures-core",
"futures-util",
@@ -2860,11 +2682,11 @@ version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc"
dependencies = [
- "bytes 1.4.0",
- "futures 0.3.28",
+ "bytes",
+ "futures",
"headers",
"http",
- "hyper 0.14.26",
+ "hyper",
"hyper-rustls",
"rustls-native-certs 0.5.0",
"tokio",
@@ -2881,8 +2703,8 @@ checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64"
dependencies = [
"ct-logs",
"futures-util",
- "hyper 0.14.26",
- "log 0.4.17",
+ "hyper",
+ "log",
"rustls 0.19.1",
"rustls-native-certs 0.5.0",
"tokio",
@@ -2897,7 +2719,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
dependencies = [
- "hyper 0.14.26",
+ "hyper",
"pin-project-lite",
"tokio",
"tokio-io-timeout",
@@ -2909,8 +2731,8 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
- "bytes 1.4.0",
- "hyper 0.14.26",
+ "bytes",
+ "hyper",
"native-tls",
"tokio",
"tokio-native-tls",
@@ -2942,50 +2764,18 @@ dependencies = [
[[package]]
name = "ibc"
version = "0.36.0"
-source = "git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=2d7edc16412b60cabf78163fe24a6264e11f77a9#2d7edc16412b60cabf78163fe24a6264e11f77a9"
-dependencies = [
- "bytes 1.4.0",
- "cfg-if 1.0.0",
- "derive_more",
- "displaydoc",
- "dyn-clone",
- "erased-serde",
- "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f)",
- "ics23",
- "num-traits 0.2.15",
- "parking_lot 0.12.1",
- "primitive-types",
- "prost",
- "safe-regex",
- "serde 1.0.163",
- "serde_derive",
- "serde_json",
- "sha2 0.10.6",
- "subtle-encoding",
- "tendermint 0.23.6",
- "tendermint-light-client-verifier 0.23.6",
- "tendermint-proto 0.23.6",
- "tendermint-testgen 0.23.6",
- "time 0.3.17",
- "tracing 0.1.37",
- "uint",
-]
-
-[[package]]
-name = "ibc"
-version = "0.36.0"
-source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=db14744bfba6239cc5f58345ff90f8b7d42637d6#db14744bfba6239cc5f58345ff90f8b7d42637d6"
+source = "git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=e71bc2cc79f8c2b32e970d95312f251398c93d9e#e71bc2cc79f8c2b32e970d95312f251398c93d9e"
dependencies = [
- "bytes 1.4.0",
+ "bytes",
"cfg-if 1.0.0",
"derive_more",
"displaydoc",
"dyn-clone",
"erased-serde",
- "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs?rev=dd8ba23110a144ffe2074a0b889676468266435a)",
+ "ibc-proto",
"ics23",
"num-traits 0.2.15",
- "parking_lot 0.12.1",
+ "parking_lot",
"primitive-types",
"prost",
"safe-regex",
@@ -2994,11 +2784,11 @@ dependencies = [
"serde_json",
"sha2 0.10.6",
"subtle-encoding",
- "tendermint 0.23.5",
- "tendermint-light-client-verifier 0.23.5",
- "tendermint-proto 0.23.5",
- "tendermint-testgen 0.23.5",
- "time 0.3.17",
+ "tendermint",
+ "tendermint-light-client-verifier",
+ "tendermint-proto",
+ "tendermint-testgen",
+ "time",
"tracing 0.1.37",
"uint",
]
@@ -3006,46 +2796,29 @@ dependencies = [
[[package]]
name = "ibc-proto"
version = "0.26.0"
-source = "git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f#7e527b5b8c95d83351e93ceafc14ac853224283f"
+source = "git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=6f4038fcf4981f1ed70771d1cd89931267f917af#6f4038fcf4981f1ed70771d1cd89931267f917af"
dependencies = [
"base64 0.13.1",
- "bytes 1.4.0",
+ "bytes",
"flex-error",
"prost",
"serde 1.0.163",
"subtle-encoding",
- "tendermint-proto 0.23.6",
+ "tendermint-proto",
"tonic",
]
-[[package]]
-name = "ibc-proto"
-version = "0.26.0"
-source = "git+https://github.com/heliaxdev/ibc-proto-rs?rev=dd8ba23110a144ffe2074a0b889676468266435a#dd8ba23110a144ffe2074a0b889676468266435a"
-dependencies = [
- "base64 0.13.1",
- "borsh 0.10.3",
- "bytes 1.4.0",
- "flex-error",
- "parity-scale-codec",
- "prost",
- "scale-info",
- "serde 1.0.163",
- "subtle-encoding",
- "tendermint-proto 0.23.5",
-]
-
[[package]]
name = "ibc-relayer"
version = "0.22.0"
-source = "git+https://github.com/heliaxdev/hermes.git?rev=8e2ff3479edc0653f34b22df450d451eedd2c2ab#8e2ff3479edc0653f34b22df450d451eedd2c2ab"
+source = "git+https://github.com/heliaxdev/hermes.git?rev=a4ad1355fc0b05908881854aa27221cb2b878ac5#a4ad1355fc0b05908881854aa27221cb2b878ac5"
dependencies = [
"anyhow",
"async-stream",
"bech32 0.9.1",
"bitcoin",
"bs58",
- "bytes 1.4.0",
+ "bytes",
"crossbeam-channel 0.5.8",
"digest 0.10.6",
"dirs-next",
@@ -3053,14 +2826,14 @@ dependencies = [
"ed25519-dalek",
"ed25519-dalek-bip32",
"flex-error",
- "futures 0.3.28",
+ "futures",
"generic-array 0.14.7",
"hdpath",
"hex",
"http",
"humantime",
"humantime-serde",
- "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f)",
+ "ibc-proto",
"ibc-relayer-types",
"itertools",
"moka",
@@ -3070,7 +2843,7 @@ dependencies = [
"regex",
"retry",
"ripemd",
- "secp256k1 0.24.3",
+ "secp256k1",
"semver 1.0.17",
"serde 1.0.163",
"serde_derive",
@@ -3079,32 +2852,32 @@ dependencies = [
"signature",
"strum",
"subtle-encoding",
- "tendermint 0.23.6",
+ "tendermint",
"tendermint-light-client",
- "tendermint-light-client-verifier 0.23.6",
- "tendermint-proto 0.23.6",
- "tendermint-rpc 0.23.6",
+ "tendermint-light-client-verifier",
+ "tendermint-proto",
+ "tendermint-rpc",
"thiserror",
- "tiny-bip39",
+ "tiny-bip39 1.0.0",
"tiny-keccak",
"tokio",
"toml",
"tonic",
"tracing 0.1.37",
- "uuid 1.3.2",
+ "uuid 1.3.3",
]
[[package]]
name = "ibc-relayer-types"
version = "0.22.0"
-source = "git+https://github.com/heliaxdev/hermes.git?rev=8e2ff3479edc0653f34b22df450d451eedd2c2ab#8e2ff3479edc0653f34b22df450d451eedd2c2ab"
+source = "git+https://github.com/heliaxdev/hermes.git?rev=a4ad1355fc0b05908881854aa27221cb2b878ac5#a4ad1355fc0b05908881854aa27221cb2b878ac5"
dependencies = [
- "bytes 1.4.0",
+ "bytes",
"derive_more",
"dyn-clone",
"erased-serde",
"flex-error",
- "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f)",
+ "ibc-proto",
"ics23",
"itertools",
"num-rational",
@@ -3115,12 +2888,12 @@ dependencies = [
"serde_derive",
"serde_json",
"subtle-encoding",
- "tendermint 0.23.6",
- "tendermint-light-client-verifier 0.23.6",
- "tendermint-proto 0.23.6",
- "tendermint-rpc 0.23.6",
- "tendermint-testgen 0.23.6",
- "time 0.3.17",
+ "tendermint",
+ "tendermint-light-client-verifier",
+ "tendermint-proto",
+ "tendermint-rpc",
+ "tendermint-testgen",
+ "time",
"uint",
]
@@ -3131,7 +2904,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca44b684ce1859cff746ff46f5765ab72e12e3c06f76a8356db8f9a2ecf43f17"
dependencies = [
"anyhow",
- "bytes 1.4.0",
+ "bytes",
"hex",
"prost",
"ripemd",
@@ -3145,17 +2918,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
-[[package]]
-name = "idna"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
-dependencies = [
- "matches",
- "unicode-bidi",
- "unicode-normalization",
-]
-
[[package]]
name = "idna"
version = "0.3.0"
@@ -3197,9 +2959,9 @@ dependencies = [
[[package]]
name = "incrementalmerkletree"
-version = "0.2.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "186fd3ab92aeac865d4b80b410de9a7b341d31ba8281373caed0b6d17b2b5e96"
+checksum = "d5ad43a3f5795945459d577f6589cf62a476e92c79b75e70cd954364e14ce17b"
dependencies = [
"serde 1.0.163",
]
@@ -3215,7 +2977,7 @@ name = "index-set"
version = "0.7.1"
source = "git+https://github.com/heliaxdev/index-set?tag=v0.7.1#dc24cdbbe3664514d59f1a4c4031863fc565f1c2"
dependencies = [
- "borsh 0.9.4",
+ "borsh",
"serde 1.0.163",
]
@@ -3225,18 +2987,27 @@ version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
"hashbrown 0.12.3",
"serde 1.0.163",
]
+[[package]]
+name = "inout"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
+dependencies = [
+ "generic-array 0.14.7",
+]
+
[[package]]
name = "input_buffer"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413"
dependencies = [
- "bytes 1.4.0",
+ "bytes",
]
[[package]]
@@ -3262,15 +3033,6 @@ dependencies = [
"windows-sys 0.48.0",
]
-[[package]]
-name = "iovec"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
-dependencies = [
- "libc",
-]
-
[[package]]
name = "ipnet"
version = "2.7.2"
@@ -3303,25 +3065,25 @@ dependencies = [
[[package]]
name = "js-sys"
-version = "0.3.62"
+version = "0.3.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5"
+checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "jubjub"
-version = "0.8.0"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2e7baec19d4e83f9145d4891178101a604565edff9645770fc979804138b04c"
+checksum = "a575df5f985fe1cd5b2b05664ff6accfc46559032b954529fd225a2168d27b0f"
dependencies = [
- "bitvec 0.22.3",
+ "bitvec",
"bls12_381",
- "ff",
- "group",
+ "ff 0.12.1",
+ "group 0.12.1",
"rand_core 0.6.4",
- "subtle",
+ "subtle 2.4.1",
]
[[package]]
@@ -3346,31 +3108,15 @@ dependencies = [
"cpufeatures",
]
-[[package]]
-name = "kernel32-sys"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
-dependencies = [
- "winapi 0.2.8",
- "winapi-build",
-]
-
[[package]]
name = "kv-log-macro"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
dependencies = [
- "log 0.4.17",
+ "log",
]
-[[package]]
-name = "language-tags"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
-
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -3429,14 +3175,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if 1.0.0",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
name = "libm"
-version = "0.2.6"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb"
+checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4"
[[package]]
name = "librocksdb-sys"
@@ -3454,6 +3200,22 @@ dependencies = [
"zstd-sys",
]
+[[package]]
+name = "libsecp256k1"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962"
+dependencies = [
+ "arrayref",
+ "crunchy",
+ "digest 0.8.1",
+ "hmac-drbg 0.2.0",
+ "rand 0.7.3",
+ "sha2 0.8.2",
+ "subtle 2.4.1",
+ "typenum",
+]
+
[[package]]
name = "libsecp256k1"
version = "0.7.0"
@@ -3462,7 +3224,7 @@ dependencies = [
"arrayref",
"base64 0.13.1",
"digest 0.9.0",
- "hmac-drbg",
+ "hmac-drbg 0.3.0",
"libsecp256k1-core",
"libsecp256k1-gen-ecmult",
"libsecp256k1-gen-genmult",
@@ -3477,9 +3239,9 @@ name = "libsecp256k1-core"
version = "0.3.0"
source = "git+https://github.com/heliaxdev/libsecp256k1?rev=bbb3bd44a49db361f21d9db80f9a087c194c0ae9#bbb3bd44a49db361f21d9db80f9a087c194c0ae9"
dependencies = [
- "crunchy 0.2.2",
+ "crunchy",
"digest 0.9.0",
- "subtle",
+ "subtle 2.4.1",
]
[[package]]
@@ -3539,41 +3301,22 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"
-[[package]]
-name = "lock_api"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
-dependencies = [
- "scopeguard",
-]
-
[[package]]
name = "lock_api"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
"scopeguard",
]
[[package]]
name = "log"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
-dependencies = [
- "log 0.4.17",
-]
-
-[[package]]
-name = "log"
-version = "0.4.17"
+version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
dependencies = [
- "cfg-if 1.0.0",
"value-bag",
]
@@ -3621,60 +3364,69 @@ dependencies = [
"serde_yaml",
]
+[[package]]
+name = "masp_note_encryption"
+version = "0.2.0"
+source = "git+https://github.com/anoma/masp?rev=cfea8c95d3f73077ca3e25380fd27e5b46e828fd#cfea8c95d3f73077ca3e25380fd27e5b46e828fd"
+dependencies = [
+ "borsh",
+ "chacha20 0.9.1",
+ "chacha20poly1305",
+ "cipher 0.4.4",
+ "rand_core 0.6.4",
+ "subtle 2.4.1",
+]
+
[[package]]
name = "masp_primitives"
-version = "0.5.0"
-source = "git+https://github.com/anoma/masp?rev=bee40fc465f6afbd10558d12fe96eb1742eee45c#bee40fc465f6afbd10558d12fe96eb1742eee45c"
+version = "0.9.0"
+source = "git+https://github.com/anoma/masp?rev=cfea8c95d3f73077ca3e25380fd27e5b46e828fd#cfea8c95d3f73077ca3e25380fd27e5b46e828fd"
dependencies = [
"aes",
"bip0039",
- "bitvec 0.22.3",
- "blake2b_simd 1.0.1",
- "blake2s_simd 1.0.1",
+ "bitvec",
+ "blake2b_simd",
+ "blake2s_simd",
"bls12_381",
- "borsh 0.9.4",
+ "borsh",
"byteorder",
- "chacha20poly1305",
- "crypto_api_chachapoly",
- "ff",
+ "ff 0.12.1",
"fpe",
- "group",
+ "group 0.12.1",
"hex",
"incrementalmerkletree",
"jubjub",
"lazy_static",
+ "masp_note_encryption",
+ "memuse",
+ "nonempty",
"rand 0.8.5",
"rand_core 0.6.4",
- "ripemd160",
- "secp256k1 0.20.3",
- "serde 1.0.163",
"sha2 0.9.9",
- "subtle",
+ "subtle 2.4.1",
"zcash_encoding",
- "zcash_primitives",
]
[[package]]
name = "masp_proofs"
-version = "0.5.0"
-source = "git+https://github.com/anoma/masp?rev=bee40fc465f6afbd10558d12fe96eb1742eee45c#bee40fc465f6afbd10558d12fe96eb1742eee45c"
+version = "0.9.0"
+source = "git+https://github.com/anoma/masp?rev=cfea8c95d3f73077ca3e25380fd27e5b46e828fd#cfea8c95d3f73077ca3e25380fd27e5b46e828fd"
dependencies = [
"bellman",
- "blake2b_simd 1.0.1",
+ "blake2b_simd",
"bls12_381",
- "byteorder",
"directories",
- "ff",
- "group",
+ "getrandom 0.2.9",
+ "group 0.12.1",
"itertools",
"jubjub",
"lazy_static",
"masp_primitives",
"minreq",
"rand_core 0.6.4",
+ "redjubjub",
+ "tracing 0.1.37",
"wagyu-zcash-parameters",
- "zcash_primitives",
- "zcash_proofs",
]
[[package]]
@@ -3686,12 +3438,6 @@ dependencies = [
"regex-automata",
]
-[[package]]
-name = "matches"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
-
[[package]]
name = "matchit"
version = "0.7.0"
@@ -3711,7 +3457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56220900f1a0923789ecd6bf25fbae8af3b2f1ff3e9e297fc9b6b8674dd4d852"
dependencies = [
"instant",
- "log 0.4.17",
+ "log",
]
[[package]]
@@ -3735,7 +3481,16 @@ version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
+]
+
+[[package]]
+name = "memoffset"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
+dependencies = [
+ "autocfg",
]
[[package]]
@@ -3744,7 +3499,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
]
[[package]]
@@ -3752,9 +3507,12 @@ name = "memuse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2145869435ace5ea6ea3d35f59be559317ec9a0d04e1812d5f185a87b6d36f1a"
-dependencies = [
- "nonempty",
-]
+
+[[package]]
+name = "memzero"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93c0d11ac30a033511ae414355d80f70d9f29a44a49140face477117a1ee90db"
[[package]]
name = "merlin"
@@ -3768,15 +3526,6 @@ dependencies = [
"zeroize",
]
-[[package]]
-name = "mime"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
-dependencies = [
- "log 0.3.9",
-]
-
[[package]]
name = "mime"
version = "0.3.17"
@@ -3789,8 +3538,8 @@ version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
dependencies = [
- "mime 0.3.17",
- "unicase 2.6.0",
+ "mime",
+ "unicase",
]
[[package]]
@@ -3823,32 +3572,13 @@ version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb6c6973f78ef55d0e5fc04fdb8f9ad67c87c9e86bca0ff77b6a3102b0eb36b7"
dependencies = [
- "log 0.4.17",
+ "log",
"once_cell",
"rustls 0.20.8",
"webpki 0.22.0",
"webpki-roots 0.22.6",
]
-[[package]]
-name = "mio"
-version = "0.6.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
-dependencies = [
- "cfg-if 0.1.10",
- "fuchsia-zircon",
- "fuchsia-zircon-sys",
- "iovec",
- "kernel32-sys",
- "libc",
- "log 0.4.17",
- "miow",
- "net2",
- "slab",
- "winapi 0.2.8",
-]
-
[[package]]
name = "mio"
version = "0.8.6"
@@ -3856,23 +3586,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
dependencies = [
"libc",
- "log 0.4.17",
+ "log",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.45.0",
]
-[[package]]
-name = "miow"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
-dependencies = [
- "kernel32-sys",
- "net2",
- "winapi 0.2.8",
- "ws2_32-sys",
-]
-
[[package]]
name = "miracl_core"
version = "2.3.0"
@@ -3890,16 +3608,16 @@ dependencies = [
"crossbeam-utils 0.8.15",
"num_cpus",
"once_cell",
- "parking_lot 0.12.1",
+ "parking_lot",
"quanta",
"rustc_version 0.4.0",
"scheduled-thread-pool",
"skeptic",
- "smallvec 1.10.0",
+ "smallvec",
"tagptr",
"thiserror",
"triomphe",
- "uuid 1.3.2",
+ "uuid 1.3.3",
]
[[package]]
@@ -3916,26 +3634,22 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
[[package]]
name = "namada"
-version = "0.16.0"
+version = "0.17.5"
dependencies = [
"assert_matches",
"async-std",
"async-trait",
- "bellman",
+ "base58 0.2.0",
"bimap",
- "bls12_381",
- "borsh 0.9.4",
+ "borsh",
"byte-unit",
"circular-queue",
"clru",
"data-encoding",
+ "derivation-path",
"derivative",
- "ibc 0.36.0 (git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=2d7edc16412b60cabf78163fe24a6264e11f77a9)",
- "ibc 0.36.0 (git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=db14744bfba6239cc5f58345ff90f8b7d42637d6)",
- "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f)",
- "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs?rev=dd8ba23110a144ffe2074a0b889676468266435a)",
"itertools",
- "libsecp256k1",
+ "libsecp256k1 0.7.0",
"loupe",
"masp_primitives",
"masp_proofs",
@@ -3952,17 +3666,19 @@ dependencies = [
"rand 0.8.5",
"rand_core 0.6.4",
"rayon",
+ "ripemd",
"rust_decimal",
"rust_decimal_macros",
"serde 1.0.163",
"serde_json",
"sha2 0.9.9",
+ "slip10_ed25519",
"tempfile",
- "tendermint 0.23.6",
- "tendermint-proto 0.23.6",
- "tendermint-rpc 0.23.6",
+ "tendermint-rpc",
"test-log",
"thiserror",
+ "tiny-bip39 0.8.2",
+ "tiny-hderive",
"tokio",
"toml",
"tracing 0.1.37",
@@ -3979,7 +3695,7 @@ dependencies = [
[[package]]
name = "namada_apps"
-version = "0.16.0"
+version = "0.17.5"
dependencies = [
"ark-serialize",
"ark-std",
@@ -3991,7 +3707,7 @@ dependencies = [
"bimap",
"bit-set",
"blake2b-rs",
- "borsh 0.9.4",
+ "borsh",
"byte-unit",
"byteorder",
"clap",
@@ -4006,7 +3722,7 @@ dependencies = [
"ferveo-common",
"file-lock",
"flate2",
- "futures 0.3.28",
+ "futures",
"git2",
"itertools",
"libc",
@@ -4029,6 +3745,7 @@ dependencies = [
"rayon",
"regex",
"reqwest",
+ "ripemd",
"rlimit",
"rocksdb",
"rpassword",
@@ -4043,10 +3760,7 @@ dependencies = [
"sysinfo",
"tar",
"tempfile",
- "tendermint 0.23.6",
- "tendermint-config 0.23.6",
- "tendermint-proto 0.23.6",
- "tendermint-rpc 0.23.6",
+ "tendermint-config",
"test-log",
"thiserror",
"tokio",
@@ -4054,26 +3768,24 @@ dependencies = [
"toml",
"tonic",
"tower",
- "tower-abci 0.1.0 (git+https://github.com/heliaxdev/tower-abci.git?rev=79069a441cee7d9955a3d826d29656a0fb16115c)",
- "tower-abci 0.1.0 (git+https://github.com/heliaxdev/tower-abci?rev=a31ce06533f5fbd943508676059d44de27395792)",
+ "tower-abci",
"tracing 0.1.37",
"tracing-log",
"tracing-subscriber 0.3.17",
- "websocket",
- "winapi 0.3.9",
+ "winapi",
+ "zeroize",
]
[[package]]
name = "namada_core"
-version = "0.16.0"
+version = "0.17.5"
dependencies = [
"ark-bls12-381",
"ark-ec",
"ark-serialize",
"assert_matches",
"bech32 0.8.1",
- "bellman",
- "borsh 0.9.4",
+ "borsh",
"chrono",
"data-encoding",
"derivative",
@@ -4081,14 +3793,12 @@ dependencies = [
"ferveo",
"ferveo-common",
"group-threshold-cryptography",
- "ibc 0.36.0 (git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=2d7edc16412b60cabf78163fe24a6264e11f77a9)",
- "ibc 0.36.0 (git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=db14744bfba6239cc5f58345ff90f8b7d42637d6)",
- "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f)",
- "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs?rev=dd8ba23110a144ffe2074a0b889676468266435a)",
+ "ibc",
+ "ibc-proto",
"ics23",
"index-set",
"itertools",
- "libsecp256k1",
+ "libsecp256k1 0.7.0",
"masp_primitives",
"namada_macros",
"pretty_assertions",
@@ -4104,8 +3814,8 @@ dependencies = [
"serde_json",
"sha2 0.9.9",
"sparse-merkle-tree",
- "tendermint 0.23.6",
- "tendermint-proto 0.23.6",
+ "tendermint",
+ "tendermint-proto",
"test-log",
"thiserror",
"tonic-build",
@@ -4116,9 +3826,9 @@ dependencies = [
[[package]]
name = "namada_encoding_spec"
-version = "0.16.0"
+version = "0.17.5"
dependencies = [
- "borsh 0.9.4",
+ "borsh",
"itertools",
"lazy_static",
"madato",
@@ -4127,7 +3837,7 @@ dependencies = [
[[package]]
name = "namada_macros"
-version = "0.16.0"
+version = "0.17.5"
dependencies = [
"proc-macro2",
"quote",
@@ -4136,16 +3846,16 @@ dependencies = [
[[package]]
name = "namada_proof_of_stake"
-version = "0.16.0"
+version = "0.17.5"
dependencies = [
- "borsh 0.9.4",
+ "borsh",
"data-encoding",
"derivative",
- "hex",
"itertools",
"namada_core",
"once_cell",
"proptest",
+ "proptest-state-machine",
"rust_decimal",
"rust_decimal_macros",
"test-log",
@@ -4156,19 +3866,19 @@ dependencies = [
[[package]]
name = "namada_test_utils"
-version = "0.16.0"
+version = "0.17.5"
dependencies = [
- "borsh 0.9.4",
+ "borsh",
"namada_core",
"strum",
]
[[package]]
name = "namada_tests"
-version = "0.16.0"
+version = "0.17.5"
dependencies = [
"assert_cmd",
- "borsh 0.9.4",
+ "borsh",
"chrono",
"color-eyre",
"concat-idents",
@@ -4188,8 +3898,10 @@ dependencies = [
"namada_test_utils",
"namada_tx_prelude",
"namada_vp_prelude",
+ "once_cell",
"pretty_assertions",
"proptest",
+ "proptest-state-machine",
"prost",
"rand 0.8.5",
"regex",
@@ -4198,10 +3910,6 @@ dependencies = [
"serde_json",
"sha2 0.9.9",
"tempfile",
- "tendermint 0.23.6",
- "tendermint-config 0.23.6",
- "tendermint-proto 0.23.6",
- "tendermint-rpc 0.23.6",
"test-log",
"tokio",
"toml",
@@ -4211,40 +3919,38 @@ dependencies = [
[[package]]
name = "namada_tx_prelude"
-version = "0.16.0"
+version = "0.17.5"
dependencies = [
- "borsh 0.9.4",
+ "borsh",
"masp_primitives",
"namada_core",
"namada_macros",
"namada_proof_of_stake",
"namada_vm_env",
"rust_decimal",
- "sha2 0.10.6",
+ "sha2 0.9.9",
"thiserror",
]
[[package]]
name = "namada_vm_env"
-version = "0.16.0"
+version = "0.17.5"
dependencies = [
- "borsh 0.9.4",
- "hex",
+ "borsh",
"masp_primitives",
- "masp_proofs",
"namada_core",
]
[[package]]
name = "namada_vp_prelude"
-version = "0.16.0"
+version = "0.17.5"
dependencies = [
- "borsh 0.9.4",
+ "borsh",
"namada_core",
"namada_macros",
"namada_proof_of_stake",
"namada_vm_env",
- "sha2 0.10.6",
+ "sha2 0.9.9",
"thiserror",
]
@@ -4256,7 +3962,7 @@ checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
dependencies = [
"lazy_static",
"libc",
- "log 0.4.17",
+ "log",
"openssl",
"openssl-probe",
"openssl-sys",
@@ -4266,41 +3972,18 @@ dependencies = [
"tempfile",
]
-[[package]]
-name = "net2"
-version = "0.2.38"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631"
-dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "nix"
-version = "0.21.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77d9f3521ea8e0641a153b3cddaf008dcbf26acd4ed739a2517295e0760d12c7"
-dependencies = [
- "bitflags",
- "cc",
- "cfg-if 1.0.0",
- "libc",
- "memoffset 0.6.5",
-]
-
[[package]]
name = "nix"
-version = "0.23.2"
+version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c"
+checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
dependencies = [
"bitflags",
- "cc",
"cfg-if 1.0.0",
"libc",
- "memoffset 0.6.5",
+ "memoffset 0.7.1",
+ "pin-utils",
+ "static_assertions",
]
[[package]]
@@ -4311,7 +3994,7 @@ checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b"
dependencies = [
"lexical-core",
"memchr",
- "version_check 0.9.4",
+ "version_check",
]
[[package]]
@@ -4336,7 +4019,7 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
dependencies = [
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -4346,7 +4029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
dependencies = [
"overload",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -4369,7 +4052,7 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
"num-integer",
"num-traits 0.2.15",
"serde 1.0.163",
@@ -4401,7 +4084,7 @@ version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
"num-traits 0.2.15",
]
@@ -4411,7 +4094,7 @@ version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
"num-integer",
"num-traits 0.2.15",
]
@@ -4422,7 +4105,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
"num-bigint",
"num-integer",
"num-traits 0.2.15",
@@ -4444,7 +4127,7 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
"libm",
]
@@ -4520,7 +4203,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -4541,33 +4224,6 @@ dependencies = [
"vcpkg",
]
-[[package]]
-name = "orchard"
-version = "0.1.0-beta.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e31f03b6d0aee6d993cac35388b818e04f076ded0ab284979e4d7cd5a8b3c2be"
-dependencies = [
- "aes",
- "arrayvec 0.7.2",
- "bigint",
- "bitvec 0.22.3",
- "blake2b_simd 1.0.1",
- "ff",
- "fpe",
- "group",
- "halo2",
- "incrementalmerkletree",
- "lazy_static",
- "memuse",
- "nonempty",
- "pasta_curves",
- "rand 0.8.5",
- "reddsa",
- "serde 1.0.163",
- "subtle",
- "zcash_note_encryption 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "orion"
version = "0.16.1"
@@ -4576,7 +4232,7 @@ checksum = "c6624905ddd92e460ff0685567539ed1ac985b2dee4c92c7edcd64fce905b00c"
dependencies = [
"ct-codecs",
"getrandom 0.2.9",
- "subtle",
+ "subtle 2.4.1",
"zeroize",
]
@@ -4592,7 +4248,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66"
dependencies = [
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -4609,11 +4265,11 @@ checksum = "2386b4ebe91c2f7f51082d4cefa145d030e33a1842a96b12e4885cc3c01f7a55"
[[package]]
name = "pairing"
-version = "0.21.0"
+version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2e415e349a3006dd7d9482cdab1c980a845bed1377777d768cb693a44540b42"
+checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b"
dependencies = [
- "group",
+ "group 0.12.1",
]
[[package]]
@@ -4623,7 +4279,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ddb756ca205bd108aee3c62c6d3c994e1df84a59b9d6d4a5ea42ee1fd5a9a28"
dependencies = [
"arrayvec 0.7.2",
- "bitvec 1.0.1",
+ "bitvec",
"byte-slice-cast",
"impl-trait-for-tuples",
"parity-scale-codec-derive",
@@ -4654,40 +4310,14 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e"
-[[package]]
-name = "parking_lot"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
-dependencies = [
- "lock_api 0.3.4",
- "parking_lot_core 0.6.3",
- "rustc_version 0.2.3",
-]
-
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
- "lock_api 0.4.9",
- "parking_lot_core 0.9.7",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a"
-dependencies = [
- "cfg-if 0.1.10",
- "cloudabi",
- "libc",
- "redox_syscall 0.1.57",
- "rustc_version 0.2.3",
- "smallvec 0.6.14",
- "winapi 0.3.9",
+ "lock_api",
+ "parking_lot_core",
]
[[package]]
@@ -4699,7 +4329,7 @@ dependencies = [
"cfg-if 1.0.0",
"libc",
"redox_syscall 0.2.16",
- "smallvec 1.10.0",
+ "smallvec",
"windows-sys 0.45.0",
]
@@ -4711,22 +4341,7 @@ checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8"
dependencies = [
"base64ct",
"rand_core 0.6.4",
- "subtle",
-]
-
-[[package]]
-name = "pasta_curves"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d647d91972bad78120fd61e06b225fcda117805c9bbf17676b51bd03a251278b"
-dependencies = [
- "blake2b_simd 0.5.11",
- "ff",
- "group",
- "lazy_static",
- "rand 0.8.5",
- "static_assertions",
- "subtle",
+ "subtle 2.4.1",
]
[[package]]
@@ -4735,6 +4350,15 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
+[[package]]
+name = "pbkdf2"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd"
+dependencies = [
+ "crypto-mac 0.8.0",
+]
+
[[package]]
name = "pbkdf2"
version = "0.9.0"
@@ -4787,12 +4411,6 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088"
-[[package]]
-name = "percent-encoding"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
-
[[package]]
name = "percent-encoding"
version = "2.2.0"
@@ -4836,7 +4454,7 @@ checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -4859,23 +4477,23 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "polling"
-version = "2.3.0"
-source = "git+https://github.com/heliaxdev/polling.git?rev=02a655775282879459a3460e2646b60c005bca2c#02a655775282879459a3460e2646b60c005bca2c"
+version = "2.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
"cfg-if 1.0.0",
"libc",
- "log 0.4.17",
- "rustversion",
+ "log",
"wepoll-ffi",
- "winapi 0.3.9",
+ "windows-sys 0.42.0",
]
[[package]]
name = "poly1305"
-version = "0.7.2"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede"
+checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
dependencies = [
"cpufeatures",
"opaque-debug 0.3.0",
@@ -4939,12 +4557,12 @@ dependencies = [
[[package]]
name = "prettyplease"
-version = "0.2.4"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ceca8aaf45b5c46ec7ed39fff75f57290368c1846d33d24a122ca81416ab058"
+checksum = "617feabb81566b593beb4886fb8c1f38064169dae4dccad0e3220160c3b37203"
dependencies = [
"proc-macro2",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -4988,7 +4606,7 @@ dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
- "version_check 0.9.4",
+ "version_check",
]
[[package]]
@@ -4999,22 +4617,23 @@ checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
- "version_check 0.9.4",
+ "version_check",
]
[[package]]
name = "proc-macro2"
-version = "1.0.56"
+version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
+checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "proptest"
-version = "1.1.0"
-source = "git+https://github.com/heliaxdev/proptest?rev=8f1b4abe7ebd35c0781bf9a00a4ee59833ffa2a1#8f1b4abe7ebd35c0781bf9a00a4ee59833ffa2a1"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65"
dependencies = [
"bit-set",
"bitflags",
@@ -5023,20 +4642,29 @@ dependencies = [
"num-traits 0.2.15",
"rand 0.8.5",
"rand_chacha 0.3.1",
- "rand_xorshift 0.3.0",
+ "rand_xorshift",
"regex-syntax 0.6.29",
"rusty-fork",
"tempfile",
"unarray",
]
+[[package]]
+name = "proptest-state-machine"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b52a714915de2d16a5289616d2265a934780f50a9dd30359322b687403fa2ac2"
+dependencies = [
+ "proptest",
+]
+
[[package]]
name = "prost"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd"
dependencies = [
- "bytes 1.4.0",
+ "bytes",
"prost-derive",
]
@@ -5046,11 +4674,11 @@ version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270"
dependencies = [
- "bytes 1.4.0",
+ "bytes",
"heck",
"itertools",
"lazy_static",
- "log 0.4.17",
+ "log",
"multimap",
"petgraph",
"prettyplease 0.1.25",
@@ -5106,11 +4734,11 @@ dependencies = [
[[package]]
name = "ptyprocess"
-version = "0.3.0"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69c28fcebfd842bfe19d69409fc321230ea8c1bebe31f274906485c761ce1917"
+checksum = "7e05aef7befb11a210468a2d77d978dde2c6381a0381e33beb575e91f57fe8cf"
dependencies = [
- "nix 0.21.2",
+ "nix",
]
[[package]]
@@ -5121,7 +4749,7 @@ checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6"
dependencies = [
"bitflags",
"memchr",
- "unicase 2.6.0",
+ "unicase",
]
[[package]]
@@ -5130,7 +4758,7 @@ version = "0.20.0"
source = "git+https://github.com/heliaxdev/wasm-utils?tag=v0.20.0#782bfa7fb5e513b602e66af492cbc4cb1b06f2ba"
dependencies = [
"byteorder",
- "log 0.4.17",
+ "log",
"parity-wasm",
]
@@ -5147,7 +4775,7 @@ dependencies = [
"raw-cpuid",
"wasi 0.10.2+wasi-snapshot-preview1",
"web-sys",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -5165,37 +4793,12 @@ dependencies = [
"proc-macro2",
]
-[[package]]
-name = "radium"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb"
-
[[package]]
name = "radium"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
-[[package]]
-name = "rand"
-version = "0.6.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
-dependencies = [
- "autocfg 0.1.8",
- "libc",
- "rand_chacha 0.1.1",
- "rand_core 0.4.2",
- "rand_hc 0.1.0",
- "rand_isaac",
- "rand_jitter",
- "rand_os",
- "rand_pcg",
- "rand_xorshift 0.1.1",
- "winapi 0.3.9",
-]
-
[[package]]
name = "rand"
version = "0.7.3"
@@ -5206,7 +4809,7 @@ dependencies = [
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
- "rand_hc 0.2.0",
+ "rand_hc",
]
[[package]]
@@ -5220,16 +4823,6 @@ dependencies = [
"rand_core 0.6.4",
]
-[[package]]
-name = "rand_chacha"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
-dependencies = [
- "autocfg 0.1.8",
- "rand_core 0.3.1",
-]
-
[[package]]
name = "rand_chacha"
version = "0.2.2"
@@ -5250,21 +4843,6 @@ dependencies = [
"rand_core 0.6.4",
]
-[[package]]
-name = "rand_core"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
-dependencies = [
- "rand_core 0.4.2",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
-
[[package]]
name = "rand_core"
version = "0.5.1"
@@ -5283,15 +4861,6 @@ dependencies = [
"getrandom 0.2.9",
]
-[[package]]
-name = "rand_hc"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
-dependencies = [
- "rand_core 0.3.1",
-]
-
[[package]]
name = "rand_hc"
version = "0.2.0"
@@ -5301,59 +4870,6 @@ dependencies = [
"rand_core 0.5.1",
]
-[[package]]
-name = "rand_isaac"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
-dependencies = [
- "rand_core 0.3.1",
-]
-
-[[package]]
-name = "rand_jitter"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
-dependencies = [
- "libc",
- "rand_core 0.4.2",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "rand_os"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
-dependencies = [
- "cloudabi",
- "fuchsia-cprng",
- "libc",
- "rand_core 0.4.2",
- "rdrand",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "rand_pcg"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
-dependencies = [
- "autocfg 0.1.8",
- "rand_core 0.4.2",
-]
-
-[[package]]
-name = "rand_xorshift"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
-dependencies = [
- "rand_core 0.3.1",
-]
-
[[package]]
name = "rand_xorshift"
version = "0.3.0"
@@ -5378,7 +4894,7 @@ version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
"crossbeam-deque",
"either",
"rayon-core",
@@ -5397,38 +4913,21 @@ dependencies = [
]
[[package]]
-name = "rdrand"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
-dependencies = [
- "rand_core 0.3.1",
-]
-
-[[package]]
-name = "reddsa"
-version = "0.1.0"
+name = "redjubjub"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a90e2c94bca3445cae0d55dff7370e29c24885d2403a1665ce19c106c79455e6"
+checksum = "6039ff156887caf92df308cbaccdc058c9d3155a913da046add6e48c4cdbd91d"
dependencies = [
- "blake2b_simd 0.5.11",
+ "blake2b_simd",
"byteorder",
"digest 0.9.0",
- "group",
"jubjub",
- "pasta_curves",
"rand_core 0.6.4",
"serde 1.0.163",
"thiserror",
"zeroize",
]
-[[package]]
-name = "redox_syscall"
-version = "0.1.57"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
-
[[package]]
name = "redox_syscall"
version = "0.2.16"
@@ -5464,9 +4963,9 @@ version = "0.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "571f7f397d61c4755285cd37853fe8e03271c243424a907415909379659381c5"
dependencies = [
- "log 0.4.17",
+ "log",
"rustc-hash",
- "smallvec 1.10.0",
+ "smallvec",
]
[[package]]
@@ -5510,7 +5009,7 @@ dependencies = [
"bitflags",
"libc",
"mach",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -5524,27 +5023,27 @@ dependencies = [
[[package]]
name = "reqwest"
-version = "0.11.17"
+version = "0.11.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91"
+checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55"
dependencies = [
"base64 0.21.0",
- "bytes 1.4.0",
+ "bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
- "hyper 0.14.26",
+ "hyper",
"hyper-tls",
"ipnet",
"js-sys",
- "log 0.4.17",
- "mime 0.3.17",
+ "log",
+ "mime",
"native-tls",
"once_cell",
- "percent-encoding 2.2.0",
+ "percent-encoding",
"pin-project-lite",
"serde 1.0.163",
"serde_json",
@@ -5552,7 +5051,7 @@ dependencies = [
"tokio",
"tokio-native-tls",
"tower-service",
- "url 2.3.1",
+ "url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
@@ -5588,7 +5087,7 @@ dependencies = [
"spin",
"untrusted",
"web-sys",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -5617,7 +5116,7 @@ version = "0.7.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58"
dependencies = [
- "bitvec 1.0.1",
+ "bitvec",
"bytecheck",
"hashbrown 0.12.3",
"ptr_meta",
@@ -5625,7 +5124,7 @@ dependencies = [
"rkyv_derive",
"seahash",
"tinyvec",
- "uuid 1.3.2",
+ "uuid 1.3.3",
]
[[package]]
@@ -5665,7 +5164,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb"
dependencies = [
"libc",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -5681,7 +5180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee9164faf726e4f3ece4978b25ca877ddc6802fa77f38cdccb32c7f805ecd70c"
dependencies = [
"arrayvec 0.7.2",
- "borsh 0.9.4",
+ "borsh",
"num-traits 0.2.15",
"serde 1.0.163",
]
@@ -5714,15 +5213,6 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
-[[package]]
-name = "rustc_version"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
-dependencies = [
- "semver 0.9.0",
-]
-
[[package]]
name = "rustc_version"
version = "0.3.3"
@@ -5762,7 +5252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
dependencies = [
"base64 0.13.1",
- "log 0.4.17",
+ "log",
"ring",
"sct 0.6.1",
"webpki 0.21.4",
@@ -5774,7 +5264,7 @@ version = "0.20.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f"
dependencies = [
- "log 0.4.17",
+ "log",
"ring",
"sct 0.7.0",
"webpki 0.22.0",
@@ -5884,12 +5374,6 @@ dependencies = [
"safe-regex-compiler",
]
-[[package]]
-name = "safemem"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
-
[[package]]
name = "same-file"
version = "1.0.6"
@@ -5899,30 +5383,6 @@ dependencies = [
"winapi-util",
]
-[[package]]
-name = "scale-info"
-version = "2.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfdef77228a4c05dc94211441595746732131ad7f6530c6c18f045da7b7ab937"
-dependencies = [
- "cfg-if 1.0.0",
- "derive_more",
- "parity-scale-codec",
- "scale-info-derive",
-]
-
-[[package]]
-name = "scale-info-derive"
-version = "2.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53012eae69e5aa5c14671942a5dd47de59d4cdcff8532a6dd0e081faf1119482"
-dependencies = [
- "proc-macro-crate 1.3.1",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
[[package]]
name = "schannel"
version = "0.1.21"
@@ -5938,7 +5398,7 @@ version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19"
dependencies = [
- "parking_lot 0.12.1",
+ "parking_lot",
]
[[package]]
@@ -5981,19 +5441,10 @@ checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1"
dependencies = [
"der",
"generic-array 0.14.7",
- "subtle",
+ "subtle 2.4.1",
"zeroize",
]
-[[package]]
-name = "secp256k1"
-version = "0.20.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a"
-dependencies = [
- "secp256k1-sys 0.4.2",
-]
-
[[package]]
name = "secp256k1"
version = "0.24.3"
@@ -6002,19 +5453,10 @@ checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62"
dependencies = [
"bitcoin_hashes",
"rand 0.8.5",
- "secp256k1-sys 0.6.1",
+ "secp256k1-sys",
"serde 1.0.163",
]
-[[package]]
-name = "secp256k1-sys"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036"
-dependencies = [
- "cc",
-]
-
[[package]]
name = "secp256k1-sys"
version = "0.6.1"
@@ -6047,22 +5489,13 @@ dependencies = [
"libc",
]
-[[package]]
-name = "semver"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
-dependencies = [
- "semver-parser 0.7.0",
-]
-
[[package]]
name = "semver"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
dependencies = [
- "semver-parser 0.10.2",
+ "semver-parser",
]
[[package]]
@@ -6074,12 +5507,6 @@ dependencies = [
"serde 1.0.163",
]
-[[package]]
-name = "semver-parser"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-
[[package]]
name = "semver-parser"
version = "0.10.2"
@@ -6143,7 +5570,7 @@ checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -6165,7 +5592,7 @@ checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -6192,18 +5619,6 @@ dependencies = [
"yaml-rust",
]
-[[package]]
-name = "sha-1"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
-dependencies = [
- "block-buffer 0.7.3",
- "digest 0.8.1",
- "fake-simd",
- "opaque-debug 0.2.3",
-]
-
[[package]]
name = "sha-1"
version = "0.9.8"
@@ -6228,6 +5643,18 @@ dependencies = [
"digest 0.10.6",
]
+[[package]]
+name = "sha2"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
+dependencies = [
+ "block-buffer 0.7.3",
+ "digest 0.8.1",
+ "fake-simd",
+ "opaque-debug 0.2.3",
+]
+
[[package]]
name = "sha2"
version = "0.9.9"
@@ -6339,16 +5766,16 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
dependencies = [
- "autocfg 1.1.0",
+ "autocfg",
]
[[package]]
-name = "smallvec"
-version = "0.6.14"
+name = "slip10_ed25519"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0"
+checksum = "4be0ff28bf14f9610a342169084e87a4f435ad798ec528dc7579a3678fa9dc9a"
dependencies = [
- "maybe-uninit",
+ "hmac-sha512",
]
[[package]]
@@ -6364,7 +5791,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
dependencies = [
"libc",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -6373,7 +5800,7 @@ version = "0.3.1-pre"
source = "git+https://github.com/heliaxdev/sparse-merkle-tree?rev=e086b235ed6e68929bf73f617dd61cd17b000a56#e086b235ed6e68929bf73f617dd61cd17b000a56"
dependencies = [
"blake2b-rs",
- "borsh 0.9.4",
+ "borsh",
"cfg-if 1.0.0",
"ics23",
"sha2 0.9.9",
@@ -6438,6 +5865,12 @@ dependencies = [
"ark-std",
]
+[[package]]
+name = "subtle"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
+
[[package]]
name = "subtle"
version = "2.4.1"
@@ -6472,9 +5905,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.15"
+version = "2.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
+checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01"
dependencies = [
"proc-macro2",
"quote",
@@ -6498,7 +5931,7 @@ dependencies = [
"libc",
"ntapi",
"once_cell",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -6543,45 +5976,17 @@ dependencies = [
"windows-sys 0.45.0",
]
-[[package]]
-name = "tendermint"
-version = "0.23.5"
-source = "git+https://github.com/heliaxdev/tendermint-rs?rev=a3a0ad5f07d380976bbd5321239aec9cc3a8f916#a3a0ad5f07d380976bbd5321239aec9cc3a8f916"
-dependencies = [
- "async-trait",
- "bytes 1.4.0",
- "ed25519",
- "ed25519-dalek",
- "flex-error",
- "futures 0.3.28",
- "num-traits 0.2.15",
- "once_cell",
- "prost",
- "prost-types",
- "serde 1.0.163",
- "serde_bytes",
- "serde_json",
- "serde_repr",
- "sha2 0.9.9",
- "signature",
- "subtle",
- "subtle-encoding",
- "tendermint-proto 0.23.5",
- "time 0.3.17",
- "zeroize",
-]
-
[[package]]
name = "tendermint"
version = "0.23.6"
-source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35"
+source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=02b256829e80f8cfecf3fa0d625c2a76c79cd043#02b256829e80f8cfecf3fa0d625c2a76c79cd043"
dependencies = [
"async-trait",
- "bytes 1.4.0",
+ "bytes",
"ed25519",
"ed25519-dalek",
"flex-error",
- "futures 0.3.28",
+ "futures",
"k256",
"num-traits 0.2.15",
"once_cell",
@@ -6594,108 +5999,65 @@ dependencies = [
"serde_repr",
"sha2 0.9.9",
"signature",
- "subtle",
+ "subtle 2.4.1",
"subtle-encoding",
- "tendermint-proto 0.23.6",
- "time 0.3.17",
+ "tendermint-proto",
+ "time",
"zeroize",
]
-[[package]]
-name = "tendermint-config"
-version = "0.23.5"
-source = "git+https://github.com/heliaxdev/tendermint-rs?rev=a3a0ad5f07d380976bbd5321239aec9cc3a8f916#a3a0ad5f07d380976bbd5321239aec9cc3a8f916"
-dependencies = [
- "flex-error",
- "serde 1.0.163",
- "serde_json",
- "tendermint 0.23.5",
- "toml",
- "url 2.3.1",
-]
-
[[package]]
name = "tendermint-config"
version = "0.23.6"
-source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35"
+source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=02b256829e80f8cfecf3fa0d625c2a76c79cd043#02b256829e80f8cfecf3fa0d625c2a76c79cd043"
dependencies = [
"flex-error",
"serde 1.0.163",
"serde_json",
- "tendermint 0.23.6",
+ "tendermint",
"toml",
- "url 2.3.1",
+ "url",
]
[[package]]
name = "tendermint-light-client"
version = "0.23.6"
-source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35"
+source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=02b256829e80f8cfecf3fa0d625c2a76c79cd043#02b256829e80f8cfecf3fa0d625c2a76c79cd043"
dependencies = [
"contracts",
"crossbeam-channel 0.4.4",
"derive_more",
"flex-error",
- "futures 0.3.28",
+ "futures",
"serde 1.0.163",
"serde_cbor",
"serde_derive",
"static_assertions",
- "tendermint 0.23.6",
- "tendermint-light-client-verifier 0.23.6",
- "tendermint-rpc 0.23.6",
- "time 0.3.17",
+ "tendermint",
+ "tendermint-light-client-verifier",
+ "tendermint-rpc",
+ "time",
"tokio",
]
[[package]]
name = "tendermint-light-client-verifier"
-version = "0.23.5"
-source = "git+https://github.com/heliaxdev/tendermint-rs?rev=a3a0ad5f07d380976bbd5321239aec9cc3a8f916#a3a0ad5f07d380976bbd5321239aec9cc3a8f916"
+version = "0.23.6"
+source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=02b256829e80f8cfecf3fa0d625c2a76c79cd043#02b256829e80f8cfecf3fa0d625c2a76c79cd043"
dependencies = [
"derive_more",
"flex-error",
"serde 1.0.163",
- "tendermint 0.23.5",
- "tendermint-rpc 0.23.5",
- "time 0.3.17",
+ "tendermint",
+ "time",
]
[[package]]
-name = "tendermint-light-client-verifier"
+name = "tendermint-proto"
version = "0.23.6"
-source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35"
+source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=02b256829e80f8cfecf3fa0d625c2a76c79cd043#02b256829e80f8cfecf3fa0d625c2a76c79cd043"
dependencies = [
- "derive_more",
- "flex-error",
- "serde 1.0.163",
- "tendermint 0.23.6",
- "time 0.3.17",
-]
-
-[[package]]
-name = "tendermint-proto"
-version = "0.23.5"
-source = "git+https://github.com/heliaxdev/tendermint-rs?rev=a3a0ad5f07d380976bbd5321239aec9cc3a8f916#a3a0ad5f07d380976bbd5321239aec9cc3a8f916"
-dependencies = [
- "bytes 1.4.0",
- "flex-error",
- "num-derive",
- "num-traits 0.2.15",
- "prost",
- "prost-types",
- "serde 1.0.163",
- "serde_bytes",
- "subtle-encoding",
- "time 0.3.17",
-]
-
-[[package]]
-name = "tendermint-proto"
-version = "0.23.6"
-source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35"
-dependencies = [
- "bytes 1.4.0",
+ "bytes",
"flex-error",
"num-derive",
"num-traits 0.2.15",
@@ -6704,46 +6066,22 @@ dependencies = [
"serde 1.0.163",
"serde_bytes",
"subtle-encoding",
- "time 0.3.17",
-]
-
-[[package]]
-name = "tendermint-rpc"
-version = "0.23.5"
-source = "git+https://github.com/heliaxdev/tendermint-rs?rev=a3a0ad5f07d380976bbd5321239aec9cc3a8f916#a3a0ad5f07d380976bbd5321239aec9cc3a8f916"
-dependencies = [
- "bytes 1.4.0",
- "flex-error",
- "getrandom 0.2.9",
- "peg",
- "pin-project",
- "serde 1.0.163",
- "serde_bytes",
- "serde_json",
- "subtle-encoding",
- "tendermint 0.23.5",
- "tendermint-config 0.23.5",
- "tendermint-proto 0.23.5",
- "thiserror",
- "time 0.3.17",
- "url 2.3.1",
- "uuid 0.8.2",
- "walkdir",
+ "time",
]
[[package]]
name = "tendermint-rpc"
version = "0.23.6"
-source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35"
+source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=02b256829e80f8cfecf3fa0d625c2a76c79cd043#02b256829e80f8cfecf3fa0d625c2a76c79cd043"
dependencies = [
"async-trait",
"async-tungstenite",
- "bytes 1.4.0",
+ "bytes",
"flex-error",
- "futures 0.3.28",
+ "futures",
"getrandom 0.2.9",
"http",
- "hyper 0.14.26",
+ "hyper",
"hyper-proxy",
"hyper-rustls",
"peg",
@@ -6752,37 +6090,22 @@ dependencies = [
"serde_bytes",
"serde_json",
"subtle-encoding",
- "tendermint 0.23.6",
- "tendermint-config 0.23.6",
- "tendermint-proto 0.23.6",
+ "tendermint",
+ "tendermint-config",
+ "tendermint-proto",
"thiserror",
- "time 0.3.17",
+ "time",
"tokio",
"tracing 0.1.37",
- "url 2.3.1",
+ "url",
"uuid 0.8.2",
"walkdir",
]
-[[package]]
-name = "tendermint-testgen"
-version = "0.23.5"
-source = "git+https://github.com/heliaxdev/tendermint-rs?rev=a3a0ad5f07d380976bbd5321239aec9cc3a8f916#a3a0ad5f07d380976bbd5321239aec9cc3a8f916"
-dependencies = [
- "ed25519-dalek",
- "gumdrop",
- "serde 1.0.163",
- "serde_json",
- "simple-error",
- "tempfile",
- "tendermint 0.23.5",
- "time 0.3.17",
-]
-
[[package]]
name = "tendermint-testgen"
version = "0.23.6"
-source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35"
+source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=02b256829e80f8cfecf3fa0d625c2a76c79cd043#02b256829e80f8cfecf3fa0d625c2a76c79cd043"
dependencies = [
"ed25519-dalek",
"gumdrop",
@@ -6790,8 +6113,8 @@ dependencies = [
"serde_json",
"simple-error",
"tempfile",
- "tendermint 0.23.6",
- "time 0.3.17",
+ "tendermint",
+ "time",
]
[[package]]
@@ -6846,7 +6169,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -6869,16 +6192,6 @@ dependencies = [
"libc",
]
-[[package]]
-name = "time"
-version = "0.1.43"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
-dependencies = [
- "libc",
- "winapi 0.3.9",
-]
-
[[package]]
name = "time"
version = "0.3.17"
@@ -6905,6 +6218,24 @@ dependencies = [
"time-core",
]
+[[package]]
+name = "tiny-bip39"
+version = "0.8.2"
+source = "git+https://github.com/anoma/tiny-bip39.git?rev=bf0f6d8713589b83af7a917366ec31f5275c0e57#bf0f6d8713589b83af7a917366ec31f5275c0e57"
+dependencies = [
+ "anyhow",
+ "hmac 0.8.1",
+ "once_cell",
+ "pbkdf2 0.4.0",
+ "rand 0.7.3",
+ "rustc-hash",
+ "sha2 0.9.9",
+ "thiserror",
+ "unicode-normalization",
+ "wasm-bindgen",
+ "zeroize",
+]
+
[[package]]
name = "tiny-bip39"
version = "1.0.0"
@@ -6924,13 +6255,26 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "tiny-hderive"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01b874a4992538d4b2f4fbbac11b9419d685f4b39bdc3fed95b04e07bfd76040"
+dependencies = [
+ "base58 0.1.0",
+ "hmac 0.7.1",
+ "libsecp256k1 0.3.5",
+ "memzero",
+ "sha2 0.8.2",
+]
+
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
- "crunchy 0.2.2",
+ "crunchy",
]
[[package]]
@@ -6942,7 +6286,7 @@ dependencies = [
"ascii",
"chunked_transfer",
"httpdate",
- "log 0.4.17",
+ "log",
]
[[package]]
@@ -6966,12 +6310,12 @@ version = "1.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105"
dependencies = [
- "autocfg 1.1.0",
- "bytes 1.4.0",
+ "autocfg",
+ "bytes",
"libc",
- "mio 0.8.6",
+ "mio",
"num_cpus",
- "parking_lot 0.12.1",
+ "parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
@@ -6979,38 +6323,6 @@ dependencies = [
"windows-sys 0.48.0",
]
-[[package]]
-name = "tokio-codec"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.31",
- "tokio-io",
-]
-
-[[package]]
-name = "tokio-executor"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671"
-dependencies = [
- "crossbeam-utils 0.7.2",
- "futures 0.1.31",
-]
-
-[[package]]
-name = "tokio-io"
-version = "0.1.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.31",
- "log 0.4.17",
-]
-
[[package]]
name = "tokio-io-timeout"
version = "1.2.0"
@@ -7029,7 +6341,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -7042,25 +6354,6 @@ dependencies = [
"tokio",
]
-[[package]]
-name = "tokio-reactor"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351"
-dependencies = [
- "crossbeam-utils 0.7.2",
- "futures 0.1.31",
- "lazy_static",
- "log 0.4.17",
- "mio 0.6.23",
- "num_cpus",
- "parking_lot 0.9.0",
- "slab",
- "tokio-executor",
- "tokio-io",
- "tokio-sync",
-]
-
[[package]]
name = "tokio-rustls"
version = "0.22.0"
@@ -7094,30 +6387,6 @@ dependencies = [
"tokio",
]
-[[package]]
-name = "tokio-sync"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee"
-dependencies = [
- "fnv",
- "futures 0.1.31",
-]
-
-[[package]]
-name = "tokio-tcp"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.31",
- "iovec",
- "mio 0.6.23",
- "tokio-io",
- "tokio-reactor",
-]
-
[[package]]
name = "tokio-test"
version = "0.4.2"
@@ -7125,33 +6394,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53474327ae5e166530d17f2d956afcb4f8a004de581b3cae10f12006bc8163e3"
dependencies = [
"async-stream",
- "bytes 1.4.0",
+ "bytes",
"futures-core",
"tokio",
"tokio-stream",
]
-[[package]]
-name = "tokio-tls"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c"
-dependencies = [
- "futures 0.1.31",
- "native-tls",
- "tokio-io",
-]
-
[[package]]
name = "tokio-util"
version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507"
dependencies = [
- "bytes 1.4.0",
+ "bytes",
"futures-core",
"futures-sink",
- "log 0.4.17",
+ "log",
"pin-project-lite",
"tokio",
]
@@ -7162,7 +6420,7 @@ version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
dependencies = [
- "bytes 1.4.0",
+ "bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
@@ -7181,15 +6439,15 @@ dependencies = [
[[package]]
name = "toml_datetime"
-version = "0.6.1"
+version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
+checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f"
[[package]]
name = "toml_edit"
-version = "0.19.8"
+version = "0.19.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13"
+checksum = "92d964908cec0d030b812013af25a0e57fddfadb1e066ecc6681d86253129d4f"
dependencies = [
"indexmap",
"toml_datetime",
@@ -7206,15 +6464,15 @@ dependencies = [
"async-trait",
"axum",
"base64 0.13.1",
- "bytes 1.4.0",
+ "bytes",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
- "hyper 0.14.26",
+ "hyper",
"hyper-timeout",
- "percent-encoding 2.2.0",
+ "percent-encoding",
"pin-project",
"prost",
"prost-derive",
@@ -7268,31 +6526,13 @@ dependencies = [
[[package]]
name = "tower-abci"
version = "0.1.0"
-source = "git+https://github.com/heliaxdev/tower-abci.git?rev=79069a441cee7d9955a3d826d29656a0fb16115c#79069a441cee7d9955a3d826d29656a0fb16115c"
+source = "git+https://github.com/heliaxdev/tower-abci.git?rev=367d8d958b83c501ed2c09e9c4595f8bf75a0b01#367d8d958b83c501ed2c09e9c4595f8bf75a0b01"
dependencies = [
- "bytes 1.4.0",
- "futures 0.3.28",
+ "bytes",
+ "futures",
"pin-project",
"prost",
- "tendermint-proto 0.23.6",
- "tokio",
- "tokio-stream",
- "tokio-util 0.6.10",
- "tower",
- "tracing 0.1.30",
- "tracing-tower",
-]
-
-[[package]]
-name = "tower-abci"
-version = "0.1.0"
-source = "git+https://github.com/heliaxdev/tower-abci?rev=a31ce06533f5fbd943508676059d44de27395792#a31ce06533f5fbd943508676059d44de27395792"
-dependencies = [
- "bytes 1.4.0",
- "futures 0.3.28",
- "pin-project",
- "prost",
- "tendermint-proto 0.23.5",
+ "tendermint-proto",
"tokio",
"tokio-stream",
"tokio-util 0.6.10",
@@ -7340,7 +6580,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [
"cfg-if 1.0.0",
- "log 0.4.17",
+ "log",
"pin-project-lite",
"tracing-attributes 0.1.24",
"tracing-core 0.1.31",
@@ -7364,7 +6604,7 @@ checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
@@ -7421,7 +6661,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
dependencies = [
"lazy_static",
- "log 0.4.17",
+ "log",
"tracing-core 0.1.31",
]
@@ -7459,7 +6699,6 @@ dependencies = [
"serde 1.0.163",
"serde_json",
"sharded-slab",
- "smallvec 1.10.0",
"thread_local",
"tracing 0.1.37",
"tracing-core 0.1.31",
@@ -7472,7 +6711,7 @@ name = "tracing-tower"
version = "0.1.0"
source = "git+https://github.com/tokio-rs/tracing/?tag=tracing-0.1.30#df4ba17d857db8ba1b553f7b293ac8ba967a42f8"
dependencies = [
- "futures 0.3.28",
+ "futures",
"pin-project-lite",
"tower-layer",
"tower-make",
@@ -7481,12 +6720,6 @@ dependencies = [
"tracing-futures 0.2.5 (git+https://github.com/tokio-rs/tracing/?tag=tracing-0.1.30)",
]
-[[package]]
-name = "traitobject"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
-
[[package]]
name = "triomphe"
version = "0.1.8"
@@ -7507,23 +6740,17 @@ checksum = "8ada8297e8d70872fa9a551d93250a9f407beb9f37ef86494eb20012a2ff7c24"
dependencies = [
"base64 0.13.1",
"byteorder",
- "bytes 1.4.0",
+ "bytes",
"http",
"httparse",
"input_buffer",
- "log 0.4.17",
+ "log",
"rand 0.8.5",
- "sha-1 0.9.8",
- "url 2.3.1",
+ "sha-1",
+ "url",
"utf-8",
]
-[[package]]
-name = "typeable"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
-
[[package]]
name = "typenum"
version = "1.16.0"
@@ -7543,7 +6770,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52"
dependencies = [
"byteorder",
- "crunchy 0.2.2",
+ "crunchy",
"hex",
"static_assertions",
]
@@ -7554,22 +6781,13 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
-[[package]]
-name = "unicase"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
-dependencies = [
- "version_check 0.1.5",
-]
-
[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
- "version_check 0.9.4",
+ "version_check",
]
[[package]]
@@ -7607,12 +6825,12 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "universal-hash"
-version = "0.4.1"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05"
+checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5"
dependencies = [
- "generic-array 0.14.7",
- "subtle",
+ "crypto-common",
+ "subtle 2.4.1",
]
[[package]]
@@ -7621,17 +6839,6 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
-[[package]]
-name = "url"
-version = "1.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
-dependencies = [
- "idna 0.1.5",
- "matches",
- "percent-encoding 1.0.1",
-]
-
[[package]]
name = "url"
version = "2.3.1"
@@ -7639,8 +6846,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
dependencies = [
"form_urlencoded",
- "idna 0.3.0",
- "percent-encoding 2.2.0",
+ "idna",
+ "percent-encoding",
]
[[package]]
@@ -7663,9 +6870,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
[[package]]
name = "uuid"
-version = "1.3.2"
+version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2"
+checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2"
dependencies = [
"getrandom 0.2.9",
]
@@ -7678,13 +6885,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "value-bag"
-version = "1.0.0-alpha.9"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55"
-dependencies = [
- "ctor",
- "version_check 0.9.4",
-]
+checksum = "a4d330786735ea358f3bc09eea4caa098569c1c93f342d9aca0514915022fe7e"
[[package]]
name = "vcpkg"
@@ -7698,12 +6901,6 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
-[[package]]
-name = "version_check"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
-
[[package]]
name = "version_check"
version = "0.9.4"
@@ -7791,7 +6988,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
dependencies = [
- "log 0.4.17",
+ "log",
"try-lock",
]
@@ -7815,9 +7012,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
-version = "0.2.85"
+version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4"
+checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73"
dependencies = [
"cfg-if 1.0.0",
"wasm-bindgen-macro",
@@ -7825,24 +7022,24 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.85"
+version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822"
+checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb"
dependencies = [
"bumpalo",
- "log 0.4.17",
+ "log",
"once_cell",
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.35"
+version = "0.4.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "083abe15c5d88556b77bdf7aef403625be9e327ad37c62c4e4129af740168163"
+checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e"
dependencies = [
"cfg-if 1.0.0",
"js-sys",
@@ -7852,9 +7049,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.85"
+version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434"
+checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -7862,28 +7059,28 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.85"
+version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869"
+checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.85"
+version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb"
+checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93"
[[package]]
name = "wasm-encoder"
-version = "0.26.0"
+version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d05d0b6fcd0aeb98adf16e7975331b3c17222aa815148f5b976370ce589d80ef"
+checksum = "e77053dc709db790691d3732cfc458adc5acc881dec524965c608effdcd9c581"
dependencies = [
"leb128",
]
@@ -7911,7 +7108,7 @@ dependencies = [
"wasmer-types",
"wasmer-vm",
"wat",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -7937,7 +7134,7 @@ dependencies = [
"rkyv",
"serde 1.0.163",
"serde_bytes",
- "smallvec 1.10.0",
+ "smallvec",
"target-lexicon",
"thiserror",
"wasmer-types",
@@ -7958,7 +7155,7 @@ dependencies = [
"loupe",
"more-asserts",
"rayon",
- "smallvec 1.10.0",
+ "smallvec",
"target-lexicon",
"tracing 0.1.37",
"wasmer-compiler",
@@ -7979,7 +7176,7 @@ dependencies = [
"loupe",
"more-asserts",
"rayon",
- "smallvec 1.10.0",
+ "smallvec",
"wasmer-compiler",
"wasmer-types",
"wasmer-vm",
@@ -8061,7 +7258,7 @@ dependencies = [
"wasmer-engine",
"wasmer-types",
"wasmer-vm",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -8109,7 +7306,7 @@ dependencies = [
"serde 1.0.163",
"thiserror",
"wasmer-types",
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -8126,9 +7323,9 @@ checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a"
[[package]]
name = "wast"
-version = "57.0.0"
+version = "58.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6eb0f5ed17ac4421193c7477da05892c2edafd67f9639e3c11a82086416662dc"
+checksum = "372eecae2d10a5091c2005b32377d7ecd6feecdf2c05838056d02d8b4f07c429"
dependencies = [
"leb128",
"memchr",
@@ -8138,18 +7335,18 @@ dependencies = [
[[package]]
name = "wat"
-version = "1.0.63"
+version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab9ab0d87337c3be2bb6fc5cd331c4ba9fd6bcb4ee85048a0dd59ed9ecf92e53"
+checksum = "6d47446190e112ab1579ab40b3ad7e319d859d74e5134683f04e9f0747bf4173"
dependencies = [
"wast",
]
[[package]]
name = "web-sys"
-version = "0.3.62"
+version = "0.3.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721"
+checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -8193,47 +7390,6 @@ dependencies = [
"webpki 0.22.0",
]
-[[package]]
-name = "websocket"
-version = "0.26.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92aacab060eea423e4036820ddd28f3f9003b2c4d8048cbda985e5a14e18038d"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.31",
- "hyper 0.10.16",
- "native-tls",
- "rand 0.6.5",
- "tokio-codec",
- "tokio-io",
- "tokio-reactor",
- "tokio-tcp",
- "tokio-tls",
- "unicase 1.4.2",
- "url 1.7.2",
- "websocket-base",
-]
-
-[[package]]
-name = "websocket-base"
-version = "0.26.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49aec794b07318993d1db16156d5a9c750120597a5ee40c6b928d416186cb138"
-dependencies = [
- "base64 0.10.1",
- "bitflags",
- "byteorder",
- "bytes 0.4.12",
- "futures 0.1.31",
- "native-tls",
- "rand 0.6.5",
- "sha-1 0.8.2",
- "tokio-codec",
- "tokio-io",
- "tokio-tcp",
- "tokio-tls",
-]
-
[[package]]
name = "wepoll-ffi"
version = "0.1.2"
@@ -8254,12 +7410,6 @@ dependencies = [
"once_cell",
]
-[[package]]
-name = "winapi"
-version = "0.2.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
-
[[package]]
name = "winapi"
version = "0.3.9"
@@ -8270,12 +7420,6 @@ dependencies = [
"winapi-x86_64-pc-windows-gnu",
]
-[[package]]
-name = "winapi-build"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
-
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
@@ -8288,7 +7432,7 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
- "winapi 0.3.9",
+ "winapi",
]
[[package]]
@@ -8299,15 +7443,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
-version = "0.29.0"
+version = "0.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aac7fef12f4b59cd0a29339406cc9203ab44e440ddff6b3f5a41455349fa9cf3"
+checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b"
dependencies = [
- "windows_aarch64_msvc 0.29.0",
- "windows_i686_gnu 0.29.0",
- "windows_i686_msvc 0.29.0",
- "windows_x86_64_gnu 0.29.0",
- "windows_x86_64_msvc 0.29.0",
+ "windows-targets 0.42.2",
]
[[package]]
@@ -8394,12 +7534,6 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d027175d00b01e0cbeb97d6ab6ebe03b12330a35786cbaca5252b1c4bf5d9b"
-
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
@@ -8412,12 +7546,6 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
-[[package]]
-name = "windows_i686_gnu"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8793f59f7b8e8b01eda1a652b2697d87b93097198ae85f823b969ca5b89bba58"
-
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
@@ -8430,12 +7558,6 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
-[[package]]
-name = "windows_i686_msvc"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8602f6c418b67024be2996c512f5f995de3ba417f4c75af68401ab8756796ae4"
-
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
@@ -8448,12 +7570,6 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3d615f419543e0bd7d2b3323af0d86ff19cbc4f816e6453f36a2c2ce889c354"
-
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
@@ -8478,12 +7594,6 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11d95421d9ed3672c280884da53201a5c46b7b2765ca6faf34b0d71cf34a3561"
-
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
@@ -8511,26 +7621,7 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
dependencies = [
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "ws2_32-sys"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
-dependencies = [
- "winapi 0.2.8",
- "winapi-build",
-]
-
-[[package]]
-name = "wyz"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188"
-dependencies = [
- "tap",
+ "winapi",
]
[[package]]
@@ -8563,83 +7654,10 @@ dependencies = [
[[package]]
name = "zcash_encoding"
version = "0.0.0"
-source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c"
-dependencies = [
- "byteorder",
- "nonempty",
-]
-
-[[package]]
-name = "zcash_note_encryption"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33f84ae538f05a8ac74c82527f06b77045ed9553a0871d9db036166a4c344e3a"
-dependencies = [
- "chacha20",
- "chacha20poly1305",
- "rand_core 0.6.4",
- "subtle",
-]
-
-[[package]]
-name = "zcash_note_encryption"
-version = "0.1.0"
-source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c"
-dependencies = [
- "chacha20",
- "chacha20poly1305",
- "rand_core 0.6.4",
- "subtle",
-]
-
-[[package]]
-name = "zcash_primitives"
-version = "0.5.0"
-source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c"
+source = "git+https://github.com/zcash/librustzcash?rev=43c18d0#43c18d000fcbe45363b2d53585d5102841eff99e"
dependencies = [
- "aes",
- "bip0039",
- "bitvec 0.22.3",
- "blake2b_simd 1.0.1",
- "blake2s_simd 1.0.1",
- "bls12_381",
"byteorder",
- "chacha20poly1305",
- "equihash",
- "ff",
- "fpe",
- "group",
- "hex",
- "incrementalmerkletree",
- "jubjub",
- "lazy_static",
- "memuse",
"nonempty",
- "orchard",
- "rand 0.8.5",
- "rand_core 0.6.4",
- "sha2 0.9.9",
- "subtle",
- "zcash_encoding",
- "zcash_note_encryption 0.1.0 (git+https://github.com/zcash/librustzcash/?rev=2425a08)",
-]
-
-[[package]]
-name = "zcash_proofs"
-version = "0.5.0"
-source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c"
-dependencies = [
- "bellman",
- "blake2b_simd 1.0.1",
- "bls12_381",
- "byteorder",
- "directories",
- "ff",
- "group",
- "jubjub",
- "lazy_static",
- "rand_core 0.6.4",
- "zcash_primitives",
]
[[package]]
@@ -8659,7 +7677,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.16",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index 6c9c630d82..317dd335e7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,40 +21,129 @@ exclude = [
"wasm_for_tests",
]
+[workspace.package]
+authors = ["Heliax AG "]
+edition = "2021"
+documentation = "https://docs.namada.net/"
+homepage = "https://namada.net/"
+keywords = ["blockchain", "privacy", "crypto", "protocol", "network"]
+license = "GPL-3.0"
+readme = "README.md"
+repository = "https://github.com/anoma/namada"
+version = "0.17.5"
+
+[workspace.dependencies]
+ark-bls12-381 = {version = "0.3"}
+ark-serialize = {version = "0.3"}
+ark-std = "0.3.0"
+# branch = "bat/arse-merkle-tree"
+arse-merkle-tree = {package = "sparse-merkle-tree", git = "https://github.com/heliaxdev/sparse-merkle-tree", rev = "e086b235ed6e68929bf73f617dd61cd17b000a56", default-features = false, features = ["std", "borsh"]}
+assert_cmd = "1.0.7"
+assert_matches = "1.5.0"
+async-std = "1.11.0"
+async-trait = {version = "0.1.51"}
+base58 = "0.2.0"
+base64 = "0.13.0"
+bech32 = "0.8.0"
+bimap = {version = "0.6.2", features = ["serde"]}
+bit-set = "0.5.2"
+blake2b-rs = "0.2.0"
+byte-unit = "4.0.13"
+byteorder = "1.4.2"
+borsh = "0.9.0"
+chrono = {version = "0.4.22", default-features = false, features = ["clock", "std"]}
+circular-queue = "0.2.6"
+clap = {git = "https://github.com/clap-rs/clap/", tag = "v3.0.0-beta.2", default-features = false, features = ["std", "suggestions", "color", "cargo"]}
+clru = {git = "https://github.com/marmeladema/clru-rs.git", rev = "71ca566"}
+color-eyre = "0.5.10"
+concat-idents = "1.1.2"
+config = "0.11.0"
+data-encoding = "2.3.2"
+derivation-path = "0.2.0"
+derivative = "2.2.0"
+directories = "4.0.1"
+ed25519-consensus = "1.2.0"
+escargot = "0.5.7"
+expectrl = "0.7.0"
+eyre = "0.6.5"
+ferveo = {git = "https://github.com/anoma/ferveo", rev = "e5abd0acc938da90140351a65a26472eb495ce4d"}
+ferveo-common = {git = "https://github.com/anoma/ferveo", rev = "e5abd0acc938da90140351a65a26472eb495ce4d"}
+file-lock = "2.0.2"
+file-serve = "0.2.0"
+flate2 = "1.0.22"
+fs_extra = "1.2.0"
+futures = "0.3"
+git2 = "0.13.25"
+ibc-relayer = {git = "https://github.com/heliaxdev/hermes.git", rev = "a4ad1355fc0b05908881854aa27221cb2b878ac5", default-features = false}
+ibc-relayer-types = {git = "https://github.com/heliaxdev/hermes.git", rev = "a4ad1355fc0b05908881854aa27221cb2b878ac5", default-features = false}
+ics23 = "0.9.0"
+index-set = {git = "https://github.com/heliaxdev/index-set", tag = "v0.7.1", features = ["serialize-borsh", "serialize-serde"]}
+itertools = "0.10.0"
+libc = "0.2.97"
+libloading = "0.7.2"
+libsecp256k1 = {git = "https://github.com/heliaxdev/libsecp256k1", rev = "bbb3bd44a49db361f21d9db80f9a087c194c0ae9", default-features = false, features = ["std", "static-context"]}
+# branch = "murisi/namada-integration"
+masp_primitives = { git = "https://github.com/anoma/masp", rev = "cfea8c95d3f73077ca3e25380fd27e5b46e828fd" }
+masp_proofs = { git = "https://github.com/anoma/masp", rev = "cfea8c95d3f73077ca3e25380fd27e5b46e828fd", default-features = false, features = ["local-prover"] }
+num_cpus = "1.13.0"
+num-derive = "0.3.3"
+num-rational = "0.4.1"
+num-traits = "0.2.14"
+once_cell = "1.8.0"
+orion = "0.16.0"
+paste = "1.0.9"
+pretty_assertions = "0.7.2"
+proptest = "1.2.0"
+proptest-state-machine = "0.1.0"
+prost = "0.11.6"
+prost-types = "0.11.6"
+rand = {version = "0.8", default-features = false}
+rand_core = {version = "0.6", default-features = false}
+rayon = "=1.5.3"
+regex = "1.4.5"
+reqwest = "0.11.4"
+ripemd = "0.1"
+rlimit = "0.5.4"
+rocksdb = {version = "0.21.0", features = ['zstd', 'jemalloc'], default-features = false}
+rpassword = "5.0.1"
+rust_decimal = { version = "=1.26.1", features = ["borsh"] }
+rust_decimal_macros = "=1.26.1"
+serde = {version = "1.0.125", features = ["derive"]}
+serde_bytes = "0.11.5"
+serde_json = "1.0.62"
+sha2 = "0.9.3"
+signal-hook = "0.3.9"
+slip10_ed25519 = "0.1.3"
+# sysinfo with disabled multithread feature
+sysinfo = {version = "=0.21.1", default-features = false}
+tar = "0.4.37"
+tempfile = {version = "3.2.0"}
+tendermint-config = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "02b256829e80f8cfecf3fa0d625c2a76c79cd043"}
+test-log = {version = "0.2.7", default-features = false, features = ["trace"]}
+tiny-bip39 = {git = "https://github.com/anoma/tiny-bip39.git", rev = "bf0f6d8713589b83af7a917366ec31f5275c0e57"}
+tiny-hderive = "0.3.0"
+thiserror = "1.0.38"
+tokio = {version = "1.8.2", default-features = false}
+tokio-test = "0.4.2"
+toml = "0.5.8"
+tonic = "0.8.3"
+tonic-build = "0.8.4"
+tower = "0.4"
+# Also, using the same version of tendermint-rs as we do here.
+tower-abci = {git = "https://github.com/heliaxdev/tower-abci.git", rev = "367d8d958b83c501ed2c09e9c4595f8bf75a0b01"}
+tracing = "0.1.30"
+tracing-log = "0.1.2"
+tracing-subscriber = {version = "0.3.7", default-features = false, features = ["env-filter", "fmt"]}
+wasmparser = "0.83.0"
+winapi = "0.3.9"
+zeroize = {version = "1.5.5", features = ["zeroize_derive"]}
+
[patch.crates-io]
# TODO temp patch for , and more tba.
borsh = {git = "https://github.com/heliaxdev/borsh-rs.git", rev = "cd5223e5103c4f139e0c54cf8259b7ec5ec4073a"}
borsh-derive = {git = "https://github.com/heliaxdev/borsh-rs.git", rev = "cd5223e5103c4f139e0c54cf8259b7ec5ec4073a"}
borsh-derive-internal = {git = "https://github.com/heliaxdev/borsh-rs.git", rev = "cd5223e5103c4f139e0c54cf8259b7ec5ec4073a"}
borsh-schema-derive-internal = {git = "https://github.com/heliaxdev/borsh-rs.git", rev = "cd5223e5103c4f139e0c54cf8259b7ec5ec4073a"}
-# The following 3 crates patch a work-around for https://github.com/smol-rs/polling/issues/38 breaking namada tooling build with nightly 2022-05-20
-polling = {git = "https://github.com/heliaxdev/polling.git", rev = "02a655775282879459a3460e2646b60c005bca2c"}
-async-io = {git = "https://github.com/heliaxdev/async-io.git", rev = "9285dad39c9a37ecd0dbd498c5ce5b0e65b02489"}
-async-process = {git = "https://github.com/heliaxdev/async-process.git", rev = "e42c527e87d937da9e01aaeb563c0b948580dc89"}
-# borsh = {path = "../borsh-rs/borsh"}
-# borsh-derive = {path = "../borsh-rs/borsh-derive"}
-# borsh-derive-internal = {path = "../borsh-rs/borsh-derive-internal"}
-# borsh-schema-derive-internal = {path = "../borsh-rs/borsh-schema-derive-internal"}
-
-# patched to a commit on the `eth-bridge-integration+consensus-timeout` branch of our fork
-tendermint = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"}
-tendermint-config = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"}
-tendermint-proto = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"}
-tendermint-rpc = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"}
-tendermint-testgen = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"}
-tendermint-light-client-verifier = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"}
-
-# patched to a commit on the `eth-bridge-integration` branch of our fork
-ibc = {git = "https://github.com/heliaxdev/cosmos-ibc-rs.git", rev = "2d7edc16412b60cabf78163fe24a6264e11f77a9"}
-ibc-proto = {git = "https://github.com/heliaxdev/ibc-proto-rs.git", rev = "7e527b5b8c95d83351e93ceafc14ac853224283f"}
-ibc-relayer = {git = "https://github.com/heliaxdev/hermes.git", rev = "8e2ff3479edc0653f34b22df450d451eedd2c2ab"}
-ibc-relayer-types = {git = "https://github.com/heliaxdev/hermes.git", rev = "8e2ff3479edc0653f34b22df450d451eedd2c2ab"}
-
-# patched to a commit on the `eth-bridge-integration` branch of our fork
-tower-abci = {git = "https://github.com/heliaxdev/tower-abci.git", rev = "79069a441cee7d9955a3d826d29656a0fb16115c"}
-
-# patched to the yanked 1.2.0 until masp updates bitvec
-funty = { git = "https://github.com/bitvecto-rs/funty/", rev = "7ef0d890fbcd8b3def1635ac1a877fc298488446" }
[profile.release]
lto = true
diff --git a/Makefile b/Makefile
index d42b3fe3ec..6a63da44ec 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,13 @@
package = namada
+# Some env vars defaults if not specified
+NAMADA_E2E_USE_PREBUILT_BINARIES ?= true
+NAMADA_E2E_DEBUG ?= true
+RUST_BACKTRACE ?= 1
+
cargo := $(env) cargo
rustup := $(env) rustup
-debug-env := RUST_BACKTRACE=1 RUST_LOG=$(package)=debug
+debug-env := RUST_BACKTRACE=$(RUST_BACKTRACE) RUST_LOG=$(package)=debug
debug-cargo := $(env) $(debug-env) cargo
# Nightly build is currently used for rustfmt and clippy.
nightly := $(shell cat rust-nightly-version)
@@ -16,11 +21,24 @@ wasm_templates := wasm/tx_template wasm/vp_template
# TODO upgrade libp2p
audit-ignores += RUSTSEC-2021-0076
+# Workspace crates
+crates := namada_core
+crates += namada
+crates += namada_apps
+crates += namada_encoding_spec
+crates += namada_macros
+crates += namada_proof_of_stake
+crates += namada_test_utils
+crates += namada_tests
+crates += namada_tx_prelude
+crates += namada_vm_env
+crates += namada_vp_prelude
+
build:
$(cargo) build
build-test:
- $(cargo) +$(nightly) build --tests -Z unstable-options
+ $(cargo) build --tests
build-release:
NAMADA_DEV=false $(cargo) build --release --package namada_apps --manifest-path Cargo.toml
@@ -41,18 +59,13 @@ check:
make -C $(wasms_for_tests) check && \
$(foreach wasm,$(wasm_templates),$(check-wasm) && ) true
-check-abcipp:
- $(cargo) +$(nightly) check \
- --workspace \
- --exclude namada_tests \
- --all-targets \
- --no-default-features \
- --features "abcipp ibc-mocks-abcipp testing" \
- -Z unstable-options
-
check-mainnet:
$(cargo) check --workspace --features "mainnet"
+# Check that every crate can be built with default features
+check-crates:
+ $(foreach p,$(crates), echo "Checking $(p)"; cargo +$(nightly) check -Z unstable-options --tests -p $(p) && ) true
+
clippy-wasm = $(cargo) +$(nightly) clippy --manifest-path $(wasm)/Cargo.toml --all-targets -- -D warnings
clippy:
@@ -61,37 +74,21 @@ clippy:
make -C $(wasms_for_tests) clippy && \
$(foreach wasm,$(wasm_templates),$(clippy-wasm) && ) true
-clippy-abcipp:
- NAMADA_DEV=false $(cargo) +$(nightly) clippy --all-targets \
- --manifest-path ./apps/Cargo.toml \
- --no-default-features \
- --features "std testing abcipp" && \
- $(cargo) +$(nightly) clippy --all-targets \
- --manifest-path ./proof_of_stake/Cargo.toml \
- --features "testing" && \
- $(cargo) +$(nightly) clippy --all-targets \
- --manifest-path ./shared/Cargo.toml \
- --no-default-features \
- --features "testing wasm-runtime abcipp ibc-mocks-abcipp ferveo-tpke" && \
- $(cargo) +$(nightly) clippy \
- --all-targets \
- --manifest-path ./vm_env/Cargo.toml \
- --no-default-features && \
- 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
-install: tendermint
- NAMADA_DEV=false $(cargo) install --path ./apps --locked
-
tendermint:
./scripts/get_tendermint.sh
+install: cometbft
+ NAMADA_DEV=false $(cargo) install --path ./apps --locked
+
+cometbft:
+ ./scripts/get_cometbft.sh
+
run-ledger:
# runs the node
$(cargo) run --bin namadan -- ledger run
@@ -109,56 +106,29 @@ audit:
test: test-unit test-e2e test-wasm
-# NOTE: `unstable-options` are used twice for all unit tests - 1st to compile
-# with allowing to use unstable features in test, 2nd to run with `report-time`
test-unit-coverage:
$(cargo) +$(nightly) llvm-cov --output-dir target \
--features namada/testing \
--html \
- -Z unstable-options \
-- --skip e2e -Z unstable-options --report-time
+# NOTE: `TEST_FILTER` is prepended with `e2e::`. Since filters in `cargo test`
+# work with a substring search, TEST_FILTER only works if it contains a string
+# that directly follows `e2e::`, e.g. `TEST_FILTER=multitoken_tests` would run
+# all tests that start with `e2e::multitoken_tests`.
test-e2e:
- RUST_BACKTRACE=1 $(cargo) test e2e \
- -Z unstable-options \
- -- \
- --test-threads=1 \
- -Z unstable-options --report-time
-
-test-unit-abcipp:
- $(cargo) test \
- --manifest-path ./apps/Cargo.toml \
- --no-default-features \
- --features "testing std abcipp" \
- -Z unstable-options \
- $(TEST_FILTER) -- \
- -Z unstable-options --report-time && \
- $(cargo) test \
- --manifest-path \
- ./proof_of_stake/Cargo.toml \
- --features "testing" \
- -Z unstable-options \
- $(TEST_FILTER) -- \
- -Z unstable-options --report-time && \
- $(cargo) test \
- --manifest-path ./shared/Cargo.toml \
- --no-default-features \
- --features "testing wasm-runtime abcipp ibc-mocks-abcipp" \
- -Z unstable-options \
- $(TEST_FILTER) -- \
- -Z unstable-options --report-time && \
- $(cargo) test \
- --manifest-path ./vm_env/Cargo.toml \
- --no-default-features \
- --features "abcipp" \
- -Z unstable-options \
- $(TEST_FILTER) -- \
- -Z unstable-options --report-time
+ NAMADA_E2E_USE_PREBUILT_BINARIES=$(NAMADA_E2E_USE_PREBUILT_BINARIES) \
+ NAMADA_E2E_DEBUG=$(NAMADA_E2E_DEBUG) \
+ RUST_BACKTRACE=$(RUST_BACKTRACE) \
+ $(cargo) +$(nightly) test e2e::$(TEST_FILTER) \
+ -Z unstable-options \
+ -- \
+ --test-threads=1 \
+ -Z unstable-options --report-time
test-unit:
$(cargo) +$(nightly) test \
$(TEST_FILTER) \
- -Z unstable-options \
-- --skip e2e \
-Z unstable-options --report-time
@@ -166,14 +136,12 @@ test-unit-mainnet:
$(cargo) +$(nightly) test \
--features "mainnet" \
$(TEST_FILTER) \
- -Z unstable-options \
-- --skip e2e \
-Z unstable-options --report-time
test-unit-debug:
$(debug-cargo) +$(nightly) test \
$(TEST_FILTER) -- \
- -Z unstable-options \
-- --skip e2e \
--nocapture \
-Z unstable-options --report-time
@@ -181,7 +149,7 @@ test-unit-debug:
test-wasm:
make -C $(wasms) test
-test-wasm-template = $(cargo) test \
+test-wasm-template = $(cargo) +$(nightly) test \
--manifest-path $(wasm)/Cargo.toml \
-- \
-Z unstable-options --report-time
@@ -189,8 +157,7 @@ test-wasm-templates:
$(foreach wasm,$(wasm_templates),$(test-wasm-template) && ) true
test-debug:
- $(debug-cargo) test \
- -Z unstable-options \
+ $(debug-cargo) +$(nightly) test \
-- \
--nocapture \
-Z unstable-options --report-time
@@ -266,4 +233,4 @@ test-miri:
MIRIFLAGS="-Zmiri-disable-isolation" $(cargo) +$(nightly) miri test
-.PHONY : build check build-release clippy install run-ledger run-gossip reset-ledger test test-debug fmt watch clean build-doc doc build-wasm-scripts-docker debug-wasm-scripts-docker build-wasm-scripts debug-wasm-scripts clean-wasm-scripts dev-deps test-miri test-unit test-unit-abcipp clippy-abcipp
+.PHONY : build check build-release clippy install run-ledger run-gossip reset-ledger test test-debug fmt watch clean build-doc doc build-wasm-scripts-docker debug-wasm-scripts-docker build-wasm-scripts debug-wasm-scripts clean-wasm-scripts dev-deps test-miri test-unit
diff --git a/README.md b/README.md
index a3c45f712e..10b2230009 100644
--- a/README.md
+++ b/README.md
@@ -19,9 +19,7 @@ interaction with the protocol.
## 📓 Docs
-* user docs: built from [docs mdBook](./documentation/docs/)
* dev docs: built from [dev mdBook](./documentation/dev/)
-* specifications: built from [specs mdBook](./documentation/specs/)
## Warning
diff --git a/apps/Cargo.toml b/apps/Cargo.toml
index a6439fbb35..35b5483d7c 100644
--- a/apps/Cargo.toml
+++ b/apps/Cargo.toml
@@ -1,13 +1,17 @@
[package]
-authors = ["Heliax AG "]
-description = "Namada apps"
-edition = "2021"
-license = "GPL-3.0"
name = "namada_apps"
-readme = "../README.md"
+description = "Namada CLI apps"
resolver = "2"
-version = "0.16.0"
default-run = "namada"
+authors.workspace = true
+edition.workspace = true
+documentation.workspace = true
+homepage.workspace = true
+keywords.workspace = true
+license.workspace = true
+readme.workspace = true
+repository.workspace = true
+version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -45,125 +49,95 @@ mainnet = [
"namada/mainnet",
]
dev = ["namada/dev"]
-std = ["ed25519-consensus/std", "rand/std", "rand_core/std"]
+std = ["ed25519-consensus/std", "rand/std", "rand_core/std", "namada/std"]
# for integration tests and test utilies
testing = ["dev"]
-abcipp = [
- "namada/abcipp",
- "namada/tendermint-rpc-abcipp",
- "tendermint-abcipp",
- "tendermint-config-abcipp",
- "tendermint-proto-abcipp",
- "tendermint-rpc-abcipp",
- "tower-abci-abcipp",
-]
-
abciplus = [
"namada/abciplus",
"namada/tendermint-rpc",
- "tendermint",
- "tendermint-config",
- "tendermint-rpc",
- "tendermint-proto",
- "tower-abci",
]
[dependencies]
-namada = {path = "../shared", default-features = false, features = ["wasm-runtime", "ferveo-tpke", "masp-tx-gen"]}
-ark-serialize = "0.3.0"
-ark-std = "0.3.0"
-# branch = "bat/arse-merkle-tree"
-arse-merkle-tree = {package = "sparse-merkle-tree", git = "https://github.com/heliaxdev/sparse-merkle-tree", rev = "e086b235ed6e68929bf73f617dd61cd17b000a56", features = ["std", "borsh"]}
-assert_matches = "1.5.0"
-async-std = {version = "=1.11.0", features = ["unstable"]}
-async-trait = "0.1.51"
-base64 = "0.13.0"
-bech32 = "0.8.0"
-blake2b-rs = "0.2.0"
-borsh = "0.9.0"
-byte-unit = "4.0.13"
-byteorder = "1.4.2"
-# https://github.com/clap-rs/clap/issues/1037
-clap = {git = "https://github.com/clap-rs/clap/", tag = "v3.0.0-beta.2", default-features = false, features = ["std", "suggestions", "color", "cargo"]}
-color-eyre = "0.5.10"
-config = "0.11.0"
-data-encoding = "2.3.2"
-derivative = "2.2.0"
-ed25519-consensus = "1.2.0"
-ferveo = {git = "https://github.com/anoma/ferveo", rev = "e5abd0acc938da90140351a65a26472eb495ce4d"}
-ferveo-common = {git = "https://github.com/anoma/ferveo", rev = "e5abd0acc938da90140351a65a26472eb495ce4d"}
-eyre = "0.6.5"
-flate2 = "1.0.22"
-file-lock = "2.0.2"
-futures = "0.3"
-itertools = "0.10.1"
-libc = "0.2.97"
-libloading = "0.7.2"
-num-derive = "0.3.3"
-num-rational = "0.4.1"
-num-traits = "0.2.14"
-num_cpus = "1.13.0"
-once_cell = "1.8.0"
-orion = "0.16.0"
-prost = "0.11.6"
-prost-types = "0.11.6"
-rand = {version = "0.8", default-features = false}
-rand_core = {version = "0.6", default-features = false}
-rayon = "=1.5.3"
-regex = "1.4.5"
-reqwest = "0.11.4"
-rlimit = "0.5.4"
-rocksdb = {version = "0.21.0", features = ['zstd', 'jemalloc'], default-features = false}
-rpassword = "5.0.1"
-serde = {version = "1.0.125", features = ["derive"]}
-serde_bytes = "0.11.5"
-serde_json = {version = "1.0.62", features = ["raw_value"]}
-sha2 = "0.9.3"
-signal-hook = "0.3.9"
-# sysinfo with disabled multithread feature
-sysinfo = {version = "=0.21.1", default-features = false}
-tar = "0.4.37"
-# temporarily using fork work-around
-tendermint-abcipp = {package = "tendermint", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", optional = true}
-tendermint-config-abcipp = {package = "tendermint-config", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", optional = true}
-tendermint-proto-abcipp = {package = "tendermint-proto", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", optional = true}
-tendermint-rpc-abcipp = {package = "tendermint-rpc", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", features = ["http-client", "websocket-client"], optional = true}
-tendermint = {version = "0.23.6", optional = true}
-tendermint-config = {version = "0.23.6", optional = true}
-tendermint-proto = {version = "0.23.6", optional = true}
-tendermint-rpc = {version = "0.23.6", features = ["http-client", "websocket-client"], optional = true}
-thiserror = "1.0.38"
-tokio = {version = "1.8.2", features = ["full"]}
-toml = "0.5.8"
-tonic = "0.8.3"
-tower = "0.4"
-# Also, using the same version of tendermint-rs as we do here.
-# with a patch for https://github.com/penumbra-zone/tower-abci/issues/7.
-tower-abci-abcipp = {package = "tower-abci", git = "https://github.com/heliaxdev/tower-abci", rev = "a31ce06533f5fbd943508676059d44de27395792", optional = true}
-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", "json"]}
-websocket = "0.26.2"
-winapi = "0.3.9"
-#libmasp = { git = "https://github.com/anoma/masp", branch = "murisi/masp-incentive" }
-masp_primitives = { git = "https://github.com/anoma/masp", rev = "bee40fc465f6afbd10558d12fe96eb1742eee45c", features = ["transparent-inputs"] }
-masp_proofs = { git = "https://github.com/anoma/masp", rev = "bee40fc465f6afbd10558d12fe96eb1742eee45c", features = ["bundled-prover", "download-params"] }
-bimap = {version = "0.6.2", features = ["serde"]}
-rust_decimal = "=1.26.1"
-rust_decimal_macros = "=1.26.1"
-directories = "4.0.1"
+namada = {path = "../shared", features = ["ferveo-tpke", "masp-tx-gen", "multicore", "http-client"]}
+ark-serialize.workspace = true
+ark-std.workspace = true
+arse-merkle-tree = { workspace = true, features = ["blake2b"] }
+assert_matches.workspace = true
+async-std = {workspace = true, features = ["unstable"]}
+async-trait.workspace = true
+base64.workspace = true
+bech32.workspace = true
+bimap.workspace = true
+blake2b-rs.workspace = true
+borsh.workspace = true
+byte-unit.workspace = true
+byteorder.workspace = true
+clap.workspace = true
+color-eyre.workspace = true
+config.workspace = true
+data-encoding.workspace = true
+derivative.workspace = true
+directories.workspace = true
+ed25519-consensus.workspace = true
+eyre.workspace = true
+ferveo-common.workspace = true
+ferveo.workspace = true
+file-lock.workspace = true
+flate2.workspace = true
+futures.workspace = true
+itertools.workspace = true
+libc.workspace = true
+libloading.workspace = true
+masp_primitives = { workspace = true, features = ["transparent-inputs"] }
+masp_proofs = { workspace = true, features = ["bundled-prover", "download-params"] }
+num_cpus.workspace = true
+num-derive.workspace = true
+num-rational.workspace = true
+num-traits.workspace = true
+once_cell.workspace = true
+orion.workspace = true
+prost-types.workspace = true
+prost.workspace = true
+rand_core.workspace = true
+rand.workspace = true
+rayon.workspace = true
+regex.workspace = true
+reqwest.workspace = true
+ripemd.workspace = true
+rlimit.workspace = true
+rocksdb.workspace = true
+rpassword.workspace = true
+rust_decimal_macros.workspace = true
+rust_decimal.workspace = true
+serde_bytes.workspace = true
+serde_json = {workspace = true, features = ["raw_value"]}
+serde.workspace = true
+sha2.workspace = true
+signal-hook.workspace = true
+sysinfo.workspace = true
+tar.workspace = true
+tendermint-config.workspace = true
+thiserror.workspace = true
+tokio = {workspace = true, features = ["full"]}
+toml.workspace = true
+tonic.workspace = true
+tower-abci.workspace = true
+tower.workspace = true
+tracing-log.workspace = true
+tracing-subscriber = { workspace = true, features = ["std", "json", "ansi", "tracing-log"]}
+tracing.workspace = true
+winapi.workspace = true
+zeroize.workspace = true
[dev-dependencies]
namada = {path = "../shared", default-features = false, features = ["testing", "wasm-runtime"]}
namada_test_utils = {path = "../test_utils"}
-bit-set = "0.5.2"
-# A fork with state machime testing
-proptest = {git = "https://github.com/heliaxdev/proptest", rev = "8f1b4abe7ebd35c0781bf9a00a4ee59833ffa2a1"}
-tempfile = "3.2.0"
-test-log = {version = "0.2.7", default-features = false, features = ["trace"]}
-tokio-test = "0.4.2"
+bit-set.workspace = true
+proptest.workspace = true
+tempfile.workspace = true
+test-log.workspace = true
+tokio-test.workspace = true
[build-dependencies]
-git2 = "0.13.25"
+git2.workspace = true
diff --git a/apps/src/bin/namada-client/cli.rs b/apps/src/bin/namada-client/cli.rs
index 10316cb6bf..bf9921a527 100644
--- a/apps/src/bin/namada-client/cli.rs
+++ b/apps/src/bin/namada-client/cli.rs
@@ -253,6 +253,13 @@ pub async fn main() -> Result<()> {
rpc::query_delegations(&client, &mut ctx.wallet, args)
.await;
}
+ Sub::QueryFindValidator(QueryFindValidator(args)) => {
+ let client =
+ HttpClient::new(args.query.ledger_address.clone())
+ .unwrap();
+ let args = args.to_sdk(&mut ctx);
+ rpc::query_find_validator(&client, args).await;
+ }
Sub::QueryResult(QueryResult(args)) => {
wait_until_node_is_synched(&args.query.ledger_address)
.await;
@@ -319,6 +326,9 @@ pub async fn main() -> Result<()> {
Utils::PkToTmAddress(PkToTmAddress(args)) => {
utils::pk_to_tm_address(global_args, args)
}
+ Utils::DefaultBaseDir(DefaultBaseDir(args)) => {
+ utils::default_base_dir(global_args, args)
+ }
},
}
Ok(())
@@ -341,7 +351,7 @@ async fn wait_until_node_is_synched(ledger_address: &TendermintAddress) {
if is_at_least_height_one && !is_catching_up {
return;
} else {
- if try_count > MAX_TRIES {
+ if try_count == MAX_TRIES {
println!(
"Node is still catching up, wait for it to finish \
synching."
@@ -351,9 +361,9 @@ async fn wait_until_node_is_synched(ledger_address: &TendermintAddress) {
println!(
" Waiting for {} ({}/{} tries)...",
if is_at_least_height_one {
- "a first block"
- } else {
"node to sync"
+ } else {
+ "a first block"
},
try_count + 1,
MAX_TRIES
diff --git a/apps/src/bin/namada-node/cli.rs b/apps/src/bin/namada-node/cli.rs
index 240e81f90c..6499a34e9e 100644
--- a/apps/src/bin/namada-node/cli.rs
+++ b/apps/src/bin/namada-node/cli.rs
@@ -7,15 +7,11 @@ use namada_apps::node::ledger;
pub fn main() -> Result<()> {
let (cmd, mut ctx) = cli::namada_node_cli()?;
- if let Some(mode) = ctx.global_args.mode.clone() {
- ctx.config.ledger.tendermint.tendermint_mode = mode;
- }
match cmd {
cmds::NamadaNode::Ledger(sub) => match sub {
cmds::Ledger::Run(cmds::LedgerRun(args)) => {
let wasm_dir = ctx.wasm_dir();
sleep_until(args.start_time);
- ctx.config.ledger.tendermint.tx_index = args.tx_index;
ledger::run(ctx.config.ledger, wasm_dir);
}
cmds::Ledger::RunUntil(cmds::LedgerRunUntil(args)) => {
diff --git a/apps/src/bin/namada-wallet/cli.rs b/apps/src/bin/namada-wallet/cli.rs
index 2ec7a3a31c..685ed7f116 100644
--- a/apps/src/bin/namada-wallet/cli.rs
+++ b/apps/src/bin/namada-wallet/cli.rs
@@ -8,14 +8,14 @@ use color_eyre::eyre::Result;
use itertools::sorted;
use masp_primitives::zip32::ExtendedFullViewingKey;
use namada::ledger::masp::find_valid_diversifier;
-use namada::ledger::wallet::FindKeyError;
+use namada::ledger::wallet::{DecryptionError, FindKeyError};
use namada::types::key::*;
use namada::types::masp::{MaspValue, PaymentAddress};
use namada_apps::cli;
use namada_apps::cli::args::CliToSdk;
use namada_apps::cli::{args, cmds, Context};
use namada_apps::wallet::{
- read_and_confirm_pwd, CliWalletUtils, DecryptionError,
+ read_and_confirm_encryption_password, CliWalletUtils,
};
use rand_core::OsRng;
@@ -23,6 +23,9 @@ pub fn main() -> Result<()> {
let (cmd, mut ctx) = cli::namada_wallet_cli()?;
match cmd {
cmds::NamadaWallet::Key(sub) => match sub {
+ cmds::WalletKey::Restore(cmds::KeyRestore(args)) => {
+ key_and_address_restore(ctx, args)
+ }
cmds::WalletKey::Gen(cmds::KeyGen(args)) => {
key_and_address_gen(ctx, args)
}
@@ -36,6 +39,9 @@ pub fn main() -> Result<()> {
cmds::WalletAddress::Gen(cmds::AddressGen(args)) => {
key_and_address_gen(ctx, args)
}
+ cmds::WalletAddress::Restore(cmds::AddressRestore(args)) => {
+ key_and_address_restore(ctx, args)
+ }
cmds::WalletAddress::Find(cmds::AddressOrAliasFind(args)) => {
address_or_alias_find(ctx, args)
}
@@ -205,7 +211,7 @@ fn spending_key_gen(
) {
let mut wallet = ctx.wallet;
let alias = alias.to_lowercase();
- let password = read_and_confirm_pwd(unsafe_dont_encrypt);
+ let password = read_and_confirm_encryption_password(unsafe_dont_encrypt);
let (alias, _key) = wallet.gen_spending_key(alias, password, alias_force);
namada_apps::wallet::save(&wallet)
.unwrap_or_else(|err| eprintln!("{}", err));
@@ -273,7 +279,8 @@ fn address_key_add(
(alias, "viewing key")
}
MaspValue::ExtendedSpendingKey(spending_key) => {
- let password = read_and_confirm_pwd(unsafe_dont_encrypt);
+ let password =
+ read_and_confirm_encryption_password(unsafe_dont_encrypt);
let alias = ctx
.wallet
.encrypt_insert_spending_key(
@@ -307,6 +314,45 @@ fn address_key_add(
);
}
+/// Restore a keypair and an implicit address from the mnemonic code in the
+/// wallet.
+fn key_and_address_restore(
+ ctx: Context,
+ args::KeyAndAddressRestore {
+ scheme,
+ alias,
+ alias_force,
+ unsafe_dont_encrypt,
+ derivation_path,
+ }: args::KeyAndAddressRestore,
+) {
+ let mut wallet = ctx.wallet;
+ let encryption_password =
+ read_and_confirm_encryption_password(unsafe_dont_encrypt);
+ let (alias, _key) = wallet
+ .derive_key_from_user_mnemonic_code(
+ scheme,
+ alias,
+ alias_force,
+ derivation_path,
+ encryption_password,
+ )
+ .unwrap_or_else(|err| {
+ eprintln!("{}", err);
+ cli::safe_exit(1)
+ })
+ .unwrap_or_else(|| {
+ println!("No changes are persisted. Exiting.");
+ cli::safe_exit(0);
+ });
+ namada_apps::wallet::save(&wallet)
+ .unwrap_or_else(|err| eprintln!("{}", err));
+ println!(
+ "Successfully added a key and an address with alias: \"{}\"",
+ alias
+ );
+}
+
/// Generate a new keypair and derive implicit address from it and store them in
/// the wallet.
fn key_and_address_gen(
@@ -316,11 +362,31 @@ fn key_and_address_gen(
alias,
alias_force,
unsafe_dont_encrypt,
+ derivation_path,
}: args::KeyAndAddressGen,
) {
let mut wallet = ctx.wallet;
- let password = read_and_confirm_pwd(unsafe_dont_encrypt);
- let (alias, _key) = wallet.gen_key(scheme, alias, password, alias_force);
+ let encryption_password =
+ read_and_confirm_encryption_password(unsafe_dont_encrypt);
+ let mut rng = OsRng;
+ let derivation_path_and_mnemonic_rng =
+ derivation_path.map(|p| (p, &mut rng));
+ let (alias, _key) = wallet
+ .gen_key(
+ scheme,
+ alias,
+ alias_force,
+ encryption_password,
+ derivation_path_and_mnemonic_rng,
+ )
+ .unwrap_or_else(|err| {
+ eprintln!("{}", err);
+ cli::safe_exit(1);
+ })
+ .unwrap_or_else(|| {
+ println!("No changes are persisted. Exiting.");
+ cli::safe_exit(0);
+ });
namada_apps::wallet::save(&wallet)
.unwrap_or_else(|err| eprintln!("{}", err));
println!(
diff --git a/apps/src/lib/cli.rs b/apps/src/lib/cli.rs
index daecbf5eee..b3078037ff 100644
--- a/apps/src/lib/cli.rs
+++ b/apps/src/lib/cli.rs
@@ -175,6 +175,7 @@ pub mod cmds {
.subcommand(QueryBondedStake::def().display_order(3))
.subcommand(QuerySlashes::def().display_order(3))
.subcommand(QueryDelegations::def().display_order(3))
+ .subcommand(QueryFindValidator::def().display_order(3))
.subcommand(QueryResult::def().display_order(3))
.subcommand(QueryRawBytes::def().display_order(3))
.subcommand(QueryProposal::def().display_order(3))
@@ -213,6 +214,8 @@ pub mod cmds {
let query_slashes = Self::parse_with_ctx(matches, QuerySlashes);
let query_delegations =
Self::parse_with_ctx(matches, QueryDelegations);
+ let query_find_validator =
+ Self::parse_with_ctx(matches, QueryFindValidator);
let query_result = Self::parse_with_ctx(matches, QueryResult);
let query_raw_bytes = Self::parse_with_ctx(matches, QueryRawBytes);
let query_proposal = Self::parse_with_ctx(matches, QueryProposal);
@@ -242,6 +245,7 @@ pub mod cmds {
.or(query_bonded_stake)
.or(query_slashes)
.or(query_delegations)
+ .or(query_find_validator)
.or(query_result)
.or(query_raw_bytes)
.or(query_proposal)
@@ -306,6 +310,7 @@ pub mod cmds {
QueryCommissionRate(QueryCommissionRate),
QuerySlashes(QuerySlashes),
QueryDelegations(QueryDelegations),
+ QueryFindValidator(QueryFindValidator),
QueryRawBytes(QueryRawBytes),
QueryProposal(QueryProposal),
QueryProposalResult(QueryProposalResult),
@@ -359,6 +364,7 @@ pub mod cmds {
#[derive(Clone, Debug)]
#[allow(clippy::large_enum_variant)]
pub enum WalletKey {
+ Restore(KeyRestore),
Gen(KeyGen),
Find(KeyFind),
List(KeyList),
@@ -371,10 +377,11 @@ pub mod cmds {
fn parse(matches: &ArgMatches) -> Option {
matches.subcommand_matches(Self::CMD).and_then(|matches| {
let generate = SubCmd::parse(matches).map(Self::Gen);
+ let restore = SubCmd::parse(matches).map(Self::Restore);
let lookup = SubCmd::parse(matches).map(Self::Find);
let list = SubCmd::parse(matches).map(Self::List);
let export = SubCmd::parse(matches).map(Self::Export);
- generate.or(lookup).or(list).or(export)
+ generate.or(restore).or(lookup).or(list).or(export)
})
}
@@ -385,6 +392,7 @@ pub mod cmds {
look-up keys.",
)
.setting(AppSettings::SubcommandRequiredElseHelp)
+ .subcommand(KeyRestore::def())
.subcommand(KeyGen::def())
.subcommand(KeyFind::def())
.subcommand(KeyList::def())
@@ -392,6 +400,31 @@ pub mod cmds {
}
}
+ /// Restore a keypair and implicit address from the mnemonic code
+ #[derive(Clone, Debug)]
+ pub struct KeyRestore(pub args::KeyAndAddressRestore);
+
+ impl SubCmd for KeyRestore {
+ const CMD: &'static str = "restore";
+
+ fn parse(matches: &ArgMatches) -> Option {
+ matches
+ .subcommand_matches(Self::CMD)
+ .map(|matches| Self(args::KeyAndAddressRestore::parse(matches)))
+ }
+
+ fn def() -> App {
+ App::new(Self::CMD)
+ .about(
+ "Restores a keypair from the given mnemonic code and HD \
+ derivation path and derives the implicit address from \
+ its public key. Stores the keypair and the address with \
+ the given alias.",
+ )
+ .add_args::()
+ }
+ }
+
/// Generate a new keypair and an implicit address derived from it
#[derive(Clone, Debug)]
pub struct KeyGen(pub args::KeyAndAddressGen);
@@ -408,7 +441,7 @@ pub mod cmds {
fn def() -> App {
App::new(Self::CMD)
.about(
- "Generates a keypair with a given alias and derive the \
+ "Generates a keypair with a given alias and derives the \
implicit address from its public key. The address will \
be stored with the same alias.",
)
@@ -640,6 +673,7 @@ pub mod cmds {
#[derive(Clone, Debug)]
pub enum WalletAddress {
Gen(AddressGen),
+ Restore(AddressRestore),
Find(AddressOrAliasFind),
List(AddressList),
Add(AddressAdd),
@@ -651,10 +685,11 @@ pub mod cmds {
fn parse(matches: &ArgMatches) -> Option {
matches.subcommand_matches(Self::CMD).and_then(|matches| {
let gen = SubCmd::parse(matches).map(Self::Gen);
+ let restore = SubCmd::parse(matches).map(Self::Restore);
let find = SubCmd::parse(matches).map(Self::Find);
let list = SubCmd::parse(matches).map(Self::List);
let add = SubCmd::parse(matches).map(Self::Add);
- gen.or(find).or(list).or(add)
+ gen.or(restore).or(find).or(list).or(add)
})
}
@@ -666,6 +701,7 @@ pub mod cmds {
)
.setting(AppSettings::SubcommandRequiredElseHelp)
.subcommand(AddressGen::def())
+ .subcommand(AddressRestore::def())
.subcommand(AddressOrAliasFind::def())
.subcommand(AddressList::def())
.subcommand(AddressAdd::def())
@@ -688,7 +724,7 @@ pub mod cmds {
fn def() -> App {
App::new(Self::CMD)
.about(
- "Generates a keypair with a given alias and derive the \
+ "Generates a keypair with a given alias and derives the \
implicit address from its public key. The address will \
be stored with the same alias.",
)
@@ -696,6 +732,31 @@ pub mod cmds {
}
}
+ /// Restore a keypair and an implicit address from the mnemonic code
+ #[derive(Clone, Debug)]
+ pub struct AddressRestore(pub args::KeyAndAddressRestore);
+
+ impl SubCmd for AddressRestore {
+ const CMD: &'static str = "restore";
+
+ fn parse(matches: &ArgMatches) -> Option {
+ matches.subcommand_matches(Self::CMD).map(|matches| {
+ AddressRestore(args::KeyAndAddressRestore::parse(matches))
+ })
+ }
+
+ fn def() -> App {
+ App::new(Self::CMD)
+ .about(
+ "Restores a keypair from the given mnemonic code and HD \
+ derivation path and derives the implicit address from \
+ its public key. Stores the keypair and the address with \
+ the given alias.",
+ )
+ .add_args::()
+ }
+ }
+
/// Find an address by its alias
#[derive(Clone, Debug)]
pub struct AddressOrAliasFind(pub args::AddressOrAliasFind);
@@ -782,7 +843,6 @@ pub mod cmds {
// The `run` command is the default if no sub-command given
.or(Some(Self::Run(LedgerRun(args::LedgerRun {
start_time: None,
- tx_index: false,
}))))
})
}
@@ -1406,6 +1466,28 @@ pub mod cmds {
}
}
+ #[derive(Clone, Debug)]
+ pub struct QueryFindValidator(pub args::QueryFindValidator);
+
+ impl SubCmd for QueryFindValidator {
+ const CMD: &'static str = "find-validator";
+
+ fn parse(matches: &ArgMatches) -> Option
+ where
+ Self: Sized,
+ {
+ matches.subcommand_matches(Self::CMD).map(|matches| {
+ QueryFindValidator(args::QueryFindValidator::parse(matches))
+ })
+ }
+
+ fn def() -> App {
+ App::new(Self::CMD)
+ .about("Find a PoS validator by its Tendermint address.")
+ .add_args::>()
+ }
+ }
+
#[derive(Clone, Debug)]
pub struct QueryRawBytes(pub args::QueryRawBytes);
@@ -1506,6 +1588,7 @@ pub mod cmds {
InitNetwork(InitNetwork),
InitGenesisValidator(InitGenesisValidator),
PkToTmAddress(PkToTmAddress),
+ DefaultBaseDir(DefaultBaseDir),
}
impl SubCmd for Utils {
@@ -1522,11 +1605,14 @@ pub mod cmds {
SubCmd::parse(matches).map(Self::InitGenesisValidator);
let pk_to_tm_address =
SubCmd::parse(matches).map(Self::PkToTmAddress);
+ let default_base_dir =
+ SubCmd::parse(matches).map(Self::DefaultBaseDir);
join_network
.or(fetch_wasms)
.or(init_network)
.or(init_genesis)
.or(pk_to_tm_address)
+ .or(default_base_dir)
})
}
@@ -1538,6 +1624,7 @@ pub mod cmds {
.subcommand(InitNetwork::def())
.subcommand(InitGenesisValidator::def())
.subcommand(PkToTmAddress::def())
+ .subcommand(DefaultBaseDir::def())
.setting(AppSettings::SubcommandRequiredElseHelp)
}
}
@@ -1643,6 +1730,29 @@ pub mod cmds {
.add_args::()
}
}
+
+ #[derive(Clone, Debug)]
+ pub struct DefaultBaseDir(pub args::DefaultBaseDir);
+
+ impl SubCmd for DefaultBaseDir {
+ const CMD: &'static str = "default-base-dir";
+
+ fn parse(matches: &ArgMatches) -> Option {
+ matches
+ .subcommand_matches(Self::CMD)
+ .map(|matches| Self(args::DefaultBaseDir::parse(matches)))
+ }
+
+ fn def() -> App {
+ App::new(Self::CMD)
+ .about(
+ "Print the default base directory that would be used if \
+ --base-dir or NAMADA_BASE_DIR were not used to set the \
+ base directory.",
+ )
+ .add_args::()
+ }
+ }
}
pub mod args {
@@ -1666,7 +1776,7 @@ pub mod args {
use super::context::*;
use super::utils::*;
use super::{ArgGroup, ArgMatches};
- use crate::config::{self, Action, ActionAtHeight, TendermintMode};
+ use crate::config::{self, Action, ActionAtHeight};
use crate::facade::tendermint::Timeout;
use crate::facade::tendermint_config::net::Address as TendermintAddress;
@@ -1684,6 +1794,7 @@ pub mod args {
pub const TX_WITHDRAW_WASM: &str = "tx_withdraw.wasm";
pub const TX_CHANGE_COMMISSION_WASM: &str =
"tx_change_validator_commission.wasm";
+ pub const TX_UNJAIL_VALIDATOR_WASM: &str = "tx_unjail_validator.wasm";
pub const ADDRESS: Arg = arg("address");
pub const ALIAS_OPT: ArgOpt = ALIAS.opt();
@@ -1734,6 +1845,9 @@ pub mod args {
pub const GENESIS_VALIDATOR: ArgOpt =
arg("genesis-validator").opt();
pub const HALT_ACTION: ArgFlag = flag("halt");
+ pub const HD_WALLET_DERIVATION_PATH: Arg = arg("hd-path");
+ pub const HD_WALLET_DERIVATION_PATH_OPT: ArgOpt =
+ HD_WALLET_DERIVATION_PATH.opt();
pub const HISTORIC: ArgFlag = flag("historic");
pub const LEDGER_ADDRESS_ABOUT: &str =
"Address of a ledger node as \"{scheme}://{host}:{port}\". If the \
@@ -1749,7 +1863,6 @@ pub mod args {
pub const MASP_VALUE: Arg = arg("value");
pub const MAX_COMMISSION_RATE_CHANGE: Arg =
arg("max-commission-rate-change");
- pub const MODE: ArgOpt = arg_opt("mode");
pub const NET_ADDRESS: Arg = arg("net-address");
pub const NAMADA_START_TIME: ArgOpt = arg_opt("time");
pub const NO_CONVERSIONS: ArgFlag = flag("no-conversions");
@@ -1786,9 +1899,9 @@ pub mod args {
pub const STORAGE_KEY: Arg = arg("storage-key");
pub const SUB_PREFIX: ArgOpt = arg_opt("sub-prefix");
pub const SUSPEND_ACTION: ArgFlag = flag("suspend");
- pub const TENDERMINT_TX_INDEX: ArgFlag = flag("tx-index");
pub const TIMEOUT_HEIGHT: ArgOpt = arg_opt("timeout-height");
pub const TIMEOUT_SEC_OFFSET: ArgOpt = arg_opt("timeout-sec-offset");
+ pub const TM_ADDRESS: Arg = arg("tm-address");
pub const TOKEN_OPT: ArgOpt = TOKEN.opt();
pub const TOKEN: Arg = arg("token");
pub const TRANSFER_SOURCE: Arg = arg("source");
@@ -1816,7 +1929,6 @@ pub mod args {
pub chain_id: Option,
pub base_dir: PathBuf,
pub wasm_dir: Option,
- pub mode: Option,
}
impl Global {
@@ -1825,12 +1937,10 @@ pub mod args {
let chain_id = CHAIN_ID_OPT.parse(matches);
let base_dir = BASE_DIR.parse(matches);
let wasm_dir = WASM_DIR.parse(matches);
- let mode = MODE.parse(matches).map(TendermintMode::from);
Global {
chain_id,
base_dir,
wasm_dir,
- mode,
}
}
@@ -1854,27 +1964,18 @@ pub mod args {
`NAMADA_WASM_DIR` environment variable, but the argument \
takes precedence, if specified.",
))
- .arg(MODE.def().about(
- "The mode in which to run Namada. Options are \n\t * \
- Validator (default)\n\t * Full\n\t * Seed",
- ))
}
}
#[derive(Clone, Debug)]
pub struct LedgerRun {
pub start_time: Option,
- pub tx_index: bool,
}
impl Args for LedgerRun {
fn parse(matches: &ArgMatches) -> Self {
let start_time = NAMADA_START_TIME.parse(matches);
- let tx_index = TENDERMINT_TX_INDEX.parse(matches);
- Self {
- start_time,
- tx_index,
- }
+ Self { start_time }
}
fn def(app: App) -> App {
@@ -1886,11 +1987,6 @@ pub mod args {
equivalent:\n2023-01-20T12:12:12Z\n2023-01-20 \
12:12:12Z\n2023- 01-20T12: 12:12Z",
))
- .arg(
- TENDERMINT_TX_INDEX
- .def()
- .about("Enable Tendermint tx indexing."),
- )
}
}
@@ -2054,7 +2150,7 @@ pub mod args {
sub_prefix: self.sub_prefix,
amount: self.amount,
native_token: ctx.native_token.clone(),
- tx_code_path: ctx.read_wasm(self.tx_code_path),
+ tx_code_path: self.tx_code_path.to_path_buf(),
}
}
}
@@ -2109,7 +2205,7 @@ pub mod args {
channel_id: self.channel_id,
timeout_height: self.timeout_height,
timeout_sec_offset: self.timeout_sec_offset,
- tx_code_path: ctx.read_wasm(self.tx_code_path),
+ tx_code_path: self.tx_code_path.to_path_buf(),
}
}
}
@@ -2170,15 +2266,8 @@ pub mod args {
TxInitAccount:: {
tx: self.tx.to_sdk(ctx),
source: ctx.get(&self.source),
- vp_code: ctx.read_wasm(self.vp_code),
- vp_code_path: self
- .vp_code_path
- .as_path()
- .to_str()
- .unwrap()
- .to_string()
- .into_bytes(),
- tx_code_path: ctx.read_wasm(self.tx_code_path),
+ vp_code_path: self.vp_code_path.to_path_buf(),
+ tx_code_path: self.tx_code_path.to_path_buf(),
public_key: ctx.get_cached(&self.public_key),
}
}
@@ -2191,13 +2280,11 @@ pub mod args {
let vp_code_path = CODE_PATH_OPT
.parse(matches)
.unwrap_or_else(|| PathBuf::from(VP_USER_WASM));
- let vp_code = vp_code_path.clone();
let tx_code_path = PathBuf::from(TX_INIT_ACCOUNT_WASM);
let public_key = PUBLIC_KEY.parse(matches);
Self {
tx,
source,
- vp_code,
vp_code_path,
public_key,
tx_code_path,
@@ -2234,13 +2321,9 @@ pub mod args {
max_commission_rate_change: self.max_commission_rate_change,
validator_vp_code_path: self
.validator_vp_code_path
- .as_path()
- .to_str()
- .unwrap()
- .to_string()
- .into_bytes(),
+ .to_path_buf(),
unsafe_dont_encrypt: self.unsafe_dont_encrypt,
- tx_code_path: ctx.read_wasm(self.tx_code_path),
+ tx_code_path: self.tx_code_path.to_path_buf(),
}
}
}
@@ -2324,20 +2407,8 @@ pub mod args {
fn to_sdk(self, ctx: &mut Context) -> TxUpdateVp {
TxUpdateVp:: {
tx: self.tx.to_sdk(ctx),
- vp_code_path: self
- .vp_code_path
- .as_path()
- .to_str()
- .unwrap()
- .to_string()
- .into_bytes(),
- tx_code_path: self
- .tx_code_path
- .as_path()
- .to_str()
- .unwrap()
- .to_string()
- .into_bytes(),
+ vp_code_path: self.vp_code_path,
+ tx_code_path: self.tx_code_path,
addr: ctx.get(&self.addr),
}
}
@@ -2379,7 +2450,7 @@ pub mod args {
amount: self.amount,
source: self.source.map(|x| ctx.get(&x)),
native_token: ctx.native_token.clone(),
- tx_code_path: ctx.read_wasm(self.tx_code_path),
+ tx_code_path: self.tx_code_path.to_path_buf(),
}
}
}
@@ -2419,7 +2490,7 @@ pub mod args {
validator: ctx.get(&self.validator),
amount: self.amount,
source: self.source.map(|x| ctx.get(&x)),
- tx_code_path: ctx.read_wasm(self.tx_code_path),
+ tx_code_path: self.tx_code_path.to_path_buf(),
}
}
}
@@ -2466,7 +2537,7 @@ pub mod args {
/// Native token address
pub native_token: C::NativeAddress,
/// Path to the TX WASM code file
- pub tx_code_path: C::Data,
+ pub tx_code_path: PathBuf,
}
impl CliToSdk> for InitProposal {
@@ -2476,7 +2547,7 @@ pub mod args {
proposal_data: self.proposal_data,
offline: self.offline,
native_token: ctx.native_token.clone(),
- tx_code_path: ctx.read_wasm(self.tx_code_path),
+ tx_code_path: self.tx_code_path,
}
}
}
@@ -2527,7 +2598,7 @@ pub mod args {
/// The proposal file path
pub proposal_data: Option,
/// Path to the TX WASM code file
- pub tx_code_path: C::Data,
+ pub tx_code_path: PathBuf,
}
impl CliToSdk> for VoteProposal {
@@ -2538,7 +2609,7 @@ pub mod args {
vote: self.vote,
offline: self.offline,
proposal_data: self.proposal_data,
- tx_code_path: ctx.read_wasm(self.tx_code_path),
+ tx_code_path: self.tx_code_path.to_path_buf(),
proposal_pgf: self.proposal_pgf,
proposal_eth: self.proposal_eth,
}
@@ -2763,7 +2834,7 @@ pub mod args {
tx: self.tx.to_sdk(ctx),
validator: ctx.get(&self.validator),
source: self.source.map(|x| ctx.get(&x)),
- tx_code_path: ctx.read_wasm(self.tx_code_path),
+ tx_code_path: self.tx_code_path.to_path_buf(),
}
}
}
@@ -2995,7 +3066,7 @@ pub mod args {
tx: self.tx.to_sdk(ctx),
validator: ctx.get(&self.validator),
rate: self.rate,
- tx_code_path: ctx.read_wasm(self.tx_code_path),
+ tx_code_path: self.tx_code_path.to_path_buf(),
}
}
}
@@ -3015,7 +3086,7 @@ pub mod args {
}
fn def(app: App) -> App {
- app.add_args::>()
+ app.add_args::>()
.arg(VALIDATOR.def().about(
"The validator's address whose commission rate to change.",
))
@@ -3027,6 +3098,43 @@ pub mod args {
}
}
+ impl CliToSdk> for TxUnjailValidator {
+ fn to_sdk(self, ctx: &mut Context) -> TxUnjailValidator {
+ TxUnjailValidator {
+ tx: self.tx.to_sdk(ctx),
+ validator: ctx.get(&self.validator),
+ tx_code_path: self
+ .tx_code_path
+ .as_path()
+ .to_str()
+ .unwrap()
+ .to_string()
+ .into_bytes(),
+ }
+ }
+ }
+
+ impl Args for TxUnjailValidator {
+ fn parse(matches: &ArgMatches) -> Self {
+ let tx = Tx::parse(matches);
+ let validator = VALIDATOR.parse(matches);
+ let tx_code_path = PathBuf::from(TX_UNJAIL_VALIDATOR_WASM);
+ Self {
+ tx,
+ validator,
+ tx_code_path,
+ }
+ }
+
+ fn def(app: App) -> App {
+ app.add_args::>().arg(
+ VALIDATOR.def().about(
+ "The address of the jailed validator to re-activate.",
+ ),
+ )
+ }
+ }
+
impl CliToSdk> for QueryCommissionRate {
fn to_sdk(self, ctx: &mut Context) -> QueryCommissionRate {
QueryCommissionRate:: {
@@ -3111,6 +3219,31 @@ pub mod args {
}
}
+ impl Args for QueryFindValidator {
+ fn parse(matches: &ArgMatches) -> Self {
+ let query = Query::parse(matches);
+ let tm_addr = TM_ADDRESS.parse(matches);
+ Self { query, tm_addr }
+ }
+
+ fn def(app: App) -> App {
+ app.add_args::>().arg(
+ TM_ADDRESS
+ .def()
+ .about("The address of the validator in Tendermint."),
+ )
+ }
+ }
+
+ impl CliToSdk> for QueryFindValidator {
+ fn to_sdk(self, ctx: &mut Context) -> QueryFindValidator {
+ QueryFindValidator:: {
+ query: self.query.to_sdk(ctx),
+ tm_addr: self.tm_addr,
+ }
+ }
+ }
+
impl CliToSdk> for QueryRawBytes {
fn to_sdk(self, ctx: &mut Context) -> QueryRawBytes {
QueryRawBytes:: {
@@ -3165,7 +3298,7 @@ pub mod args {
gas_limit: self.gas_limit,
signing_key: self.signing_key.map(|x| ctx.get_cached(&x)),
signer: self.signer.map(|x| ctx.get(&x)),
- tx_code_path: ctx.read_wasm(self.tx_code_path),
+ tx_reveal_code_path: self.tx_reveal_code_path,
password: self.password,
expiration: self.expiration,
chain_id: self.chain_id,
@@ -3201,6 +3334,9 @@ pub mod args {
initialized, the alias will be the prefix of each new \
address joined with a number.",
))
+ .arg(WALLET_ALIAS_FORCE.def().about(
+ "Override the alias without confirmation if it already exists.",
+ ))
.arg(GAS_AMOUNT.def().about(
"The amount being paid for the inclusion of this transaction",
))
@@ -3251,7 +3387,7 @@ pub mod args {
let expiration = EXPIRATION_OPT.parse(matches);
let signing_key = SIGNING_KEY_OPT.parse(matches);
let signer = SIGNER.parse(matches);
- let tx_code_path = PathBuf::from(TX_REVEAL_PK);
+ let tx_reveal_code_path = PathBuf::from(TX_REVEAL_PK);
let chain_id = CHAIN_ID_OPT.parse(matches);
let password = None;
Self {
@@ -3268,7 +3404,7 @@ pub mod args {
expiration,
signing_key,
signer,
- tx_code_path,
+ tx_reveal_code_path,
password,
chain_id,
}
@@ -3318,6 +3454,9 @@ pub mod args {
.def()
.about("An alias to be associated with the new entry."),
)
+ .arg(ALIAS_FORCE.def().about(
+ "Override the alias without confirmation if it already exists.",
+ ))
.arg(
MASP_VALUE
.def()
@@ -3386,6 +3525,9 @@ pub mod args {
"An alias to be associated with the payment address.",
),
)
+ .arg(ALIAS_FORCE.def().about(
+ "Override the alias without confirmation if it already exists.",
+ ))
.arg(VIEWING_KEY.def().about("The viewing key."))
.arg(PIN.def().about(
"Require that the single transaction to this address be \
@@ -3394,17 +3536,65 @@ pub mod args {
}
}
+ impl Args for KeyAndAddressRestore {
+ fn parse(matches: &ArgMatches) -> Self {
+ let scheme = SCHEME.parse(matches);
+ let alias = ALIAS_OPT.parse(matches);
+ let alias_force = ALIAS_FORCE.parse(matches);
+ let unsafe_dont_encrypt = UNSAFE_DONT_ENCRYPT.parse(matches);
+ let derivation_path = HD_WALLET_DERIVATION_PATH_OPT.parse(matches);
+ Self {
+ scheme,
+ alias,
+ alias_force,
+ unsafe_dont_encrypt,
+ derivation_path,
+ }
+ }
+
+ fn def(app: App) -> App {
+ app.arg(SCHEME.def().about(
+ "The type of key that should be added. Argument must be \
+ either ed25519 or secp256k1. If none provided, the default \
+ key scheme is ed25519.",
+ ))
+ .arg(ALIAS_OPT.def().about(
+ "The key and address alias. If none provided, the alias will \
+ be the public key hash.",
+ ))
+ .arg(
+ ALIAS_FORCE
+ .def()
+ .about("Force overwrite the alias if it already exists."),
+ )
+ .arg(UNSAFE_DONT_ENCRYPT.def().about(
+ "UNSAFE: Do not encrypt the keypair. Do not use this for keys \
+ used in a live network.",
+ ))
+ .arg(HD_WALLET_DERIVATION_PATH_OPT.def().about(
+ "HD key derivation path. Use keyword `default` to refer to a \
+ scheme default path:\n- m/44'/60'/0'/0/0 for secp256k1 \
+ scheme\n- m/44'/877'/0'/0'/0' for ed25519 scheme.\nFor \
+ ed25519, all path indices will be promoted to hardened \
+ indexes. If none is specified, the scheme default path is \
+ used.",
+ ))
+ }
+ }
+
impl Args for KeyAndAddressGen {
fn parse(matches: &ArgMatches) -> Self {
let scheme = SCHEME.parse(matches);
let alias = ALIAS_OPT.parse(matches);
let alias_force = ALIAS_FORCE.parse(matches);
let unsafe_dont_encrypt = UNSAFE_DONT_ENCRYPT.parse(matches);
+ let derivation_path = HD_WALLET_DERIVATION_PATH_OPT.parse(matches);
Self {
scheme,
alias,
alias_force,
unsafe_dont_encrypt,
+ derivation_path,
}
}
@@ -3418,10 +3608,22 @@ pub mod args {
"The key and address alias. If none provided, the alias will \
be the public key hash.",
))
+ .arg(ALIAS_FORCE.def().about(
+ "Override the alias without confirmation if it already exists.",
+ ))
.arg(UNSAFE_DONT_ENCRYPT.def().about(
"UNSAFE: Do not encrypt the keypair. Do not use this for keys \
used in a live network.",
))
+ .arg(HD_WALLET_DERIVATION_PATH_OPT.def().about(
+ "Generate a new key and wallet using BIP39 mnemonic code and \
+ HD derivation path. Use keyword `default` to refer to a \
+ scheme default path:\n- m/44'/60'/0'/0/0 for secp256k1 \
+ scheme\n- m/44'/877'/0'/0'/0' for ed25519 scheme.\nFor \
+ ed25519, all path indices will be promoted to hardened \
+ indexes. If none specified, mnemonic code and derivation \
+ path are not used.",
+ ))
}
}
@@ -3586,6 +3788,9 @@ pub mod args {
.def()
.about("An alias to be associated with the address."),
)
+ .arg(ALIAS_FORCE.def().about(
+ "Override the alias without confirmation if it already exists.",
+ ))
.arg(
RAW_ADDRESS
.def()
@@ -3646,6 +3851,19 @@ pub mod args {
}
}
+ #[derive(Clone, Debug)]
+ pub struct DefaultBaseDir {}
+
+ impl Args for DefaultBaseDir {
+ fn parse(_matches: &ArgMatches) -> Self {
+ Self {}
+ }
+
+ fn def(app: App) -> App {
+ app
+ }
+ }
+
#[derive(Clone, Debug)]
pub struct FetchWasms {
pub chain_id: ChainId,
diff --git a/apps/src/lib/cli/context.rs b/apps/src/lib/cli/context.rs
index 42c1bb6c94..dbe1cec667 100644
--- a/apps/src/lib/cli/context.rs
+++ b/apps/src/lib/cli/context.rs
@@ -1,6 +1,6 @@
//! CLI input types can be used for command arguments
-use std::collections::HashSet;
+use std::collections::{HashMap, HashSet};
use std::env;
use std::marker::PhantomData;
use std::path::{Path, PathBuf};
@@ -89,7 +89,7 @@ impl Context {
let mut config = Config::load(
&global_args.base_dir,
&global_config.default_chain_id,
- global_args.mode.clone(),
+ None,
);
let chain_dir = global_args
@@ -194,10 +194,31 @@ impl Context {
wasm_loader::read_wasm_or_exit(self.wasm_dir(), file_name)
}
- /// Get address with vp type
+ /// Try to find an alias for a given address from the wallet. If not found,
+ /// formats the address into a string.
+ pub fn lookup_alias(&self, addr: &Address) -> String {
+ match self.wallet.find_alias(addr) {
+ Some(alias) => alias.to_string(),
+ None => addr.to_string(),
+ }
+ }
+
+ /// Get addresses with tokens VP type.
pub fn tokens(&self) -> HashSet {
self.wallet.get_addresses_with_vp_type(AddressVpType::Token)
}
+
+ /// Get addresses with tokens VP type associated with their aliases.
+ pub fn tokens_with_aliases(&self) -> HashMap {
+ self.wallet
+ .get_addresses_with_vp_type(AddressVpType::Token)
+ .into_iter()
+ .map(|addr| {
+ let alias = self.lookup_alias(&addr);
+ (addr, alias)
+ })
+ .collect()
+ }
}
/// Load global config from expected path in the `base_dir` or try to generate a
diff --git a/apps/src/lib/client/rpc.rs b/apps/src/lib/client/rpc.rs
index 109b0ffa2d..8aa466420e 100644
--- a/apps/src/lib/client/rpc.rs
+++ b/apps/src/lib/client/rpc.rs
@@ -16,8 +16,7 @@ use data_encoding::HEXLOWER;
use itertools::Either;
use masp_primitives::asset_type::AssetType;
use masp_primitives::merkle_tree::MerklePath;
-use masp_primitives::primitives::ViewingKey;
-use masp_primitives::sapling::Node;
+use masp_primitives::sapling::{Node, ViewingKey};
use masp_primitives::transaction::components::Amount;
use masp_primitives::zip32::ExtendedFullViewingKey;
use namada::core::types::transaction::governance::ProposalType;
@@ -33,7 +32,9 @@ use namada::ledger::pos::{
self, BondId, BondsAndUnbondsDetail, CommissionPair, PosParams, Slash,
};
use namada::ledger::queries::RPC;
-use namada::ledger::rpc::{query_epoch, TxResponse};
+use namada::ledger::rpc::{
+ enriched_bonds_and_unbonds, query_epoch, TxResponse,
+};
use namada::ledger::storage::ConversionState;
use namada::ledger::wallet::{AddressVpType, Wallet};
use namada::proof_of_stake::types::WeightedValidator;
@@ -78,8 +79,19 @@ pub async fn query_and_print_epoch<
/// Query the last committed block
pub async fn query_block(
client: &C,
-) -> crate::facade::tendermint_rpc::endpoint::block::Response {
- namada::ledger::rpc::query_block(client).await
+) {
+ let block = namada::ledger::rpc::query_block(client).await;
+ match block {
+ Some(block) => {
+ println!(
+ "Last committed block ID: {}, height: {}, time: {}",
+ block.hash, block.height, block.time
+ );
+ }
+ None => {
+ println!("No block has been committed yet.");
+ }
+ }
}
/// Query the results of the last committed block
@@ -107,7 +119,7 @@ pub async fn query_transfers<
|| Either::Right(wallet.get_addresses().into_values().collect()),
Either::Left,
);
- let _ = shielded.load();
+ let _ = shielded.load().await;
// Obtain the effects of all shielded and transparent transactions
let transfers = shielded
.query_tx_deltas(
@@ -304,7 +316,8 @@ pub async fn query_transparent_balance<
}
(None, Some(owner)) => {
for token in tokens {
- let prefix = token.to_db_key().into();
+ let prefix =
+ token::balance_key(&token, &owner.address().unwrap());
let balances =
query_storage_prefix::(client, &prefix)
.await;
@@ -319,7 +332,7 @@ pub async fn query_transparent_balance<
}
}
(Some(token), None) => {
- let prefix = token.to_db_key().into();
+ let prefix = token::balance_prefix(&token);
let balances =
query_storage_prefix::(client, &prefix).await;
if let Some(balances) = balances {
@@ -368,7 +381,7 @@ pub async fn query_pinned_balance<
.values()
.map(|fvk| ExtendedFullViewingKey::from(*fvk).fvk.vk)
.collect();
- let _ = shielded.load();
+ let _ = shielded.load().await;
// Print the token balances by payment address
for owner in owners {
let mut balance = Err(PinnedBalanceError::InvalidViewingKey);
@@ -693,14 +706,14 @@ pub async fn query_shielded_balance<
Some(viewing_key) => vec![viewing_key],
None => wallet.get_viewing_keys().values().copied().collect(),
};
- let _ = shielded.load();
+ let _ = shielded.load().await;
let fvks: Vec<_> = viewing_keys
.iter()
.map(|fvk| ExtendedFullViewingKey::from(*fvk).fvk.vk)
.collect();
shielded.fetch(client, &[], &fvks).await;
// Save the update state so that future fetches can be short-circuited
- let _ = shielded.save();
+ let _ = shielded.save().await;
// The epoch is required to identify timestamped tokens
let epoch = query_and_print_epoch(client).await;
// Map addresses to token names
@@ -1253,7 +1266,7 @@ pub async fn query_bonds(
_wallet: &mut Wallet,
args: args::QueryBonds,
) -> std::io::Result<()> {
- let _epoch = query_and_print_epoch(client).await;
+ let epoch = query_and_print_epoch(client).await;
let source = args.owner;
let validator = args.validator;
@@ -1261,21 +1274,10 @@ pub async fn query_bonds(
let stdout = io::stdout();
let mut w = stdout.lock();
- let bonds_and_unbonds: pos::types::BondsAndUnbondsDetails =
- unwrap_client_response::(
- RPC.vp()
- .pos()
- .bonds_and_unbonds(client, &source, &validator)
- .await,
- );
- let mut bonds_total: token::Amount = 0.into();
- let mut bonds_total_slashed: token::Amount = 0.into();
- let mut unbonds_total: token::Amount = 0.into();
- let mut unbonds_total_slashed: token::Amount = 0.into();
- let mut total_withdrawable: token::Amount = 0.into();
- for (bond_id, details) in bonds_and_unbonds {
- let mut total: token::Amount = 0.into();
- let mut total_slashed: token::Amount = 0.into();
+ let bonds_and_unbonds =
+ enriched_bonds_and_unbonds(client, epoch, &source, &validator).await;
+
+ for (bond_id, details) in &bonds_and_unbonds.data {
let bond_type = if bond_id.source == bond_id.validator {
format!("Self-bonds from {}", bond_id.validator)
} else {
@@ -1285,74 +1287,66 @@ pub async fn query_bonds(
)
};
writeln!(w, "{}:", bond_type)?;
- for bond in details.bonds {
+ for bond in &details.data.bonds {
writeln!(
w,
" Remaining active bond from epoch {}: Δ {}",
bond.start, bond.amount
)?;
- total += bond.amount;
- total_slashed += bond.slashed_amount.unwrap_or_default();
}
- if total_slashed != token::Amount::default() {
+ if details.bonds_total_slashed != token::Amount::default() {
writeln!(
w,
"Active (slashed) bonds total: {}",
- total - total_slashed
+ details.bonds_total_active()
)?;
}
- writeln!(w, "Bonds total: {}", total)?;
+ writeln!(w, "Bonds total: {}", details.bonds_total)?;
writeln!(w)?;
- bonds_total += total;
- bonds_total_slashed += total_slashed;
- let mut withdrawable = token::Amount::default();
- if !details.unbonds.is_empty() {
- let mut total: token::Amount = 0.into();
- let mut total_slashed: token::Amount = 0.into();
+ if !details.data.unbonds.is_empty() {
let bond_type = if bond_id.source == bond_id.validator {
format!("Unbonded self-bonds from {}", bond_id.validator)
} else {
format!("Unbonded delegations from {}", bond_id.source)
};
writeln!(w, "{}:", bond_type)?;
- for unbond in details.unbonds {
- total += unbond.amount;
- total_slashed += unbond.slashed_amount.unwrap_or_default();
+ for unbond in &details.data.unbonds {
writeln!(
w,
" Withdrawable from epoch {} (active from {}): Δ {}",
unbond.withdraw, unbond.start, unbond.amount
)?;
}
- withdrawable = total - total_slashed;
- writeln!(w, "Unbonded total: {}", total)?;
-
- unbonds_total += total;
- unbonds_total_slashed += total_slashed;
- total_withdrawable += withdrawable;
+ writeln!(w, "Unbonded total: {}", details.unbonds_total)?;
}
- writeln!(w, "Withdrawable total: {}", withdrawable)?;
+ writeln!(w, "Withdrawable total: {}", details.total_withdrawable)?;
writeln!(w)?;
}
- if bonds_total != bonds_total_slashed {
+ if bonds_and_unbonds.bonds_total != bonds_and_unbonds.bonds_total_slashed {
writeln!(
w,
"All bonds total active: {}",
- bonds_total - bonds_total_slashed
+ bonds_and_unbonds.bonds_total_active()
)?;
}
- writeln!(w, "All bonds total: {}", bonds_total)?;
+ writeln!(w, "All bonds total: {}", bonds_and_unbonds.bonds_total)?;
- if unbonds_total != unbonds_total_slashed {
+ if bonds_and_unbonds.unbonds_total
+ != bonds_and_unbonds.unbonds_total_slashed
+ {
writeln!(
w,
"All unbonds total active: {}",
- unbonds_total - unbonds_total_slashed
+ bonds_and_unbonds.unbonds_total_active()
)?;
}
- writeln!(w, "All unbonds total: {}", unbonds_total)?;
- writeln!(w, "All unbonds total withdrawable: {}", total_withdrawable)?;
+ writeln!(w, "All unbonds total: {}", bonds_and_unbonds.unbonds_total)?;
+ writeln!(
+ w,
+ "All unbonds total withdrawable: {}",
+ bonds_and_unbonds.total_withdrawable
+ )?;
Ok(())
}
@@ -1502,9 +1496,7 @@ pub async fn query_slashes(
writeln!(
w,
"Slash epoch {}, type {}, rate {}",
- slash.epoch,
- slash.r#type,
- slash.r#type.get_slash_rate(¶ms)
+ slash.epoch, slash.r#type, slash.rate
)
.unwrap();
}
@@ -1562,6 +1554,30 @@ pub async fn query_delegations(
}
}
+pub async fn query_find_validator(
+ client: &C,
+ args: args::QueryFindValidator,
+) {
+ let args::QueryFindValidator { query: _, tm_addr } = args;
+ if tm_addr.len() != 40 {
+ eprintln!(
+ "Expected 40 characters in Tendermint address, got {}",
+ tm_addr.len()
+ );
+ cli::safe_exit(1);
+ }
+ let tm_addr = tm_addr.to_ascii_uppercase();
+ let validator = unwrap_client_response::(
+ RPC.vp().pos().validator_by_tm_addr(client, &tm_addr).await,
+ );
+ match validator {
+ Some(address) => println!("Found validator address \"{address}\"."),
+ None => {
+ println!("No validator with Tendermint address {tm_addr} found.")
+ }
+ }
+}
+
/// Dry run a transaction
pub async fn dry_run_tx(
client: &C,
diff --git a/apps/src/lib/client/signing.rs b/apps/src/lib/client/signing.rs
index eec89b4f80..c44da88f9b 100644
--- a/apps/src/lib/client/signing.rs
+++ b/apps/src/lib/client/signing.rs
@@ -5,10 +5,10 @@ use namada::ledger::rpc::TxBroadcastData;
use namada::ledger::signing::TxSigningKey;
use namada::ledger::tx;
use namada::ledger::wallet::{Wallet, WalletUtils};
+use namada::proof_of_stake::Epoch;
use namada::proto::Tx;
use namada::types::address::Address;
use namada::types::key::*;
-use namada::types::storage::Epoch;
use crate::cli::args;
@@ -77,8 +77,12 @@ pub async fn sign_tx<
/// Create a wrapper tx from a normal tx. Get the hash of the
/// wrapper and its payload which is needed for monitoring its
/// progress on chain.
-pub async fn sign_wrapper(
+pub async fn sign_wrapper<
+ C: namada::ledger::queries::Client + Sync,
+ U: WalletUtils,
+>(
client: &C,
+ wallet: &mut Wallet,
args: &args::Tx,
epoch: Epoch,
tx: Tx,
@@ -87,6 +91,7 @@ pub async fn sign_wrapper(
) -> TxBroadcastData {
namada::ledger::signing::sign_wrapper(
client,
+ wallet,
args,
epoch,
tx,
diff --git a/apps/src/lib/client/tx.rs b/apps/src/lib/client/tx.rs
index ce334adb41..237cef3c92 100644
--- a/apps/src/lib/client/tx.rs
+++ b/apps/src/lib/client/tx.rs
@@ -7,6 +7,7 @@ use std::path::PathBuf;
use async_std::io;
use async_std::io::prelude::WriteExt;
+use async_trait::async_trait;
use borsh::{BorshDeserialize, BorshSerialize};
use data_encoding::HEXLOWER_PERMISSIVE;
use masp_proofs::prover::LocalTxProver;
@@ -14,30 +15,37 @@ use namada::ledger::governance::storage as gov_storage;
use namada::ledger::rpc::{TxBroadcastData, TxResponse};
use namada::ledger::signing::TxSigningKey;
use namada::ledger::wallet::{Wallet, WalletUtils};
-use namada::ledger::{masp, tx};
-use namada::proto::Tx;
+use namada::ledger::{masp, pos, tx};
+use namada::proof_of_stake::parameters::PosParams;
+use namada::proto::{Code, Data, Section, Tx};
use namada::types::address::Address;
use namada::types::governance::{
OfflineProposal, OfflineVote, Proposal, ProposalVote, VoteType,
};
+use namada::types::hash::Hash;
use namada::types::key::*;
use namada::types::storage::{Epoch, Key};
use namada::types::token;
use namada::types::transaction::governance::{
InitProposalData, ProposalType, VoteProposalData,
};
-use namada::types::transaction::InitValidator;
+use namada::types::transaction::{InitValidator, TxType};
use rust_decimal::Decimal;
-use tendermint_rpc::HttpClient;
+use sha2::{Digest as Sha2Digest, Sha256};
use super::rpc;
use crate::cli::context::WalletAddress;
use crate::cli::{args, safe_exit, Context};
use crate::client::rpc::query_wasm_code_hash;
use crate::client::signing::find_keypair;
+use crate::client::tx::tx::ProcessTxResponse;
+use crate::config::TendermintMode;
use crate::facade::tendermint_rpc::endpoint::broadcast::tx_sync::Response;
+use crate::facade::tendermint_rpc::HttpClient;
use crate::node::ledger::tendermint_node;
-use crate::wallet::{gen_validator_keys, read_and_confirm_pwd, CliWalletUtils};
+use crate::wallet::{
+ gen_validator_keys, read_and_confirm_encryption_password, CliWalletUtils,
+};
pub async fn submit_custom(
client: &C,
@@ -111,14 +119,18 @@ pub async fn submit_init_validator<
let consensus_key_alias = format!("{}-consensus-key", alias);
let account_key = account_key.unwrap_or_else(|| {
println!("Generating validator account key...");
- let password = read_and_confirm_pwd(unsafe_dont_encrypt);
+ let password =
+ read_and_confirm_encryption_password(unsafe_dont_encrypt);
ctx.wallet
.gen_key(
scheme,
Some(validator_key_alias.clone()),
- password,
tx_args.wallet_alias_force,
+ password,
+ None,
)
+ .expect("Key generation should not fail.")
+ .expect("No existing alias expected.")
.1
.ref_to()
});
@@ -133,15 +145,19 @@ pub async fn submit_init_validator<
})
.unwrap_or_else(|| {
println!("Generating consensus key...");
- let password = read_and_confirm_pwd(unsafe_dont_encrypt);
+ let password =
+ read_and_confirm_encryption_password(unsafe_dont_encrypt);
ctx.wallet
.gen_key(
// Note that TM only allows ed25519 for consensus key
SchemeType::Ed25519,
Some(consensus_key_alias.clone()),
- password,
tx_args.wallet_alias_force,
+ password,
+ None,
)
+ .expect("Key generation should not fail.")
+ .expect("No existing alias expected.")
.1
});
@@ -160,11 +176,12 @@ pub async fn submit_init_validator<
.expect("DKG sessions keys should have been created")
.public();
- let vp_code_path = String::from_utf8(validator_vp_code_path).unwrap();
- let validator_vp_code_hash =
- query_wasm_code_hash::(client, vp_code_path)
- .await
- .unwrap();
+ let validator_vp_code_hash = query_wasm_code_hash::(
+ client,
+ validator_vp_code_path.to_str().unwrap(),
+ )
+ .await
+ .unwrap();
// Validate the commission rate data
if commission_rate > Decimal::ONE || commission_rate < Decimal::ZERO {
@@ -192,6 +209,12 @@ pub async fn submit_init_validator<
.await
.unwrap();
+ let mut tx = Tx::new(TxType::Raw);
+ let extra = tx.add_section(Section::ExtraData(Code::from_hash(
+ validator_vp_code_hash,
+ )));
+ let extra_hash =
+ Hash(extra.hash(&mut Sha256::new()).finalize_reset().into());
let data = InitValidator {
account_key,
consensus_key: consensus_key.ref_to(),
@@ -199,15 +222,14 @@ pub async fn submit_init_validator<
dkg_key,
commission_rate,
max_commission_rate_change,
- validator_vp_code_hash,
+ validator_vp_code_hash: extra_hash,
};
let data = data.try_to_vec().expect("Encoding tx data shouldn't fail");
- let tx = Tx::new(
- tx_code_hash.to_vec(),
- Some(data),
- tx_args.chain_id.clone().unwrap(),
- tx_args.expiration,
- );
+ tx.header.chain_id = tx_args.chain_id.clone().unwrap();
+ tx.header.expiration = tx_args.expiration;
+ tx.set_data(Data::new(data));
+ tx.set_code(Code::from_hash(tx_code_hash));
+
let (mut ctx, result) = process_tx(
client,
ctx,
@@ -270,10 +292,26 @@ pub async fn submit_init_validator<
crate::wallet::save(&ctx.wallet)
.unwrap_or_else(|err| eprintln!("{}", err));
- let tendermint_home = ctx.config.ledger.tendermint_dir();
+ let tendermint_home = ctx.config.ledger.cometbft_dir();
tendermint_node::write_validator_key(&tendermint_home, &consensus_key);
tendermint_node::write_validator_state(tendermint_home);
+ // Write Namada config stuff or figure out how to do the above
+ // tendermint_node things two epochs in the future!!!
+ ctx.config.ledger.shell.tendermint_mode = TendermintMode::Validator;
+ ctx.config
+ .write(
+ &ctx.config.ledger.shell.base_dir,
+ &ctx.config.ledger.chain_id,
+ true,
+ )
+ .unwrap();
+
+ let key = pos::params_key();
+ let pos_params = rpc::query_storage_value::(client, &key)
+ .await
+ .expect("Pos parameter should be defined.");
+
println!();
println!(
"The validator's addresses and keys were stored in the wallet:"
@@ -285,6 +323,11 @@ pub async fn submit_init_validator<
"The ledger node has been setup to use this validator's address \
and consensus key."
);
+ println!(
+ "Your validator will be active in {} epochs. Be sure to restart \
+ your node for the changes to take effect!",
+ pos_params.pipeline_len
+ );
} else {
println!("Transaction dry run. No addresses have been saved.")
}
@@ -315,7 +358,7 @@ impl CLIShieldedUtils {
&& output_path.exists())
{
println!("MASP parameters not present, downloading...");
- masp_proofs::download_parameters()
+ masp_proofs::download_masp_parameters(None)
.expect("MASP parameters not present or downloadable");
println!("MASP parameter download complete, resuming execution...");
}
@@ -336,8 +379,9 @@ impl Default for CLIShieldedUtils {
}
}
+#[async_trait(?Send)]
impl masp::ShieldedUtils for CLIShieldedUtils {
- type C = tendermint_rpc::HttpClient;
+ type C = crate::facade::tendermint_rpc::HttpClient;
fn local_tx_prover(&self) -> LocalTxProver {
if let Ok(params_dir) = env::var(masp::ENV_VAR_MASP_PARAMS_DIR) {
@@ -354,7 +398,7 @@ impl masp::ShieldedUtils for CLIShieldedUtils {
/// Try to load the last saved shielded context from the given context
/// directory. If this fails, then leave the current context unchanged.
- fn load(self) -> std::io::Result> {
+ async fn load(self) -> std::io::Result> {
// Try to load shielded context from file
let mut ctx_file = File::open(self.context_dir.join(FILE_NAME))?;
let mut bytes = Vec::new();
@@ -367,7 +411,10 @@ impl masp::ShieldedUtils for CLIShieldedUtils {
}
/// Save this shielded context into its associated context directory
- fn save(&self, ctx: &masp::ShieldedContext) -> std::io::Result<()> {
+ async fn save(
+ &self,
+ ctx: &masp::ShieldedContext,
+ ) -> std::io::Result<()> {
// TODO: use mktemp crate?
let tmp_path = self.context_dir.join(TMP_FILE_NAME);
{
@@ -434,9 +481,9 @@ pub async fn submit_init_proposal(
serde_json::from_reader(file).expect("JSON was not well-formatted");
let signer = WalletAddress::new(proposal.clone().author.to_string());
- let governance_parameters = rpc::get_governance_parameters(client).await;
let current_epoch = rpc::query_and_print_epoch(client).await;
+ let governance_parameters = rpc::get_governance_parameters(client).await;
if proposal.voting_start_epoch <= current_epoch
|| proposal.voting_start_epoch.0
% governance_parameters.min_proposal_period
@@ -527,13 +574,10 @@ pub async fn submit_init_proposal(
safe_exit(1)
};
- let balance = rpc::get_token_balance(
- client,
- &args.native_token,
- &proposal.author,
- )
- .await
- .unwrap_or_default();
+ let balance =
+ rpc::get_token_balance(client, &ctx.native_token, &proposal.author)
+ .await
+ .unwrap_or_default();
if balance
< token::Amount::from(governance_parameters.min_proposal_fund)
{
@@ -551,18 +595,17 @@ pub async fn submit_init_proposal(
safe_exit(1);
}
+ let mut tx = Tx::new(TxType::Raw);
let data = init_proposal_data
.try_to_vec()
.expect("Encoding proposal data shouldn't fail");
let tx_code_hash = query_wasm_code_hash(client, args::TX_INIT_PROPOSAL)
.await
.unwrap();
- let tx = Tx::new(
- tx_code_hash.to_vec(),
- Some(data),
- ctx.config.ledger.chain_id.clone(),
- args.tx.expiration,
- );
+ tx.header.chain_id = ctx.config.ledger.chain_id.clone();
+ tx.header.expiration = args.tx.expiration;
+ tx.set_data(Data::new(data));
+ tx.set_code(Code::from_hash(tx_code_hash));
process_tx::(
client,
@@ -599,7 +642,7 @@ pub async fn submit_vote_proposal(
"yay" => {
if let Some(pgf) = args.proposal_pgf {
let splits = pgf.trim().split_ascii_whitespace();
- let address_iter = splits.clone().into_iter().step_by(2);
+ let address_iter = splits.clone().step_by(2);
let cap_iter = splits.into_iter().skip(1).step_by(2);
let mut set = HashSet::new();
for (address, cap) in
@@ -806,8 +849,18 @@ pub async fn submit_vote_proposal(
let data = tx_data
.try_to_vec()
.expect("Encoding proposal data shouldn't fail");
- let tx_code = args.tx_code_path;
- let tx = Tx::new(tx_code, Some(data), chain_id, expiration);
+
+ let tx_code_hash = query_wasm_code_hash(
+ client,
+ args.tx_code_path.to_str().unwrap(),
+ )
+ .await
+ .unwrap();
+ let mut tx = Tx::new(TxType::Raw);
+ tx.header.chain_id = chain_id;
+ tx.header.expiration = expiration;
+ tx.set_data(Data::new(data));
+ tx.set_code(Code::from_hash(tx_code_hash));
process_tx::(
client,
@@ -873,7 +926,7 @@ pub async fn submit_reveal_pk_aux(
ctx: &mut Context,
public_key: &common::PublicKey,
args: &args::Tx,
-) -> Result<(), tx::Error> {
+) -> Result {
let args = args::Tx {
chain_id: args
.clone()
@@ -990,6 +1043,20 @@ pub async fn submit_validator_commission_change<
.await
}
+pub async fn submit_unjail_validator<
+ C: namada::ledger::queries::Client + Sync,
+>(
+ client: &C,
+ mut ctx: Context,
+ mut args: args::TxUnjailValidator,
+) -> Result<(), tx::Error> {
+ args.tx.chain_id = args
+ .tx
+ .chain_id
+ .or_else(|| Some(ctx.config.ledger.chain_id.clone()));
+ tx::submit_unjail_validator::(client, &mut ctx.wallet, args).await
+}
+
/// Submit transaction and wait for result. Returns a list of addresses
/// initialized in the transaction if any. In dry run, this is always empty.
async fn process_tx(
@@ -1001,7 +1068,10 @@ async fn process_tx(
#[cfg(not(feature = "mainnet"))] requires_pow: bool,
) -> Result<(Context, Vec), tx::Error> {
let args = args::Tx {
- chain_id: args.clone().chain_id.or_else(|| Some(tx.chain_id.clone())),
+ chain_id: args
+ .clone()
+ .chain_id
+ .or_else(|| Some(tx.header.chain_id.clone())),
..args.clone()
};
let res: Vec = tx::process_tx::(
@@ -1013,7 +1083,8 @@ async fn process_tx(
#[cfg(not(feature = "mainnet"))]
requires_pow,
)
- .await?;
+ .await?
+ .initialized_accounts();
Ok((ctx, res))
}
diff --git a/apps/src/lib/client/utils.rs b/apps/src/lib/client/utils.rs
index 107c5465dd..ee63ecb1d2 100644
--- a/apps/src/lib/client/utils.rs
+++ b/apps/src/lib/client/utils.rs
@@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::env;
use std::fs::{self, File, OpenOptions};
use std::io::Write;
-use std::net::{IpAddr, Ipv4Addr, SocketAddr};
+use std::net::SocketAddr;
use std::path::{Path, PathBuf};
use std::str::FromStr;
@@ -27,11 +27,13 @@ use crate::config::genesis::genesis_config::{
self, GenesisConfig, HexString, ValidatorPreGenesisConfig,
};
use crate::config::global::GlobalConfig;
-use crate::config::{self, Config, TendermintMode};
+use crate::config::{self, get_default_namada_folder, Config, TendermintMode};
use crate::facade::tendermint::node::Id as TendermintNodeId;
use crate::facade::tendermint_config::net::Address as TendermintAddress;
use crate::node::ledger::tendermint_node;
-use crate::wallet::{pre_genesis, read_and_confirm_pwd, CliWalletUtils};
+use crate::wallet::{
+ pre_genesis, read_and_confirm_encryption_password, CliWalletUtils,
+};
use crate::wasm_loader;
pub const NET_ACCOUNTS_DIR: &str = "setup";
@@ -231,11 +233,7 @@ pub async fn join_network(
let base_dir = base_dir.clone();
let chain_id = chain_id.clone();
tokio::task::spawn_blocking(move || {
- let mut config = Config::load(
- &base_dir,
- &chain_id,
- global_args.mode.clone(),
- );
+ let mut config = Config::load(&base_dir, &chain_id, None);
config.wasm_dir = wasm_dir;
config.write(&base_dir, &chain_id, true).unwrap();
})
@@ -288,7 +286,7 @@ pub async fn join_network(
})
.clone();
- let tm_home_dir = chain_dir.join("tendermint");
+ let tm_home_dir = chain_dir.join("cometbft");
// Write consensus key to tendermint home
tendermint_node::write_validator_key(
@@ -321,27 +319,20 @@ pub async fn join_network(
let chain_id = chain_id.clone();
tokio::task::spawn_blocking(move || {
let mut config = Config::load(&base_dir, &chain_id, None);
+ config.ledger.shell.tendermint_mode = TendermintMode::Validator;
- config.ledger.tendermint.tendermint_mode =
- TendermintMode::Validator;
- // Validator node should turned off peer exchange reactor
- config.ledger.tendermint.p2p_pex = false;
// Remove self from persistent peers
- config
- .ledger
- .tendermint
- .p2p_persistent_peers
- .retain(|peer| {
- if let TendermintAddress::Tcp {
- peer_id: Some(peer_id),
- ..
- } = peer
- {
- node_id != *peer_id
- } else {
- true
- }
- });
+ config.ledger.cometbft.p2p.persistent_peers.retain(|peer| {
+ if let TendermintAddress::Tcp {
+ peer_id: Some(peer_id),
+ ..
+ } = peer
+ {
+ node_id != *peer_id
+ } else {
+ true
+ }
+ });
config.write(&base_dir, &chain_id, true).unwrap();
})
.await
@@ -454,7 +445,7 @@ pub fn init_network(
let validator_dir = accounts_dir.join(name);
let chain_dir = validator_dir.join(&accounts_temp_dir);
- let tm_home_dir = chain_dir.join("tendermint");
+ let tm_home_dir = chain_dir.join("cometbft");
// Find or generate tendermint node key
let node_pk = try_parse_public_key(
@@ -491,7 +482,7 @@ pub fn init_network(
config.address = Some(address.to_string());
// Generate the consensus, account and reward keys, unless they're
- // pre-defined.
+ // pre-defined. Do not use mnemonic code / HD derivation path.
let mut wallet = crate::wallet::load_or_new(&chain_dir);
let consensus_pk = try_parse_public_key(
@@ -501,13 +492,12 @@ pub fn init_network(
.unwrap_or_else(|| {
let alias = format!("{}-consensus-key", name);
println!("Generating validator {} consensus key...", name);
- let password = read_and_confirm_pwd(unsafe_dont_encrypt);
- let (_alias, keypair) = wallet.gen_key(
- SchemeType::Ed25519,
- Some(alias),
- password,
- true,
- );
+ let password =
+ read_and_confirm_encryption_password(unsafe_dont_encrypt);
+ let (_alias, keypair) = wallet
+ .gen_key(SchemeType::Ed25519, Some(alias), true, password, None)
+ .expect("Key generation should not fail.")
+ .expect("No existing alias expected.");
// Write consensus key for Tendermint
tendermint_node::write_validator_key(&tm_home_dir, &keypair);
@@ -522,13 +512,12 @@ pub fn init_network(
.unwrap_or_else(|| {
let alias = format!("{}-account-key", name);
println!("Generating validator {} account key...", name);
- let password = read_and_confirm_pwd(unsafe_dont_encrypt);
- let (_alias, keypair) = wallet.gen_key(
- SchemeType::Ed25519,
- Some(alias),
- password,
- true,
- );
+ let password =
+ read_and_confirm_encryption_password(unsafe_dont_encrypt);
+ let (_alias, keypair) = wallet
+ .gen_key(SchemeType::Ed25519, Some(alias), true, password, None)
+ .expect("Key generation should not fail.")
+ .expect("No existing alias expected.");
keypair.ref_to()
});
@@ -539,13 +528,12 @@ pub fn init_network(
.unwrap_or_else(|| {
let alias = format!("{}-protocol-key", name);
println!("Generating validator {} protocol signing key...", name);
- let password = read_and_confirm_pwd(unsafe_dont_encrypt);
- let (_alias, keypair) = wallet.gen_key(
- SchemeType::Ed25519,
- Some(alias),
- password,
- true,
- );
+ let password =
+ read_and_confirm_encryption_password(unsafe_dont_encrypt);
+ let (_alias, keypair) = wallet
+ .gen_key(SchemeType::Ed25519, Some(alias), true, password, None)
+ .expect("Key generation should not fail.")
+ .expect("No existing alias expected.");
keypair.ref_to()
});
@@ -593,7 +581,8 @@ pub fn init_network(
crate::wallet::save(&wallet).unwrap();
});
- // Create a wallet for all accounts other than validators
+ // Create a wallet for all accounts other than validators.
+ // Do not use mnemonic code / HD derivation path.
let mut wallet =
crate::wallet::load_or_new(&accounts_dir.join(NET_OTHER_ACCOUNTS_DIR));
if let Some(established) = &mut config.established {
@@ -625,13 +614,18 @@ pub fn init_network(
"Generating implicit account {} key and address ...",
name
);
- let password = read_and_confirm_pwd(unsafe_dont_encrypt);
- let (_alias, keypair) = wallet.gen_key(
- SchemeType::Ed25519,
- Some(name.clone()),
- password,
- true,
- );
+ let password =
+ read_and_confirm_encryption_password(unsafe_dont_encrypt);
+ let (_alias, keypair) = wallet
+ .gen_key(
+ SchemeType::Ed25519,
+ Some(name.clone()),
+ true,
+ password,
+ None,
+ )
+ .expect("Key generation should not fail.")
+ .expect("No existing alias expected.");
let public_key =
genesis_config::HexString(keypair.ref_to().to_string());
config.public_key = Some(public_key);
@@ -739,7 +733,7 @@ pub fn init_network(
// directories.
config.ledger.shell.base_dir = config::DEFAULT_BASE_DIR.into();
// Add a ledger P2P persistent peers
- config.ledger.tendermint.p2p_persistent_peers = persistent_peers
+ config.ledger.cometbft.p2p.persistent_peers = persistent_peers
.iter()
.enumerate()
.filter_map(|(index, peer)|
@@ -750,37 +744,39 @@ pub fn init_network(
None
})
.collect();
- config.ledger.tendermint.consensus_timeout_commit =
+
+ config.ledger.cometbft.consensus.timeout_commit =
consensus_timeout_commit;
- config.ledger.tendermint.p2p_allow_duplicate_ip =
- allow_duplicate_ip;
- config.ledger.tendermint.p2p_addr_book_strict = !localhost;
+ config.ledger.cometbft.p2p.allow_duplicate_ip = allow_duplicate_ip;
+ config.ledger.cometbft.p2p.addr_book_strict = !localhost;
// Clear the net address from the config and use it to set ports
let net_address = validator_config.net_address.take().unwrap();
+ let ip = SocketAddr::from_str(&net_address).unwrap().ip();
let first_port = SocketAddr::from_str(&net_address).unwrap().port();
if !localhost {
- config
- .ledger
- .tendermint
- .p2p_address
- .set_ip(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)));
+ config.ledger.cometbft.p2p.laddr = TendermintAddress::from_str(
+ &format!("0.0.0.0:{}", first_port),
+ )
+ .unwrap();
}
- config.ledger.tendermint.p2p_address.set_port(first_port);
+ config.ledger.cometbft.p2p.laddr =
+ TendermintAddress::from_str(&format!("{}:{}", ip, first_port))
+ .unwrap();
if !localhost {
- config
- .ledger
- .tendermint
- .rpc_address
- .set_ip(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)));
+ config.ledger.cometbft.rpc.laddr = TendermintAddress::from_str(
+ &format!("0.0.0.0:{}", first_port + 1),
+ )
+ .unwrap();
}
- config
- .ledger
- .tendermint
- .rpc_address
- .set_port(first_port + 1);
- config.ledger.shell.ledger_address.set_port(first_port + 2);
- // Validator node should turned off peer exchange reactor
- config.ledger.tendermint.p2p_pex = false;
+ config.ledger.cometbft.rpc.laddr = TendermintAddress::from_str(
+ &format!("{}:{}", ip, first_port + 1),
+ )
+ .unwrap();
+
+ config.ledger.cometbft.proxy_app = TendermintAddress::from_str(
+ &format!("{}:{}", ip, first_port + 2),
+ )
+ .unwrap();
config.write(&validator_dir, &chain_id, true).unwrap();
},
@@ -788,19 +784,15 @@ pub fn init_network(
// Update the ledger config persistent peers and save it
let mut config = Config::load(&global_args.base_dir, &chain_id, None);
- config.ledger.tendermint.p2p_persistent_peers = persistent_peers;
- config.ledger.tendermint.consensus_timeout_commit =
- consensus_timeout_commit;
- config.ledger.tendermint.p2p_allow_duplicate_ip = allow_duplicate_ip;
+ config.ledger.cometbft.p2p.persistent_peers = persistent_peers;
+ config.ledger.cometbft.consensus.timeout_commit = consensus_timeout_commit;
+ config.ledger.cometbft.p2p.allow_duplicate_ip = allow_duplicate_ip;
// Open P2P address
if !localhost {
- config
- .ledger
- .tendermint
- .p2p_address
- .set_ip(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)));
+ config.ledger.cometbft.p2p.laddr =
+ TendermintAddress::from_str("0.0.0.0:26656").unwrap();
}
- config.ledger.tendermint.p2p_addr_book_strict = !localhost;
+ config.ledger.cometbft.p2p.addr_book_strict = !localhost;
config.ledger.genesis_time = genesis.genesis_time.into();
config
.write(&global_args.base_dir, &chain_id, true)
@@ -877,13 +869,18 @@ fn init_established_account(
}
if config.public_key.is_none() {
println!("Generating established account {} key...", name.as_ref());
- let password = read_and_confirm_pwd(unsafe_dont_encrypt);
- let (_alias, keypair) = wallet.gen_key(
- SchemeType::Ed25519,
- Some(format!("{}-key", name.as_ref())),
- password,
- true,
- );
+ let password =
+ read_and_confirm_encryption_password(unsafe_dont_encrypt);
+ let (_alias, keypair) = wallet
+ .gen_key(
+ SchemeType::Ed25519,
+ Some(format!("{}-key", name.as_ref())),
+ true,
+ password,
+ None, // do not use mnemonic code / HD derivation path
+ )
+ .expect("Key generation should not fail.")
+ .expect("No existing alias expected.");
let public_key =
genesis_config::HexString(keypair.ref_to().to_string());
config.public_key = Some(public_key);
@@ -901,6 +898,18 @@ pub fn pk_to_tm_address(
println!("{tm_addr}");
}
+pub fn default_base_dir(
+ _global_args: args::Global,
+ _args: args::DefaultBaseDir,
+) {
+ println!(
+ "{}",
+ get_default_namada_folder().to_str().expect(
+ "expected a default namada folder to be possible to determine"
+ )
+ );
+}
+
/// Initialize genesis validator's address, consensus key and validator account
/// key and use it in the ledger's node.
pub fn init_genesis_validator(
diff --git a/apps/src/lib/config/genesis.rs b/apps/src/lib/config/genesis.rs
index 6b029b6407..527893057d 100644
--- a/apps/src/lib/config/genesis.rs
+++ b/apps/src/lib/config/genesis.rs
@@ -1,8 +1,6 @@
//! The parameters used for the chain's genesis
use std::collections::HashMap;
-#[cfg(not(feature = "dev"))]
-use std::path::Path;
use borsh::{BorshDeserialize, BorshSerialize};
use derivative::Derivative;
@@ -12,8 +10,6 @@ use namada::ledger::governance::parameters::GovParams;
use namada::ledger::parameters::EpochDuration;
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::*;
@@ -308,6 +304,9 @@ pub mod genesis_config {
// light client attack.
// XXX: u64 doesn't work with toml-rs!
pub light_client_attack_min_slash_rate: Decimal,
+ /// Number of epochs above and below (separately) the current epoch to
+ /// consider when doing cubic slashing
+ pub cubic_slashing_window_length: u64,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
@@ -653,6 +652,7 @@ pub mod genesis_config {
target_staked_ratio,
duplicate_vote_min_slash_rate,
light_client_attack_min_slash_rate,
+ cubic_slashing_window_length,
} = pos_params;
let pos_params = PosParams {
max_validator_slots,
@@ -665,6 +665,7 @@ pub mod genesis_config {
target_staked_ratio,
duplicate_vote_min_slash_rate,
light_client_attack_min_slash_rate,
+ cubic_slashing_window_length,
};
let mut genesis = Genesis {
@@ -880,14 +881,17 @@ pub struct Parameters {
pub wrapper_tx_fees: Option,
}
-#[cfg(not(feature = "dev"))]
-pub fn genesis(base_dir: impl AsRef, chain_id: &ChainId) -> Genesis {
+#[cfg(not(any(test, feature = "dev")))]
+pub fn genesis(
+ base_dir: impl AsRef,
+ chain_id: &namada::types::chain::ChainId,
+) -> Genesis {
let path = base_dir
.as_ref()
.join(format!("{}.toml", chain_id.as_str()));
genesis_config::read_genesis_config(path)
}
-#[cfg(feature = "dev")]
+#[cfg(any(test, feature = "dev"))]
pub fn genesis(num_validators: u64) -> Genesis {
use namada::types::address::{self};
use rust_decimal_macros::dec;
diff --git a/apps/src/lib/config/mod.rs b/apps/src/lib/config/mod.rs
index 2df988e298..4a6be155aa 100644
--- a/apps/src/lib/config/mod.rs
+++ b/apps/src/lib/config/mod.rs
@@ -6,9 +6,7 @@ pub mod utils;
use std::fs::{create_dir_all, File};
use std::io::Write;
-use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::path::{Path, PathBuf};
-use std::str::FromStr;
use directories::ProjectDirs;
use namada::types::chain::ChainId;
@@ -18,8 +16,9 @@ use serde::{Deserialize, Serialize};
use thiserror::Error;
use crate::cli;
-use crate::facade::tendermint::Timeout;
-use crate::facade::tendermint_config::net::Address as TendermintAddress;
+use crate::facade::tendermint_config::{
+ TendermintConfig, TxIndexConfig, TxIndexer,
+};
/// Base directory contains global config and chain directories.
pub const DEFAULT_BASE_DIR: &str = ".namada";
@@ -30,8 +29,8 @@ pub const DEFAULT_WASM_DIR: &str = "wasm";
pub const DEFAULT_WASM_CHECKSUMS_FILE: &str = "checksums.json";
/// Chain-specific Namada configuration. Nested in chain dirs.
pub const FILENAME: &str = "config.toml";
-/// Chain-specific Tendermint configuration. Nested in chain dirs.
-pub const TENDERMINT_DIR: &str = "tendermint";
+/// Chain-specific CometBFT configuration. Nested in chain dirs.
+pub const COMETBFT_DIR: &str = "cometbft";
/// Chain-specific Namada DB. Nested in chain dirs.
pub const DB_DIR: &str = "db";
@@ -95,13 +94,13 @@ pub struct Ledger {
pub genesis_time: Rfc3339String,
pub chain_id: ChainId,
pub shell: Shell,
- pub tendermint: Tendermint,
+ pub cometbft: TendermintConfig,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Shell {
pub base_dir: PathBuf,
- pub ledger_address: SocketAddr,
+ // pub ledger_address: SocketAddr,
/// RocksDB block cache maximum size in bytes.
/// When not set, defaults to 1/3 of the available memory.
pub block_cache_bytes: Option,
@@ -116,35 +115,12 @@ pub struct Shell {
pub storage_read_past_height_limit: Option,
/// Use the [`Ledger::db_dir()`] method to read the value.
db_dir: PathBuf,
- /// Use the [`Ledger::tendermint_dir()`] method to read the value.
- tendermint_dir: PathBuf,
+ /// Use the [`Ledger::cometbft_dir()`] method to read the value.
+ cometbft_dir: PathBuf,
/// An optional action to take when a given blockheight is reached.
pub action_at_height: Option,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize)]
-pub struct Tendermint {
- pub rpc_address: SocketAddr,
- pub p2p_address: SocketAddr,
- /// The persistent peers addresses must include node ID
- pub p2p_persistent_peers: Vec,
- /// Turns the peer exchange reactor on or off. Validator node will want the
- /// pex turned off.
- pub p2p_pex: bool,
- /// Toggle to disable guard against peers connecting from the same IP
- pub p2p_allow_duplicate_ip: bool,
- /// Set `true` for strict address routability rules
- /// Set `false` for private or local networks
- pub p2p_addr_book_strict: bool,
- /// How long we wait after committing a block, before starting on the new
- /// height
- pub consensus_timeout_commit: Timeout,
+ /// Specify if tendermint is started as validator, fullnode or seednode
pub tendermint_mode: TendermintMode,
- pub instrumentation_prometheus: bool,
- pub instrumentation_prometheus_listen_addr: SocketAddr,
- pub instrumentation_namespace: String,
- /// Toggle to enable tx indexing
- pub tx_index: bool,
}
impl Ledger {
@@ -153,47 +129,28 @@ impl Ledger {
chain_id: ChainId,
mode: TendermintMode,
) -> Self {
+ let mut tendermint_config =
+ TendermintConfig::parse_toml(DEFAULT_COMETBFT_CONFIG).unwrap();
+ tendermint_config.instrumentation.namespace = "namada_tm".to_string();
+ tendermint_config.tx_index = TxIndexConfig {
+ indexer: TxIndexer::Null,
+ };
Self {
genesis_time: Rfc3339String("1970-01-01T00:00:00Z".to_owned()),
chain_id,
shell: Shell {
base_dir: base_dir.as_ref().to_owned(),
- ledger_address: SocketAddr::new(
- IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
- 26658,
- ),
block_cache_bytes: None,
vp_wasm_compilation_cache_bytes: None,
tx_wasm_compilation_cache_bytes: None,
// Default corresponds to 1 hour of past blocks at 1 block/sec
storage_read_past_height_limit: Some(3600),
db_dir: DB_DIR.into(),
- tendermint_dir: TENDERMINT_DIR.into(),
+ cometbft_dir: COMETBFT_DIR.into(),
action_at_height: None,
- },
- tendermint: Tendermint {
- rpc_address: SocketAddr::new(
- IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
- 26657,
- ),
- p2p_address: SocketAddr::new(
- IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
- 26656,
- ),
- p2p_persistent_peers: vec![],
- p2p_pex: true,
- p2p_allow_duplicate_ip: false,
- p2p_addr_book_strict: true,
- consensus_timeout_commit: Timeout::from_str("1s").unwrap(),
tendermint_mode: mode,
- instrumentation_prometheus: false,
- instrumentation_prometheus_listen_addr: SocketAddr::new(
- IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
- 26661,
- ),
- instrumentation_namespace: "namadan_tm".to_string(),
- tx_index: false,
},
+ cometbft: tendermint_config,
}
}
@@ -208,8 +165,8 @@ impl Ledger {
}
/// Get the directory path to Tendermint
- pub fn tendermint_dir(&self) -> PathBuf {
- self.shell.tendermint_dir(&self.chain_id)
+ pub fn cometbft_dir(&self) -> PathBuf {
+ self.shell.cometbft_dir(&self.chain_id)
}
}
@@ -220,10 +177,10 @@ impl Shell {
}
/// Get the directory path to Tendermint
- pub fn tendermint_dir(&self, chain_id: &ChainId) -> PathBuf {
+ pub fn cometbft_dir(&self, chain_id: &ChainId) -> PathBuf {
self.base_dir
.join(chain_id.as_str())
- .join(&self.tendermint_dir)
+ .join(&self.cometbft_dir)
}
}
@@ -407,3 +364,490 @@ And this is correct
nested:Nested,
}
"#;
+
+pub const DEFAULT_COMETBFT_CONFIG: &str = r#"
+
+# This is a TOML config file.
+# For more information, see https://github.com/toml-lang/toml
+
+# NOTE: Any path below can be absolute (e.g. "/var/myawesomeapp/data") or
+# relative to the home directory (e.g. "data"). The home directory is
+# "$HOME/.cometbft" by default, but could be changed via $CMTHOME env variable
+# or --home cmd flag.
+
+#######################################################################
+### Main Base Config Options ###
+#######################################################################
+
+# TCP or UNIX socket address of the ABCI application,
+# or the name of an ABCI application compiled in with the CometBFT binary
+proxy_app = "tcp://127.0.0.1:26658"
+
+# A custom human readable name for this node
+moniker = "technodrome"
+
+# If this node is many blocks behind the tip of the chain, BlockSync
+# allows them to catchup quickly by downloading blocks in parallel
+# and verifying their commits
+#
+# Deprecated: this key will be removed and BlockSync will be enabled
+# unconditionally in the next major release.
+block_sync = true
+
+# Database backend: goleveldb | cleveldb | boltdb | rocksdb | badgerdb
+# * goleveldb (github.com/syndtr/goleveldb - most popular implementation)
+# - pure go
+# - stable
+# * cleveldb (uses levigo wrapper)
+# - fast
+# - requires gcc
+# - use cleveldb build tag (go build -tags cleveldb)
+# * boltdb (uses etcd's fork of bolt - github.com/etcd-io/bbolt)
+# - EXPERIMENTAL
+# - may be faster is some use-cases (random reads - indexer)
+# - use boltdb build tag (go build -tags boltdb)
+# * rocksdb (uses github.com/tecbot/gorocksdb)
+# - EXPERIMENTAL
+# - requires gcc
+# - use rocksdb build tag (go build -tags rocksdb)
+# * badgerdb (uses github.com/dgraph-io/badger)
+# - EXPERIMENTAL
+# - use badgerdb build tag (go build -tags badgerdb)
+db_backend = "goleveldb"
+
+# Database directory
+db_dir = "data"
+
+# Output level for logging, including package level options
+log_level = "info"
+
+# Output format: 'plain' (colored text) or 'json'
+log_format = "plain"
+
+##### additional base config options #####
+
+# Path to the JSON file containing the initial validator set and other meta data
+genesis_file = "config/genesis.json"
+
+# Path to the JSON file containing the private key to use as a validator in the consensus protocol
+priv_validator_key_file = "config/priv_validator_key.json"
+
+# Path to the JSON file containing the last sign state of a validator
+priv_validator_state_file = "data/priv_validator_state.json"
+
+# TCP or UNIX socket address for CometBFT to listen on for
+# connections from an external PrivValidator process
+priv_validator_laddr = ""
+
+# Path to the JSON file containing the private key to use for node authentication in the p2p protocol
+node_key_file = "config/node_key.json"
+
+# Mechanism to connect to the ABCI application: socket | grpc
+abci = "socket"
+
+# If true, query the ABCI app on connecting to a new peer
+# so the app can decide if we should keep the connection or not
+filter_peers = false
+
+
+#######################################################################
+### Advanced Configuration Options ###
+#######################################################################
+
+#######################################################
+### RPC Server Configuration Options ###
+#######################################################
+[rpc]
+
+# TCP or UNIX socket address for the RPC server to listen on
+laddr = "tcp://127.0.0.1:26657"
+
+# A list of origins a cross-domain request can be executed from
+# Default value '[]' disables cors support
+# Use '["*"]' to allow any origin
+cors_allowed_origins = []
+
+# A list of methods the client is allowed to use with cross-domain requests
+cors_allowed_methods = ["HEAD", "GET", "POST", ]
+
+# A list of non simple headers the client is allowed to use with cross-domain requests
+cors_allowed_headers = ["Origin", "Accept", "Content-Type", "X-Requested-With", "X-Server-Time", ]
+
+# TCP or UNIX socket address for the gRPC server to listen on
+# NOTE: This server only supports /broadcast_tx_commit
+grpc_laddr = ""
+
+# Maximum number of simultaneous connections.
+# Does not include RPC (HTTP&WebSocket) connections. See max_open_connections
+# If you want to accept a larger number than the default, make sure
+# you increase your OS limits.
+# 0 - unlimited.
+# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files}
+# 1024 - 40 - 10 - 50 = 924 = ~900
+grpc_max_open_connections = 900
+
+# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool
+unsafe = false
+
+# Maximum number of simultaneous connections (including WebSocket).
+# Does not include gRPC connections. See grpc_max_open_connections
+# If you want to accept a larger number than the default, make sure
+# you increase your OS limits.
+# 0 - unlimited.
+# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files}
+# 1024 - 40 - 10 - 50 = 924 = ~900
+max_open_connections = 900
+
+# Maximum number of unique clientIDs that can /subscribe
+# If you're using /broadcast_tx_commit, set to the estimated maximum number
+# of broadcast_tx_commit calls per block.
+max_subscription_clients = 100
+
+# Maximum number of unique queries a given client can /subscribe to
+# If you're using GRPC (or Local RPC client) and /broadcast_tx_commit, set to
+# the estimated # maximum number of broadcast_tx_commit calls per block.
+max_subscriptions_per_client = 5
+
+# Experimental parameter to specify the maximum number of events a node will
+# buffer, per subscription, before returning an error and closing the
+# subscription. Must be set to at least 100, but higher values will accommodate
+# higher event throughput rates (and will use more memory).
+experimental_subscription_buffer_size = 200
+
+# Experimental parameter to specify the maximum number of RPC responses that
+# can be buffered per WebSocket client. If clients cannot read from the
+# WebSocket endpoint fast enough, they will be disconnected, so increasing this
+# parameter may reduce the chances of them being disconnected (but will cause
+# the node to use more memory).
+#
+# Must be at least the same as "experimental_subscription_buffer_size",
+# otherwise connections could be dropped unnecessarily. This value should
+# ideally be somewhat higher than "experimental_subscription_buffer_size" to
+# accommodate non-subscription-related RPC responses.
+experimental_websocket_write_buffer_size = 200
+
+# If a WebSocket client cannot read fast enough, at present we may
+# silently drop events instead of generating an error or disconnecting the
+# client.
+#
+# Enabling this experimental parameter will cause the WebSocket connection to
+# be closed instead if it cannot read fast enough, allowing for greater
+# predictability in subscription behavior.
+experimental_close_on_slow_client = false
+
+# How long to wait for a tx to be committed during /broadcast_tx_commit.
+# WARNING: Using a value larger than 10s will result in increasing the
+# global HTTP write timeout, which applies to all connections and endpoints.
+# See https://github.com/tendermint/tendermint/issues/3435
+timeout_broadcast_tx_commit = "10s"
+
+# Maximum size of request body, in bytes
+max_body_bytes = 1000000
+
+# Maximum size of request header, in bytes
+max_header_bytes = 1048576
+
+# The path to a file containing certificate that is used to create the HTTPS server.
+# Might be either absolute path or path related to CometBFT's config directory.
+# If the certificate is signed by a certificate authority,
+# the certFile should be the concatenation of the server's certificate, any intermediates,
+# and the CA's certificate.
+# NOTE: both tls_cert_file and tls_key_file must be present for CometBFT to create HTTPS server.
+# Otherwise, HTTP server is run.
+tls_cert_file = ""
+
+# The path to a file containing matching private key that is used to create the HTTPS server.
+# Might be either absolute path or path related to CometBFT's config directory.
+# NOTE: both tls-cert-file and tls-key-file must be present for CometBFT to create HTTPS server.
+# Otherwise, HTTP server is run.
+tls_key_file = ""
+
+# pprof listen address (https://golang.org/pkg/net/http/pprof)
+pprof_laddr = ""
+
+#######################################################
+### P2P Configuration Options ###
+#######################################################
+[p2p]
+
+# Address to listen for incoming connections
+laddr = "tcp://0.0.0.0:26656"
+
+# Address to advertise to peers for them to dial
+# If empty, will use the same port as the laddr,
+# and will introspect on the listener or use UPnP
+# to figure out the address. ip and port are required
+# example: 159.89.10.97:26656
+external_address = ""
+
+# Comma separated list of seed nodes to connect to
+seeds = ""
+
+# Comma separated list of nodes to keep persistent connections to
+persistent_peers = ""
+
+# UPNP port forwarding
+upnp = false
+
+# Path to address book
+addr_book_file = "config/addrbook.json"
+
+# Set true for strict address routability rules
+# Set false for private or local networks
+addr_book_strict = true
+
+# Maximum number of inbound peers
+max_num_inbound_peers = 40
+
+# Maximum number of outbound peers to connect to, excluding persistent peers
+max_num_outbound_peers = 10
+
+# List of node IDs, to which a connection will be (re)established ignoring any existing limits
+unconditional_peer_ids = ""
+
+# Maximum pause when redialing a persistent peer (if zero, exponential backoff is used)
+persistent_peers_max_dial_period = "0s"
+
+# Time to wait before flushing messages out on the connection
+flush_throttle_timeout = "100ms"
+
+# Maximum size of a message packet payload, in bytes
+max_packet_msg_payload_size = 1024
+
+# Rate at which packets can be sent, in bytes/second
+send_rate = 5120000
+
+# Rate at which packets can be received, in bytes/second
+recv_rate = 5120000
+
+# Set true to enable the peer-exchange reactor
+pex = true
+
+# Seed mode, in which node constantly crawls the network and looks for
+# peers. If another node asks it for addresses, it responds and disconnects.
+#
+# Does not work if the peer-exchange reactor is disabled.
+seed_mode = false
+
+# Comma separated list of peer IDs to keep private (will not be gossiped to other peers)
+private_peer_ids = ""
+
+# Toggle to disable guard against peers connecting from the same ip.
+allow_duplicate_ip = false
+
+# Peer connection configuration.
+handshake_timeout = "20s"
+dial_timeout = "3s"
+
+#######################################################
+### Mempool Configuration Option ###
+#######################################################
+[mempool]
+
+# Mempool version to use:
+# 1) "v0" - (default) FIFO mempool.
+# 2) "v1" - prioritized mempool (deprecated; will be removed in the next release).
+version = "v0"
+
+recheck = true
+broadcast = true
+wal_dir = ""
+
+# Maximum number of transactions in the mempool
+size = 5000
+
+# Limit the total size of all txs in the mempool.
+# This only accounts for raw transactions (e.g. given 1MB transactions and
+# max_txs_bytes=5MB, mempool will only accept 5 transactions).
+max_txs_bytes = 1073741824
+
+# Size of the cache (used to filter transactions we saw earlier) in transactions
+cache_size = 10000
+
+# Do not remove invalid transactions from the cache (default: false)
+# Set to true if it's not possible for any invalid transaction to become valid
+# again in the future.
+keep-invalid-txs-in-cache = false
+
+# Maximum size of a single transaction.
+# NOTE: the max size of a tx transmitted over the network is {max_tx_bytes}.
+max_tx_bytes = 1048576
+
+# Maximum size of a batch of transactions to send to a peer
+# Including space needed by encoding (one varint per transaction).
+# XXX: Unused due to https://github.com/tendermint/tendermint/issues/5796
+max_batch_bytes = 0
+
+# ttl-duration, if non-zero, defines the maximum amount of time a transaction
+# can exist for in the mempool.
+#
+# Note, if ttl-num-blocks is also defined, a transaction will be removed if it
+# has existed in the mempool at least ttl-num-blocks number of blocks or if it's
+# insertion time into the mempool is beyond ttl-duration.
+ttl-duration = "0s"
+
+# ttl-num-blocks, if non-zero, defines the maximum number of blocks a transaction
+# can exist for in the mempool.
+#
+# Note, if ttl-duration is also defined, a transaction will be removed if it
+# has existed in the mempool at least ttl-num-blocks number of blocks or if
+# it's insertion time into the mempool is beyond ttl-duration.
+ttl-num-blocks = 0
+
+#######################################################
+### State Sync Configuration Options ###
+#######################################################
+[statesync]
+# State sync rapidly bootstraps a new node by discovering, fetching, and restoring a state machine
+# snapshot from peers instead of fetching and replaying historical blocks. Requires some peers in
+# the network to take and serve state machine snapshots. State sync is not attempted if the node
+# has any local state (LastBlockHeight > 0). The node will have a truncated block history,
+# starting from the height of the snapshot.
+enable = false
+
+# RPC servers (comma-separated) for light client verification of the synced state machine and
+# retrieval of state data for node bootstrapping. Also needs a trusted height and corresponding
+# header hash obtained from a trusted source, and a period during which validators can be trusted.
+#
+# For Cosmos SDK-based chains, trust_period should usually be about 2/3 of the unbonding time (~2
+# weeks) during which they can be financially punished (slashed) for misbehavior.
+rpc_servers = ""
+trust_height = 0
+trust_hash = ""
+trust_period = "168h0m0s"
+
+# Time to spend discovering snapshots before initiating a restore.
+discovery_time = "15s"
+
+# Temporary directory for state sync snapshot chunks, defaults to the OS tempdir (typically /tmp).
+# Will create a new, randomly named directory within, and remove it when done.
+temp_dir = ""
+
+# The timeout duration before re-requesting a chunk, possibly from a different
+# peer (default: 1 minute).
+chunk_request_timeout = "10s"
+
+# The number of concurrent chunk fetchers to run (default: 1).
+chunk_fetchers = "4"
+
+#######################################################
+### Block Sync Configuration Options ###
+#######################################################
+[blocksync]
+
+# Block Sync version to use:
+#
+# In v0.37, v1 and v2 of the block sync protocols were deprecated.
+# Please use v0 instead.
+#
+# 1) "v0" - the default block sync implementation
+version = "v0"
+
+#######################################################
+### Consensus Configuration Options ###
+#######################################################
+[consensus]
+
+wal_file = "data/cs.wal/wal"
+
+# How long we wait for a proposal block before prevoting nil
+timeout_propose = "3s"
+# How much timeout_propose increases with each round
+timeout_propose_delta = "500ms"
+# How long we wait after receiving +2/3 prevotes for “anything” (ie. not a single block or nil)
+timeout_prevote = "1s"
+# How much the timeout_prevote increases with each round
+timeout_prevote_delta = "500ms"
+# How long we wait after receiving +2/3 precommits for “anything” (ie. not a single block or nil)
+timeout_precommit = "1s"
+# How much the timeout_precommit increases with each round
+timeout_precommit_delta = "500ms"
+# How long we wait after committing a block, before starting on the new
+# height (this gives us a chance to receive some more precommits, even
+# though we already have +2/3).
+timeout_commit = "1s"
+
+# How many blocks to look back to check existence of the node's consensus votes before joining consensus
+# When non-zero, the node will panic upon restart
+# if the same consensus key was used to sign {double_sign_check_height} last blocks.
+# So, validators should stop the state machine, wait for some blocks, and then restart the state machine to avoid panic.
+double_sign_check_height = 0
+
+# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
+skip_timeout_commit = false
+
+# EmptyBlocks mode and possible interval between empty blocks
+create_empty_blocks = true
+create_empty_blocks_interval = "0s"
+
+# Reactor sleep duration parameters
+peer_gossip_sleep_duration = "100ms"
+peer_query_maj23_sleep_duration = "2s"
+
+#######################################################
+### Storage Configuration Options ###
+#######################################################
+[storage]
+
+# Set to true to discard ABCI responses from the state store, which can save a
+# considerable amount of disk space. Set to false to ensure ABCI responses are
+# persisted. ABCI responses are required for /block_results RPC queries, and to
+# reindex events in the command-line tool.
+discard_abci_responses = false
+
+#######################################################
+### Transaction Indexer Configuration Options ###
+#######################################################
+[tx_index]
+
+# What indexer to use for transactions
+#
+# The application will set which txs to index. In some cases a node operator will be able
+# to decide which txs to index based on configuration set in the application.
+#
+# Options:
+# 1) "null"
+# 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend).
+# - When "kv" is chosen "tx.height" and "tx.hash" will always be indexed.
+# 3) "psql" - the indexer services backed by PostgreSQL.
+# When "kv" or "psql" is chosen "tx.height" and "tx.hash" will always be indexed.
+indexer = "kv"
+
+# The PostgreSQL connection configuration, the connection format:
+# postgresql://:@:/?
+psql-conn = ""
+
+#######################################################
+### Instrumentation Configuration Options ###
+#######################################################
+[instrumentation]
+
+# When true, Prometheus metrics are served under /metrics on
+# PrometheusListenAddr.
+# Check out the documentation for the list of available metrics.
+prometheus = false
+
+# Address to listen for Prometheus collector(s) connections
+prometheus_listen_addr = ":26660"
+
+# Maximum number of simultaneous connections.
+# If you want to accept a larger number than the default, make sure
+# you increase your OS limits.
+# 0 - unlimited.
+max_open_connections = 3
+
+# Instrumentation namespace
+namespace = "cometbft"
+
+"#;
+
+#[cfg(test)]
+mod tests {
+ use super::DEFAULT_COMETBFT_CONFIG;
+ use crate::facade::tendermint_config::TendermintConfig;
+
+ #[test]
+ fn test_default_cometbft_config() {
+ assert!(TendermintConfig::parse_toml(DEFAULT_COMETBFT_CONFIG).is_ok());
+ }
+}
diff --git a/apps/src/lib/config/utils.rs b/apps/src/lib/config/utils.rs
index 19b2648d3b..ca038dcb42 100644
--- a/apps/src/lib/config/utils.rs
+++ b/apps/src/lib/config/utils.rs
@@ -1,11 +1,13 @@
//! Configuration utilities
+use std::net::{SocketAddr, ToSocketAddrs};
use std::str::FromStr;
use std::{cmp, env};
use itertools::Either;
use crate::cli;
+use crate::facade::tendermint_config::net::Address as TendermintAddress;
/// Find how many threads to use from an environment variable if it's set and
/// valid (>= 1). If the environment variable is invalid, exits the process with
@@ -45,6 +47,24 @@ fn num_of_threads_aux(
}
}
+// fixme: Handle this gracefully with either an Option or a Result. Ensure that
+// hostname resolution works.
+pub fn convert_tm_addr_to_socket_addr(
+ tm_addr: &TendermintAddress,
+) -> SocketAddr {
+ let tm_addr = tm_addr.clone();
+ match tm_addr {
+ TendermintAddress::Tcp {
+ peer_id: _,
+ host,
+ port,
+ } => (host, port).to_socket_addrs().unwrap().next().unwrap(),
+ TendermintAddress::Unix { path: _ } => {
+ panic!("Unix addresses aren't currently supported.")
+ }
+ }
+}
+
#[cfg(test)]
mod test {
use std::panic;
diff --git a/apps/src/lib/mod.rs b/apps/src/lib/mod.rs
index 65d0472e9e..7df31ea2ea 100644
--- a/apps/src/lib/mod.rs
+++ b/apps/src/lib/mod.rs
@@ -23,8 +23,8 @@ pub mod facade {
#[cfg(not(feature = "abcipp"))]
pub use {
- tendermint, tendermint_config, tendermint_proto, tendermint_rpc,
- tower_abci,
+ namada::tendermint, namada::tendermint_proto, namada::tendermint_rpc,
+ tendermint_config, tower_abci,
};
#[cfg(feature = "abcipp")]
pub use {
diff --git a/apps/src/lib/node/ledger/broadcaster.rs b/apps/src/lib/node/ledger/broadcaster.rs
index 199ab953c1..915a7eee67 100644
--- a/apps/src/lib/node/ledger/broadcaster.rs
+++ b/apps/src/lib/node/ledger/broadcaster.rs
@@ -1,3 +1,5 @@
+use std::net::SocketAddr;
+
use tokio::sync::mpsc::UnboundedReceiver;
use crate::facade::tendermint_rpc::{Client, HttpClient};
@@ -13,7 +15,7 @@ pub struct Broadcaster {
impl Broadcaster {
/// Create a new broadcaster that will send Http messages
/// over the given url.
- pub fn new(url: &str, receiver: UnboundedReceiver>) -> Self {
+ pub fn new(url: SocketAddr, receiver: UnboundedReceiver>) -> Self {
Self {
client: HttpClient::new(format!("http://{}", url).as_str())
.unwrap(),
diff --git a/apps/src/lib/node/ledger/mod.rs b/apps/src/lib/node/ledger/mod.rs
index 39a8460ac2..710df318bf 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;
-use crate::config::utils::num_of_threads;
+use crate::config::utils::{convert_tm_addr_to_socket_addr, num_of_threads};
use crate::config::TendermintMode;
use crate::facade::tendermint_proto::abci::CheckTxType;
use crate::facade::tower_abci::{response, split, Server};
@@ -92,7 +92,7 @@ impl Shell {
tracing::debug!("Request InitChain");
self.init_chain(
init,
- #[cfg(feature = "dev")]
+ #[cfg(any(test, feature = "dev"))]
1,
)
.map(Response::InitChain)
@@ -408,7 +408,8 @@ fn start_abci_broadcaster_shell(
task::JoinHandle<()>,
thread::JoinHandle<()>,
) {
- let rpc_address = config.tendermint.rpc_address.to_string();
+ let rpc_address =
+ convert_tm_addr_to_socket_addr(&config.cometbft.rpc.laddr);
let RunAuxSetup {
vp_wasm_compilation_cache,
tx_wasm_compilation_cache,
@@ -421,41 +422,40 @@ fn start_abci_broadcaster_shell(
tokio::sync::mpsc::unbounded_channel();
// Start broadcaster
- let broadcaster = if matches!(
- config.tendermint.tendermint_mode,
- TendermintMode::Validator
- ) {
- let (bc_abort_send, bc_abort_recv) =
- tokio::sync::oneshot::channel::<()>();
-
- spawner
- .spawn_abortable("Broadcaster", move |aborter| async move {
- // Construct a service for broadcasting protocol txs from the
- // ledger
- let mut broadcaster =
- Broadcaster::new(&rpc_address, broadcaster_receiver);
- broadcaster.run(bc_abort_recv).await;
- tracing::info!("Broadcaster is no longer running.");
-
- drop(aborter);
- })
- .with_cleanup(async move {
- let _ = bc_abort_send.send(());
- })
- } else {
- spawn_dummy_task(())
- };
+ let broadcaster =
+ if matches!(config.shell.tendermint_mode, TendermintMode::Validator) {
+ let (bc_abort_send, bc_abort_recv) =
+ tokio::sync::oneshot::channel::<()>();
+
+ spawner
+ .spawn_abortable("Broadcaster", move |aborter| async move {
+ // Construct a service for broadcasting protocol txs from
+ // the ledger
+ let mut broadcaster =
+ Broadcaster::new(rpc_address, broadcaster_receiver);
+ broadcaster.run(bc_abort_recv).await;
+ tracing::info!("Broadcaster is no longer running.");
+
+ drop(aborter);
+ })
+ .with_cleanup(async move {
+ let _ = bc_abort_send.send(());
+ })
+ } else {
+ spawn_dummy_task(())
+ };
// Setup DB cache, it must outlive the DB instance that's in the shell
let db_cache =
rocksdb::Cache::new_lru_cache(db_block_cache_size_bytes as usize);
// Construct our ABCI application.
- let tendermint_mode = config.tendermint.tendermint_mode.clone();
- let ledger_address = config.shell.ledger_address;
- #[cfg(not(feature = "dev"))]
+ let tendermint_mode = config.shell.tendermint_mode.clone();
+ let proxy_app_address =
+ convert_tm_addr_to_socket_addr(&config.cometbft.proxy_app);
+ #[cfg(not(any(test, feature = "dev")))]
let genesis = genesis::genesis(&config.shell.base_dir, &config.chain_id);
- #[cfg(feature = "dev")]
+ #[cfg(any(test, feature = "dev"))]
let genesis = genesis::genesis(1);
let (shell, abci_service, service_handle) = AbcippShim::new(
config,
@@ -476,7 +476,7 @@ fn start_abci_broadcaster_shell(
let res = run_abci(
abci_service,
service_handle,
- ledger_address,
+ proxy_app_address,
abci_abort_recv,
)
.await;
@@ -513,7 +513,7 @@ fn start_abci_broadcaster_shell(
async fn run_abci(
abci_service: AbciService,
service_handle: tokio::sync::broadcast::Sender<()>,
- ledger_address: SocketAddr,
+ proxy_app_address: SocketAddr,
abort_recv: tokio::sync::oneshot::Receiver<()>,
) -> shell::Result<()> {
// Split it into components.
@@ -541,7 +541,7 @@ async fn run_abci(
.unwrap();
tokio::select! {
// Run the server with the ABCI service
- status = server.listen(ledger_address) => {
+ status = server.listen(proxy_app_address) => {
status.map_err(|err| Error::TowerServer(err.to_string()))
},
resp_sender = abort_recv => {
@@ -566,17 +566,17 @@ fn start_tendermint(
spawner: &mut AbortableSpawner,
config: &config::Ledger,
) -> task::JoinHandle> {
- let tendermint_dir = config.tendermint_dir();
+ let tendermint_dir = config.cometbft_dir();
let chain_id = config.chain_id.clone();
- let ledger_address = config.shell.ledger_address.to_string();
- let tendermint_config = config.tendermint.clone();
+ let proxy_app_address = config.cometbft.proxy_app.to_string();
+ let config = config.clone();
let genesis_time = config
.genesis_time
.clone()
.try_into()
.expect("expected RFC3339 genesis_time");
- // Channel for signalling shut down to Tendermint process
+ // Channel for signalling shut down to cometbft process
let (tm_abort_send, tm_abort_recv) =
tokio::sync::oneshot::channel::>();
@@ -586,8 +586,8 @@ fn start_tendermint(
tendermint_dir,
chain_id,
genesis_time,
- ledger_address,
- tendermint_config,
+ proxy_app_address,
+ config,
tm_abort_recv,
)
.map_err(Error::Tendermint)
diff --git a/apps/src/lib/node/ledger/shell/finalize_block.rs b/apps/src/lib/node/ledger/shell/finalize_block.rs
index 27ff2955ac..c5f0fc6807 100644
--- a/apps/src/lib/node/ledger/shell/finalize_block.rs
+++ b/apps/src/lib/node/ledger/shell/finalize_block.rs
@@ -75,10 +75,15 @@ where
Some(EPOCH_SWITCH_BLOCKS_DELAY)
);
- tracing::debug!(
- "Block height: {height}, epoch: {current_epoch}, new epoch: \
+ tracing::info!(
+ "Block height: {height}, epoch: {current_epoch}, is new epoch: \
{new_epoch}."
);
+ tracing::debug!(
+ "New epoch block delay for updating the Tendermint validator set: \
+ {:?}",
+ self.wl_storage.storage.update_epoch_blocks_delay
+ );
if new_epoch {
namada::ledger::storage::update_allowed_conversions(
@@ -103,7 +108,10 @@ where
// Invariant: This has to be applied after
// `copy_validator_sets_and_positions` if we're starting a new epoch
- self.slash();
+ self.record_slashes_from_evidence();
+ if new_epoch {
+ self.process_slashes();
+ }
let wrapper_fees = self.get_wrapper_tx_fees();
let mut stats = InternalStats::default();
@@ -127,26 +135,19 @@ where
if ErrorCodes::from_u32(processed_tx.result.code).unwrap()
== ErrorCodes::InvalidSig
{
- let mut tx_event = match process_tx(tx.clone()) {
- Ok(tx @ TxType::Wrapper(_))
- | Ok(tx @ TxType::Protocol(_)) => {
+ let mut tx_event = match tx.header().tx_type {
+ TxType::Wrapper(_) | TxType::Protocol(_) => {
Event::new_tx_event(&tx, height.0)
}
- _ => match TxType::try_from(tx) {
- Ok(tx @ TxType::Wrapper(_))
- | Ok(tx @ TxType::Protocol(_)) => {
- Event::new_tx_event(&tx, height.0)
- }
- _ => {
- tracing::error!(
- "Internal logic error: FinalizeBlock received \
- a tx with an invalid signature error code \
- that could not be deserialized to a \
- WrapperTx / ProtocolTx type"
- );
- continue;
- }
- },
+ _ => {
+ tracing::error!(
+ "Internal logic error: FinalizeBlock received a \
+ tx with an invalid signature error code that \
+ could not be deserialized to a WrapperTx / \
+ ProtocolTx type"
+ );
+ continue;
+ }
};
tx_event["code"] = processed_tx.result.code.to_string();
tx_event["info"] =
@@ -156,8 +157,8 @@ where
continue;
}
- let tx_type = if let Ok(tx_type) = process_tx(tx) {
- tx_type
+ let tx = if let Ok(()) = tx.validate_header() {
+ tx
} else {
tracing::error!(
"Internal logic error: FinalizeBlock received tx that \
@@ -165,12 +166,13 @@ where
);
continue;
};
+ let tx_type = tx.header();
// If [`process_proposal`] rejected a Tx, emit an event here and
// move on to next tx
if ErrorCodes::from_u32(processed_tx.result.code).unwrap()
!= ErrorCodes::Ok
{
- let mut tx_event = Event::new_tx_event(&tx_type, height.0);
+ let mut tx_event = Event::new_tx_event(&tx, height.0);
tx_event["code"] = processed_tx.result.code.to_string();
tx_event["info"] =
format!("Tx rejected: {}", &processed_tx.result.info);
@@ -179,7 +181,7 @@ where
// if the rejected tx was decrypted, remove it
// from the queue of txs to be processed and remove the hash
// from storage
- if let TxType::Decrypted(_) = &tx_type {
+ if let TxType::Decrypted(_) = &tx_type.tx_type {
let tx_hash = self
.wl_storage
.storage
@@ -187,7 +189,9 @@ where
.pop()
.expect("Missing wrapper tx in queue")
.tx
- .tx_hash;
+ .clone()
+ .update_header(TxType::Raw)
+ .header_hash();
let tx_hash_key =
replay_protection::get_tx_hash_key(&tx_hash);
self.wl_storage
@@ -198,23 +202,26 @@ where
continue;
}
- let (mut tx_event, tx_unsigned_hash) = match &tx_type {
+ let (mut tx_event, tx_unsigned_hash) = match &tx_type.tx_type {
TxType::Wrapper(wrapper) => {
- let mut tx_event = Event::new_tx_event(&tx_type, height.0);
+ stats.increment_wrapper_txs();
+ let mut tx_event = Event::new_tx_event(&tx, height.0);
// Writes both txs hash to storage
- let tx = Tx::try_from(processed_tx.tx.as_ref()).unwrap();
+ let processed_tx =
+ Tx::try_from(processed_tx.tx.as_ref()).unwrap();
let wrapper_tx_hash_key =
replay_protection::get_tx_hash_key(&hash::Hash(
- tx.unsigned_hash(),
+ processed_tx.header_hash().0,
));
self.wl_storage
.storage
.write(&wrapper_tx_hash_key, vec![])
.expect("Error while writing tx hash to storage");
- let inner_tx_hash_key =
- replay_protection::get_tx_hash_key(&wrapper.tx_hash);
+ let inner_tx_hash_key = replay_protection::get_tx_hash_key(
+ &tx.clone().update_header(TxType::Raw).header_hash(),
+ );
self.wl_storage
.storage
.write(&inner_tx_hash_key, vec![])
@@ -275,8 +282,8 @@ where
}
}
- self.wl_storage.storage.tx_queue.push(WrapperTxInQueue {
- tx: wrapper.clone(),
+ self.wl_storage.storage.tx_queue.push(TxInQueue {
+ tx: processed_tx.clone(),
#[cfg(not(feature = "mainnet"))]
has_valid_pow,
});
@@ -291,20 +298,23 @@ where
.pop()
.expect("Missing wrapper tx in queue")
.tx
- .tx_hash;
- let mut event = Event::new_tx_event(&tx_type, height.0);
+ .clone()
+ .update_header(TxType::Raw)
+ .header_hash();
+ let mut event = Event::new_tx_event(&tx, height.0);
match inner {
- DecryptedTx::Decrypted {
- tx,
- has_valid_pow: _,
- } => {
- stats.increment_tx_type(
- namada::core::types::hash::Hash(tx.code_hash())
- .to_string(),
- );
+ DecryptedTx::Decrypted { has_valid_pow: _ } => {
+ if let Some(code_sec) = tx
+ .get_section(tx.code_sechash())
+ .and_then(Section::code_sec)
+ {
+ stats.increment_tx_type(
+ code_sec.code.hash().to_string(),
+ );
+ }
}
- DecryptedTx::Undecryptable(_) => {
+ DecryptedTx::Undecryptable => {
event["log"] =
"Transaction could not be decrypted.".into();
event["code"] = ErrorCodes::Undecryptable.into();
@@ -312,7 +322,7 @@ where
}
(event, Some(wrapper_hash))
}
- TxType::Raw(_) => {
+ TxType::Raw => {
tracing::error!(
"Internal logic error: FinalizeBlock received a \
TxType::Raw transaction"
@@ -329,7 +339,7 @@ where
};
match protocol::apply_tx(
- tx_type,
+ tx.clone(),
tx_length,
TxIndex(
tx_index
@@ -364,7 +374,9 @@ where
}
for ibc_event in &result.ibc_events {
// Add the IBC event besides the tx_event
- let event = Event::from(ibc_event.clone());
+ let mut event = Event::from(ibc_event.clone());
+ // Add the height for IBC event query
+ event["height"] = height.to_string();
response.events.push(event);
}
match serde_json::to_string(
@@ -417,8 +429,8 @@ where
.storage
.delete(&tx_hash_key)
.expect(
- "Error while deleting tx hash key from storage",
- );
+ "Error while deleting tx hash key from storage",
+ );
}
}
@@ -526,7 +538,7 @@ where
hash: BlockHash,
byzantine_validators: Vec,
) -> (BlockHeight, bool) {
- let height = self.wl_storage.storage.last_height + 1;
+ let height = self.wl_storage.storage.get_last_block_height() + 1;
self.gas_meter.reset();
@@ -600,7 +612,7 @@ where
/// executed while finalizing the first block of a new epoch and is applied
/// with respect to the previous epoch.
fn apply_inflation(&mut self, current_epoch: Epoch) -> Result<()> {
- let last_epoch = current_epoch - 1;
+ let last_epoch = current_epoch.prev();
// Get input values needed for the PD controller for PoS and MASP.
// Run the PD controllers to calculate new rates.
//
@@ -885,32 +897,44 @@ fn pos_votes_from_abci(
#[cfg(test)]
mod test_finalize_block {
use std::collections::{BTreeMap, BTreeSet};
- use std::str::FromStr;
use data_encoding::HEXUPPER;
use namada::ledger::parameters::EpochDuration;
use namada::ledger::storage_api;
use namada::proof_of_stake::btree_set::BTreeSetShims;
- use namada::proof_of_stake::types::WeightedValidator;
+ use namada::proof_of_stake::parameters::PosParams;
+ use namada::proof_of_stake::storage::{
+ is_validator_slashes_key, slashes_prefix,
+ };
+ use namada::proof_of_stake::types::{
+ decimal_mult_amount, BondId, SlashType, ValidatorState,
+ WeightedValidator,
+ };
use namada::proof_of_stake::{
+ enqueued_slashes_handle, get_num_consensus_validators,
read_consensus_validator_set_addresses_with_stake,
- rewards_accumulator_handle, validator_consensus_key_handle,
- validator_rewards_products_handle,
+ rewards_accumulator_handle, unjail_validator,
+ validator_consensus_key_handle, validator_rewards_products_handle,
+ validator_slashes_handle, validator_state_handle, write_pos_params,
};
+ use namada::proto::{Code, Data, Section, Signature};
use namada::types::governance::ProposalVote;
use namada::types::key::tm_consensus_key_raw_hash;
use namada::types::storage::Epoch;
use namada::types::time::DurationSecs;
+ use namada::types::token::Amount;
use namada::types::transaction::governance::{
InitProposalData, ProposalType, VoteProposalData,
};
- use namada::types::transaction::{EncryptionKey, Fee, WrapperTx, MIN_FEE};
+ use namada::types::transaction::{Fee, WrapperTx, MIN_FEE};
use namada_test_utils::TestWasms;
use rust_decimal_macros::dec;
use test_log::test;
use super::*;
- use crate::facade::tendermint_proto::abci::{Validator, VoteInfo};
+ use crate::facade::tendermint_proto::abci::{
+ Misbehavior, Validator, VoteInfo,
+ };
use crate::node::ledger::shell::test_utils::*;
use crate::node::ledger::shims::abcipp_shim_types::shim::request::{
FinalizeBlock, ProcessedTx,
@@ -938,31 +962,31 @@ mod test_finalize_block {
// create some wrapper txs
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()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
- Fee {
- amount: MIN_FEE.into(),
- token: shell.wl_storage.storage.native_token.clone(),
- },
+ let mut wrapper =
+ Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: MIN_FEE.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair,
+ Epoch(0),
+ 0.into(),
+ #[cfg(not(feature = "mainnet"))]
+ None,
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.set_data(Data::new("wasm_code".as_bytes().to_owned()));
+ wrapper.set_code(Code::new(
+ format!("transaction data: {}", i).as_bytes().to_owned(),
+ ));
+ wrapper.add_section(Section::Signature(Signature::new(
+ &wrapper.header_hash(),
&keypair,
- Epoch(0),
- 0.into(),
- raw_tx.clone(),
- Default::default(),
- #[cfg(not(feature = "mainnet"))]
- None,
- );
- let tx = wrapper
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Test failed");
+ )));
+ wrapper.encrypt(&Default::default());
if i > 1 {
processed_txs.push(ProcessedTx {
- tx: tx.to_bytes(),
+ tx: wrapper.to_bytes(),
result: TxResult {
code: u32::try_from(i.rem_euclid(2))
.expect("Test failed"),
@@ -998,10 +1022,9 @@ mod test_finalize_block {
for wrapper in shell.iter_tx_queue() {
// we cannot easily implement the PartialEq trait for WrapperTx
// so we check the hashes of the inner txs for equality
- assert_eq!(
- wrapper.tx.tx_hash,
- valid_tx.next().expect("Test failed").tx_hash
- );
+ let valid_tx = valid_tx.next().expect("Test failed");
+ assert_eq!(wrapper.tx.header.code_hash, *valid_tx.code_sechash());
+ assert_eq!(wrapper.tx.header.data_hash, *valid_tx.data_sechash());
counter += 1;
}
assert_eq!(counter, 3);
@@ -1015,13 +1038,7 @@ mod test_finalize_block {
fn test_process_proposal_rejected_decrypted_tx() {
let (mut shell, _) = setup(1);
let keypair = gen_keypair();
- let raw_tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some(String::from("transaction data").as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
+ let mut outer_tx = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -1029,25 +1046,28 @@ mod test_finalize_block {
&keypair,
Epoch(0),
0.into(),
- raw_tx.clone(),
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
-
+ ))));
+ outer_tx.header.chain_id = shell.chain_id.clone();
+ outer_tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ outer_tx.set_data(Data::new(
+ String::from("transaction data").as_bytes().to_owned(),
+ ));
+ outer_tx.encrypt(&Default::default());
+ shell.enqueue_tx(outer_tx.clone());
+
+ outer_tx.update_header(TxType::Decrypted(DecryptedTx::Decrypted {
+ #[cfg(not(feature = "mainnet"))]
+ has_valid_pow: false,
+ }));
let processed_tx = ProcessedTx {
- tx: Tx::from(TxType::Decrypted(DecryptedTx::Decrypted {
- tx: raw_tx,
- #[cfg(not(feature = "mainnet"))]
- has_valid_pow: false,
- }))
- .to_bytes(),
+ tx: outer_tx.to_bytes(),
result: TxResult {
code: ErrorCodes::InvalidTx.into(),
info: "".into(),
},
};
- shell.enqueue_tx(wrapper);
// check that the decrypted tx was not applied
for event in shell
@@ -1072,13 +1092,7 @@ mod test_finalize_block {
let (mut shell, _) = setup(1);
let keypair = crate::wallet::defaults::daewon_keypair();
- let pubkey = EncryptionKey::default();
// not valid tx bytes
- let tx = "garbage data".as_bytes().to_owned();
- let inner_tx =
- namada::types::transaction::encrypted::EncryptedTx::encrypt(
- &tx, pubkey,
- );
let wrapper = WrapperTx {
fee: Fee {
amount: 0.into(),
@@ -1087,23 +1101,20 @@ mod test_finalize_block {
pk: keypair.ref_to(),
epoch: Epoch(0),
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(
- wrapper.clone(),
- )))
- .to_bytes(),
+ tx: Tx::new(TxType::Decrypted(DecryptedTx::Undecryptable))
+ .to_bytes(),
result: TxResult {
code: ErrorCodes::Ok.into(),
info: "".into(),
},
};
- shell.enqueue_tx(wrapper);
+ let tx = Tx::new(TxType::Wrapper(Box::new(wrapper)));
+ shell.enqueue_tx(tx);
// check that correct error message is returned
for event in shell
@@ -1147,37 +1158,35 @@ mod test_finalize_block {
// create two decrypted txs
let tx_code = TestWasms::TxNoOp.read_bytes();
for i in 0..2 {
- let raw_tx = Tx::new(
- tx_code.clone(),
- Some(
- format!("Decrypted transaction data: {}", i)
- .as_bytes()
- .to_owned(),
- ),
- shell.chain_id.clone(),
- None,
- );
- let wrapper_tx = WrapperTx::new(
- Fee {
- amount: MIN_FEE.into(),
- token: shell.wl_storage.storage.native_token.clone(),
- },
- &keypair,
- Epoch(0),
- 0.into(),
- raw_tx.clone(),
- Default::default(),
+ let mut outer_tx =
+ Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: MIN_FEE.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair,
+ Epoch(0),
+ 0.into(),
+ #[cfg(not(feature = "mainnet"))]
+ None,
+ ))));
+ outer_tx.header.chain_id = shell.chain_id.clone();
+ outer_tx.set_code(Code::new(tx_code.clone()));
+ outer_tx.set_data(Data::new(
+ format!("Decrypted transaction data: {}", i)
+ .as_bytes()
+ .to_owned(),
+ ));
+ outer_tx.encrypt(&Default::default());
+ shell.enqueue_tx(outer_tx.clone());
+ outer_tx.update_header(TxType::Decrypted(DecryptedTx::Decrypted {
#[cfg(not(feature = "mainnet"))]
- None,
- );
- shell.enqueue_tx(wrapper_tx);
+ has_valid_pow: false,
+ }));
+ outer_tx.decrypt(::G2Affine::prime_subgroup_generator())
+ .expect("Test failed");
processed_txs.push(ProcessedTx {
- tx: Tx::from(TxType::Decrypted(DecryptedTx::Decrypted {
- tx: raw_tx,
- #[cfg(not(feature = "mainnet"))]
- has_valid_pow: false,
- }))
- .to_bytes(),
+ tx: outer_tx.to_bytes(),
result: TxResult {
code: ErrorCodes::Ok.into(),
info: "".into(),
@@ -1186,35 +1195,33 @@ mod test_finalize_block {
}
// create two wrapper txs
for i in 0..2 {
- let raw_tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some(
- format!("Encrypted transaction data: {}", i)
- .as_bytes()
- .to_owned(),
- ),
- shell.chain_id.clone(),
- None,
- );
- let wrapper_tx = WrapperTx::new(
- Fee {
- amount: MIN_FEE.into(),
- token: shell.wl_storage.storage.native_token.clone(),
- },
+ let mut wrapper_tx =
+ Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: MIN_FEE.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair,
+ Epoch(0),
+ 0.into(),
+ #[cfg(not(feature = "mainnet"))]
+ None,
+ ))));
+ wrapper_tx.header.chain_id = shell.chain_id.clone();
+ wrapper_tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper_tx.set_data(Data::new(
+ format!("Encrypted transaction data: {}", i)
+ .as_bytes()
+ .to_owned(),
+ ));
+ wrapper_tx.add_section(Section::Signature(Signature::new(
+ &wrapper_tx.header_hash(),
&keypair,
- Epoch(0),
- 0.into(),
- raw_tx.clone(),
- Default::default(),
- #[cfg(not(feature = "mainnet"))]
- None,
- );
- let wrapper = wrapper_tx
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Test failed");
- valid_txs.push(wrapper_tx);
+ )));
+ wrapper_tx.encrypt(&Default::default());
+ valid_txs.push(wrapper_tx.clone());
processed_txs.push(ProcessedTx {
- tx: wrapper.to_bytes(),
+ tx: wrapper_tx.to_bytes(),
result: TxResult {
code: ErrorCodes::Ok.into(),
info: "".into(),
@@ -1260,10 +1267,9 @@ mod test_finalize_block {
let mut counter = 0;
for wrapper in shell.iter_tx_queue() {
- assert_eq!(
- wrapper.tx.tx_hash,
- txs.next().expect("Test failed").tx_hash
- );
+ let next = txs.next().expect("Test failed");
+ assert_eq!(wrapper.tx.header.code_hash, *next.code_sechash());
+ assert_eq!(wrapper.tx.header.data_hash, *next.data_sechash());
counter += 1;
}
assert_eq!(counter, 2);
@@ -1334,12 +1340,11 @@ mod test_finalize_block {
// Collect all storage key-vals into a sorted map
let store_block_state = |shell: &TestShell| -> BTreeMap<_, _> {
- let prefix: Key = FromStr::from_str("").unwrap();
shell
.wl_storage
.storage
.db
- .iter_prefix(&prefix)
+ .iter_optional_prefix(None)
.map(|(key, val, _gas)| (key, val))
.collect()
};
@@ -1505,7 +1510,7 @@ mod test_finalize_block {
// FINALIZE BLOCK 1. Tell Namada that val1 is the block proposer. We
// won't receive votes from TM since we receive votes at a 1-block
// delay, so votes will be empty here
- next_block_for_inflation(&mut shell, pkh1.clone(), vec![]);
+ next_block_for_inflation(&mut shell, pkh1.clone(), vec![], None);
assert!(
rewards_accumulator_handle()
.is_empty(&shell.wl_storage)
@@ -1515,7 +1520,7 @@ mod test_finalize_block {
// FINALIZE BLOCK 2. Tell Namada that val1 is the block proposer.
// Include votes that correspond to block 1. Make val2 the next block's
// proposer.
- next_block_for_inflation(&mut shell, pkh2.clone(), votes.clone());
+ next_block_for_inflation(&mut shell, pkh2.clone(), votes.clone(), None);
assert!(rewards_prod_1.is_empty(&shell.wl_storage).unwrap());
assert!(rewards_prod_2.is_empty(&shell.wl_storage).unwrap());
assert!(rewards_prod_3.is_empty(&shell.wl_storage).unwrap());
@@ -1538,7 +1543,7 @@ mod test_finalize_block {
);
// FINALIZE BLOCK 3, with val1 as proposer for the next block.
- next_block_for_inflation(&mut shell, pkh1.clone(), votes);
+ next_block_for_inflation(&mut shell, pkh1.clone(), votes, None);
assert!(rewards_prod_1.is_empty(&shell.wl_storage).unwrap());
assert!(rewards_prod_2.is_empty(&shell.wl_storage).unwrap());
assert!(rewards_prod_3.is_empty(&shell.wl_storage).unwrap());
@@ -1590,7 +1595,7 @@ mod test_finalize_block {
// FINALIZE BLOCK 4. The next block proposer will be val1. Only val1,
// val2, and val3 vote on this block.
- next_block_for_inflation(&mut shell, pkh1.clone(), votes.clone());
+ next_block_for_inflation(&mut shell, pkh1.clone(), votes.clone(), None);
assert!(rewards_prod_1.is_empty(&shell.wl_storage).unwrap());
assert!(rewards_prod_2.is_empty(&shell.wl_storage).unwrap());
assert!(rewards_prod_3.is_empty(&shell.wl_storage).unwrap());
@@ -1623,7 +1628,12 @@ mod test_finalize_block {
get_rewards_acc(&shell.wl_storage),
get_rewards_sum(&shell.wl_storage),
);
- next_block_for_inflation(&mut shell, pkh1.clone(), votes.clone());
+ next_block_for_inflation(
+ &mut shell,
+ pkh1.clone(),
+ votes.clone(),
+ None,
+ );
}
assert!(
rewards_accumulator_handle()
@@ -1678,12 +1688,26 @@ mod test_finalize_block {
shell: &mut TestShell,
proposer_address: Vec,
votes: Vec,
+ byzantine_validators: Option>,
) {
- let req = FinalizeBlock {
+ // Let the header time be always ahead of the next epoch min start time
+ let header = Header {
+ time: shell
+ .wl_storage
+ .storage
+ .next_epoch_min_start_time
+ .next_second(),
+ ..Default::default()
+ };
+ let mut req = FinalizeBlock {
+ header,
proposer_address,
votes,
..Default::default()
};
+ if let Some(byz_vals) = byzantine_validators {
+ req.byzantine_validators = byz_vals;
+ }
shell.finalize_block(req).unwrap();
shell.commit();
}
@@ -1699,29 +1723,35 @@ mod test_finalize_block {
wasm_path.push("wasm_for_tests/tx_no_op.wasm");
let tx_code = std::fs::read(wasm_path)
.expect("Expected a file at given code path");
- let raw_tx = Tx::new(
- tx_code,
- Some("Encrypted transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper_tx = WrapperTx::new(
- Fee {
- amount: 0.into(),
- token: shell.wl_storage.storage.native_token.clone(),
- },
- &keypair,
- Epoch(0),
- 0.into(),
- raw_tx.clone(),
- Default::default(),
+ let mut wrapper_tx =
+ Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: 0.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair,
+ Epoch(0),
+ 0.into(),
+ #[cfg(not(feature = "mainnet"))]
+ None,
+ ))));
+ wrapper_tx.header.chain_id = shell.chain_id.clone();
+ wrapper_tx.set_code(Code::new(tx_code));
+ wrapper_tx.set_data(Data::new(
+ "Encrypted transaction data".as_bytes().to_owned(),
+ ));
+ let mut decrypted_tx = wrapper_tx.clone();
+ wrapper_tx.encrypt(&Default::default());
+
+ decrypted_tx.update_header(TxType::Decrypted(DecryptedTx::Decrypted {
#[cfg(not(feature = "mainnet"))]
- None,
- );
+ has_valid_pow: false,
+ }));
// Write inner hash in storage
- let inner_hash_key =
- replay_protection::get_tx_hash_key(&wrapper_tx.tx_hash);
+ let inner_hash_key = replay_protection::get_tx_hash_key(
+ &wrapper_tx.clone().update_header(TxType::Raw).header_hash(),
+ );
shell
.wl_storage
.storage
@@ -1729,12 +1759,7 @@ mod test_finalize_block {
.expect("Test failed");
let processed_tx = ProcessedTx {
- tx: Tx::from(TxType::Decrypted(DecryptedTx::Decrypted {
- tx: raw_tx,
- #[cfg(not(feature = "mainnet"))]
- has_valid_pow: false,
- }))
- .to_bytes(),
+ tx: decrypted_tx.to_bytes(),
result: TxResult {
code: ErrorCodes::Ok.into(),
info: "".into(),
@@ -1764,4 +1789,1226 @@ mod test_finalize_block {
// .0
// )
}
+
+ #[test]
+ fn test_ledger_slashing() -> storage_api::Result<()> {
+ let num_validators = 7_u64;
+ let (mut shell, _) = setup(num_validators);
+ let mut params = read_pos_params(&shell.wl_storage).unwrap();
+ params.unbonding_len = 4;
+ write_pos_params(&mut shell.wl_storage, params.clone())?;
+
+ let validator_set: Vec =
+ read_consensus_validator_set_addresses_with_stake(
+ &shell.wl_storage,
+ Epoch::default(),
+ )
+ .unwrap()
+ .into_iter()
+ .collect();
+
+ let val1 = validator_set[0].clone();
+ let val2 = validator_set[1].clone();
+
+ let initial_stake = val1.bonded_stake;
+ let total_initial_stake = num_validators * initial_stake;
+
+ let get_pkh = |address, epoch| {
+ let ck = validator_consensus_key_handle(&address)
+ .get(&shell.wl_storage, epoch, ¶ms)
+ .unwrap()
+ .unwrap();
+ let hash_string = tm_consensus_key_raw_hash(&ck);
+ HEXUPPER.decode(hash_string.as_bytes()).unwrap()
+ };
+
+ let mut all_pkhs: Vec> = Vec::new();
+ let mut behaving_pkhs: Vec> = Vec::new();
+ for (idx, validator) in validator_set.iter().enumerate() {
+ // Every validator should be in the consensus set
+ assert_eq!(
+ validator_state_handle(&validator.address)
+ .get(&shell.wl_storage, Epoch::default(), ¶ms)
+ .unwrap(),
+ Some(ValidatorState::Consensus)
+ );
+ all_pkhs.push(get_pkh(validator.address.clone(), Epoch::default()));
+ if idx > 1_usize {
+ behaving_pkhs
+ .push(get_pkh(validator.address.clone(), Epoch::default()));
+ }
+ }
+
+ let pkh1 = all_pkhs[0].clone();
+ let pkh2 = all_pkhs[1].clone();
+
+ // Finalize block 1 (no votes since this is the first block)
+ next_block_for_inflation(&mut shell, pkh1.clone(), vec![], None);
+
+ let votes = get_default_true_votes(
+ &shell.wl_storage,
+ shell.wl_storage.storage.block.epoch,
+ );
+ assert!(!votes.is_empty());
+ assert_eq!(votes.len(), 7_usize);
+
+ // For block 2, include the evidences found for block 1.
+ // NOTE: Only the type, height, and validator address fields from the
+ // Misbehavior struct are used in Namada
+ let byzantine_validators = vec![
+ Misbehavior {
+ r#type: 1,
+ validator: Some(Validator {
+ address: pkh1.clone(),
+ power: Default::default(),
+ }),
+ height: 1,
+ time: Default::default(),
+ total_voting_power: Default::default(),
+ },
+ Misbehavior {
+ r#type: 2,
+ validator: Some(Validator {
+ address: pkh2,
+ power: Default::default(),
+ }),
+ height: 1,
+ time: Default::default(),
+ total_voting_power: Default::default(),
+ },
+ ];
+ next_block_for_inflation(
+ &mut shell,
+ pkh1.clone(),
+ votes,
+ Some(byzantine_validators),
+ );
+
+ let processing_epoch = shell.wl_storage.storage.block.epoch
+ + params.unbonding_len
+ + 1_u64
+ + params.cubic_slashing_window_length;
+
+ // Check that the ValidatorState, enqueued slashes, and validator sets
+ // are properly updated
+ assert_eq!(
+ validator_state_handle(&val1.address)
+ .get(&shell.wl_storage, Epoch::default(), ¶ms)
+ .unwrap(),
+ Some(ValidatorState::Consensus)
+ );
+ assert_eq!(
+ validator_state_handle(&val2.address)
+ .get(&shell.wl_storage, Epoch::default(), ¶ms)
+ .unwrap(),
+ Some(ValidatorState::Consensus)
+ );
+ assert!(
+ enqueued_slashes_handle()
+ .at(&Epoch::default())
+ .is_empty(&shell.wl_storage)?
+ );
+ assert_eq!(
+ get_num_consensus_validators(&shell.wl_storage, Epoch::default())
+ .unwrap(),
+ 7_u64
+ );
+ for epoch in Epoch::default().next().iter_range(params.pipeline_len) {
+ assert_eq!(
+ validator_state_handle(&val1.address)
+ .get(&shell.wl_storage, epoch, ¶ms)
+ .unwrap(),
+ Some(ValidatorState::Jailed)
+ );
+ assert_eq!(
+ validator_state_handle(&val2.address)
+ .get(&shell.wl_storage, epoch, ¶ms)
+ .unwrap(),
+ Some(ValidatorState::Jailed)
+ );
+ assert!(
+ enqueued_slashes_handle()
+ .at(&epoch)
+ .is_empty(&shell.wl_storage)?
+ );
+ assert_eq!(
+ get_num_consensus_validators(&shell.wl_storage, epoch).unwrap(),
+ 5_u64
+ );
+ }
+ assert!(
+ !enqueued_slashes_handle()
+ .at(&processing_epoch)
+ .is_empty(&shell.wl_storage)?
+ );
+
+ // Advance to the processing epoch
+ let votes = get_default_true_votes(&shell.wl_storage, Epoch::default());
+ loop {
+ next_block_for_inflation(
+ &mut shell,
+ pkh1.clone(),
+ votes.clone(),
+ None,
+ );
+ // println!(
+ // "Block {} epoch {}",
+ // shell.wl_storage.storage.block.height,
+ // shell.wl_storage.storage.block.epoch
+ // );
+ if shell.wl_storage.storage.block.epoch == processing_epoch {
+ // println!("Reached processing epoch");
+ break;
+ } else {
+ assert!(
+ enqueued_slashes_handle()
+ .at(&shell.wl_storage.storage.block.epoch)
+ .is_empty(&shell.wl_storage)?
+ );
+ let stake1 = read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val1.address,
+ shell.wl_storage.storage.block.epoch,
+ )?
+ .unwrap();
+ let stake2 = read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val2.address,
+ shell.wl_storage.storage.block.epoch,
+ )?
+ .unwrap();
+ let total_stake = read_total_stake(
+ &shell.wl_storage,
+ ¶ms,
+ shell.wl_storage.storage.block.epoch,
+ )?;
+ assert_eq!(stake1, initial_stake);
+ assert_eq!(stake2, initial_stake);
+ assert_eq!(total_stake, total_initial_stake);
+ }
+ }
+
+ let num_slashes = storage_api::iter_prefix_bytes(
+ &shell.wl_storage,
+ &slashes_prefix(),
+ )?
+ .filter(|kv_res| {
+ let (k, _v) = kv_res.as_ref().unwrap();
+ is_validator_slashes_key(k).is_some()
+ })
+ .count();
+
+ assert_eq!(num_slashes, 2);
+ assert_eq!(
+ validator_slashes_handle(&val1.address)
+ .len(&shell.wl_storage)
+ .unwrap(),
+ 1_u64
+ );
+ assert_eq!(
+ validator_slashes_handle(&val2.address)
+ .len(&shell.wl_storage)
+ .unwrap(),
+ 1_u64
+ );
+
+ let slash1 = validator_slashes_handle(&val1.address)
+ .get(&shell.wl_storage, 0)?
+ .unwrap();
+ let slash2 = validator_slashes_handle(&val2.address)
+ .get(&shell.wl_storage, 0)?
+ .unwrap();
+
+ assert_eq!(slash1.r#type, SlashType::DuplicateVote);
+ assert_eq!(slash2.r#type, SlashType::LightClientAttack);
+ assert_eq!(slash1.epoch, Epoch::default());
+ assert_eq!(slash2.epoch, Epoch::default());
+
+ // Each validator has equal weight in this test, and two have been
+ // slashed
+ let frac = dec!(2) / dec!(7);
+ let cubic_rate = dec!(9) * frac * frac;
+
+ assert_eq!(slash1.rate, cubic_rate);
+ assert_eq!(slash2.rate, cubic_rate);
+
+ // Check that there are still 5 consensus validators and the 2
+ // misbehaving ones are still jailed
+ for epoch in shell
+ .wl_storage
+ .storage
+ .block
+ .epoch
+ .iter_range(params.pipeline_len + 1)
+ {
+ assert_eq!(
+ validator_state_handle(&val1.address)
+ .get(&shell.wl_storage, epoch, ¶ms)
+ .unwrap(),
+ Some(ValidatorState::Jailed)
+ );
+ assert_eq!(
+ validator_state_handle(&val2.address)
+ .get(&shell.wl_storage, epoch, ¶ms)
+ .unwrap(),
+ Some(ValidatorState::Jailed)
+ );
+ assert_eq!(
+ get_num_consensus_validators(&shell.wl_storage, epoch).unwrap(),
+ 5_u64
+ );
+ }
+
+ // Check that the deltas at the pipeline epoch are slashed
+ let pipeline_epoch =
+ shell.wl_storage.storage.block.epoch + params.pipeline_len;
+ let stake1 = read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val1.address,
+ pipeline_epoch,
+ )?
+ .unwrap();
+ let stake2 = read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val2.address,
+ pipeline_epoch,
+ )?
+ .unwrap();
+ let total_stake =
+ read_total_stake(&shell.wl_storage, ¶ms, pipeline_epoch)?;
+
+ let expected_slashed = decimal_mult_amount(cubic_rate, initial_stake);
+ assert_eq!(stake1, initial_stake - expected_slashed);
+ assert_eq!(stake2, initial_stake - expected_slashed);
+ assert_eq!(total_stake, total_initial_stake - 2 * expected_slashed);
+
+ // Unjail one of the validators
+ let current_epoch = shell.wl_storage.storage.block.epoch;
+ unjail_validator(&mut shell.wl_storage, &val1.address, current_epoch)?;
+ let pipeline_epoch = current_epoch + params.pipeline_len;
+
+ // Check that the state is the same until the pipeline epoch, at which
+ // point one validator is unjailed
+ for epoch in shell
+ .wl_storage
+ .storage
+ .block
+ .epoch
+ .iter_range(params.pipeline_len)
+ {
+ assert_eq!(
+ validator_state_handle(&val1.address)
+ .get(&shell.wl_storage, epoch, ¶ms)
+ .unwrap(),
+ Some(ValidatorState::Jailed)
+ );
+ assert_eq!(
+ validator_state_handle(&val2.address)
+ .get(&shell.wl_storage, epoch, ¶ms)
+ .unwrap(),
+ Some(ValidatorState::Jailed)
+ );
+ assert_eq!(
+ get_num_consensus_validators(&shell.wl_storage, epoch).unwrap(),
+ 5_u64
+ );
+ }
+ assert_eq!(
+ validator_state_handle(&val1.address)
+ .get(&shell.wl_storage, pipeline_epoch, ¶ms)
+ .unwrap(),
+ Some(ValidatorState::Consensus)
+ );
+ assert_eq!(
+ validator_state_handle(&val2.address)
+ .get(&shell.wl_storage, pipeline_epoch, ¶ms)
+ .unwrap(),
+ Some(ValidatorState::Jailed)
+ );
+ assert_eq!(
+ get_num_consensus_validators(&shell.wl_storage, pipeline_epoch)
+ .unwrap(),
+ 6_u64
+ );
+
+ Ok(())
+ }
+
+ /// NOTE: must call `get_default_true_votes` before every call to
+ /// `next_block_for_inflation`
+ #[test]
+ fn test_multiple_misbehaviors() -> storage_api::Result<()> {
+ for num_validators in 4u64..10u64 {
+ println!("NUM VALIDATORS = {}", num_validators);
+ test_multiple_misbehaviors_by_num_vals(num_validators)?;
+ }
+ Ok(())
+ }
+
+ /// Current test procedure (prefixed by epoch in which the event occurs):
+ /// 0) Validator initial stake of 200_000
+ /// 1) Delegate 67_231 to validator
+ /// 1) Self-unbond 154_654
+ /// 2) Unbond delegation of 18_000
+ /// 3) Self-bond 9_123
+ /// 4) Self-unbond 15_000
+ /// 5) Delegate 8_144 to validator
+ /// 6) Discover misbehavior in epoch 3
+ /// 7) Discover misbehavior in epoch 3
+ /// 7) Discover misbehavior in epoch 4
+ fn test_multiple_misbehaviors_by_num_vals(
+ num_validators: u64,
+ ) -> storage_api::Result<()> {
+ // Setup the network with pipeline_len = 2, unbonding_len = 4
+ // let num_validators = 8_u64;
+ let (mut shell, _) = setup(num_validators);
+ let mut params = read_pos_params(&shell.wl_storage).unwrap();
+ params.unbonding_len = 4;
+ params.max_validator_slots = 4;
+ write_pos_params(&mut shell.wl_storage, params.clone())?;
+
+ // Slash pool balance
+ let nam_address = shell.wl_storage.storage.native_token.clone();
+ let slash_balance_key = token::balance_key(
+ &nam_address,
+ &namada_proof_of_stake::SLASH_POOL_ADDRESS,
+ );
+ let slash_pool_balance_init: token::Amount = shell
+ .wl_storage
+ .read(&slash_balance_key)
+ .expect("must be able to read")
+ .unwrap_or_default();
+ debug_assert_eq!(slash_pool_balance_init, token::Amount::default());
+
+ let consensus_set: Vec =
+ read_consensus_validator_set_addresses_with_stake(
+ &shell.wl_storage,
+ Epoch::default(),
+ )
+ .unwrap()
+ .into_iter()
+ .collect();
+
+ let val1 = consensus_set[0].clone();
+ let pkh1 = get_pkh_from_address(
+ &shell.wl_storage,
+ ¶ms,
+ val1.address.clone(),
+ Epoch::default(),
+ );
+
+ let initial_stake = val1.bonded_stake;
+ let total_initial_stake = num_validators * initial_stake;
+
+ // Finalize block 1
+ next_block_for_inflation(&mut shell, pkh1.clone(), vec![], None);
+
+ let votes = get_default_true_votes(&shell.wl_storage, Epoch::default());
+ assert!(!votes.is_empty());
+
+ // Advance to epoch 1 and
+ // 1. Delegate 67231 NAM to validator
+ // 2. Validator self-unbond 154654 NAM
+ let current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
+ assert_eq!(shell.wl_storage.storage.block.epoch.0, 1_u64);
+
+ // Make an account with balance and delegate some tokens
+ let delegator = address::testing::gen_implicit_address();
+ let del_1_amount = token::Amount::whole(67_231);
+ let staking_token = shell.wl_storage.storage.native_token.clone();
+ credit_tokens(
+ &mut shell.wl_storage,
+ &staking_token,
+ &delegator,
+ token::Amount::whole(200_000),
+ )
+ .unwrap();
+ namada_proof_of_stake::bond_tokens(
+ &mut shell.wl_storage,
+ Some(&delegator),
+ &val1.address,
+ del_1_amount,
+ current_epoch,
+ )
+ .unwrap();
+
+ // Self-unbond
+ let self_unbond_1_amount = token::Amount::whole(154_654);
+ namada_proof_of_stake::unbond_tokens(
+ &mut shell.wl_storage,
+ None,
+ &val1.address,
+ self_unbond_1_amount,
+ current_epoch,
+ )
+ .unwrap();
+
+ let val_stake = namada_proof_of_stake::read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val1.address,
+ current_epoch + params.pipeline_len,
+ )
+ .unwrap()
+ .unwrap_or_default();
+
+ let total_stake = namada_proof_of_stake::read_total_stake(
+ &shell.wl_storage,
+ ¶ms,
+ current_epoch + params.pipeline_len,
+ )
+ .unwrap();
+
+ assert_eq!(
+ val_stake,
+ initial_stake + del_1_amount - self_unbond_1_amount
+ );
+ assert_eq!(
+ total_stake,
+ total_initial_stake + del_1_amount - self_unbond_1_amount
+ );
+
+ // Advance to epoch 2 and
+ // 1. Unbond 18000 NAM from delegation
+ let votes = get_default_true_votes(
+ &shell.wl_storage,
+ shell.wl_storage.storage.block.epoch,
+ );
+ let current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
+ println!("\nUnbonding in epoch 2");
+ let del_unbond_1_amount = token::Amount::whole(18_000);
+ namada_proof_of_stake::unbond_tokens(
+ &mut shell.wl_storage,
+ Some(&delegator),
+ &val1.address,
+ del_unbond_1_amount,
+ current_epoch,
+ )
+ .unwrap();
+
+ let val_stake = namada_proof_of_stake::read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val1.address,
+ current_epoch + params.pipeline_len,
+ )
+ .unwrap()
+ .unwrap_or_default();
+ let total_stake = namada_proof_of_stake::read_total_stake(
+ &shell.wl_storage,
+ ¶ms,
+ current_epoch + params.pipeline_len,
+ )
+ .unwrap();
+ assert_eq!(
+ val_stake,
+ initial_stake + del_1_amount
+ - self_unbond_1_amount
+ - del_unbond_1_amount
+ );
+ assert_eq!(
+ total_stake,
+ total_initial_stake + del_1_amount
+ - self_unbond_1_amount
+ - del_unbond_1_amount
+ );
+
+ // Advance to epoch 3 and
+ // 1. Validator self-bond 9123 NAM
+ let votes = get_default_true_votes(
+ &shell.wl_storage,
+ shell.wl_storage.storage.block.epoch,
+ );
+ let current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
+ println!("\nBonding in epoch 3");
+
+ let self_bond_1_amount = token::Amount::whole(9_123);
+ namada_proof_of_stake::bond_tokens(
+ &mut shell.wl_storage,
+ None,
+ &val1.address,
+ self_bond_1_amount,
+ current_epoch,
+ )
+ .unwrap();
+
+ // Advance to epoch 4
+ // 1. Validator self-unbond 15000 NAM
+ let votes = get_default_true_votes(
+ &shell.wl_storage,
+ shell.wl_storage.storage.block.epoch,
+ );
+ let current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
+ assert_eq!(current_epoch.0, 4_u64);
+
+ let self_unbond_2_amount = token::Amount::whole(15_000);
+ namada_proof_of_stake::unbond_tokens(
+ &mut shell.wl_storage,
+ None,
+ &val1.address,
+ self_unbond_2_amount,
+ current_epoch,
+ )
+ .unwrap();
+
+ // Advance to epoch 5 and
+ // Delegate 8144 NAM to validator
+ let votes = get_default_true_votes(
+ &shell.wl_storage,
+ shell.wl_storage.storage.block.epoch,
+ );
+ let current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
+ assert_eq!(current_epoch.0, 5_u64);
+ println!("Delegating in epoch 5");
+
+ // Delegate
+ let del_2_amount = token::Amount::whole(8_144);
+ namada_proof_of_stake::bond_tokens(
+ &mut shell.wl_storage,
+ Some(&delegator),
+ &val1.address,
+ del_2_amount,
+ current_epoch,
+ )
+ .unwrap();
+
+ println!("Advancing to epoch 6");
+
+ // Advance to epoch 6
+ let votes = get_default_true_votes(
+ &shell.wl_storage,
+ shell.wl_storage.storage.block.epoch,
+ );
+ let current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
+ assert_eq!(current_epoch.0, 6_u64);
+
+ // Discover a misbehavior committed in epoch 3
+ // NOTE: Only the type, height, and validator address fields from the
+ // Misbehavior struct are used in Namada
+ let misbehavior_epoch = Epoch(3_u64);
+ let height = shell
+ .wl_storage
+ .storage
+ .block
+ .pred_epochs
+ .first_block_heights[misbehavior_epoch.0 as usize];
+ let misbehaviors = vec![Misbehavior {
+ r#type: 1,
+ validator: Some(Validator {
+ address: pkh1.clone(),
+ power: Default::default(),
+ }),
+ height: height.0 as i64,
+ time: Default::default(),
+ total_voting_power: Default::default(),
+ }];
+ let votes = get_default_true_votes(
+ &shell.wl_storage,
+ shell.wl_storage.storage.block.epoch,
+ );
+ next_block_for_inflation(
+ &mut shell,
+ pkh1.clone(),
+ votes.clone(),
+ Some(misbehaviors),
+ );
+
+ // Assertions
+ assert_eq!(current_epoch.0, 6_u64);
+ let processing_epoch = misbehavior_epoch
+ + params.unbonding_len
+ + 1_u64
+ + params.cubic_slashing_window_length;
+ let enqueued_slash = enqueued_slashes_handle()
+ .at(&processing_epoch)
+ .at(&val1.address)
+ .front(&shell.wl_storage)
+ .unwrap()
+ .unwrap();
+ assert_eq!(enqueued_slash.epoch, misbehavior_epoch);
+ assert_eq!(enqueued_slash.r#type, SlashType::DuplicateVote);
+ assert_eq!(enqueued_slash.rate, Decimal::ZERO);
+ let last_slash =
+ namada_proof_of_stake::read_validator_last_slash_epoch(
+ &shell.wl_storage,
+ &val1.address,
+ )
+ .unwrap();
+ assert_eq!(last_slash, Some(misbehavior_epoch));
+ assert!(
+ namada_proof_of_stake::validator_slashes_handle(&val1.address)
+ .is_empty(&shell.wl_storage)
+ .unwrap()
+ );
+
+ println!("Advancing to epoch 7");
+
+ // Advance to epoch 7
+ let current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
+
+ // Discover two more misbehaviors, one committed in epoch 3, one in
+ // epoch 4
+ let height4 = shell
+ .wl_storage
+ .storage
+ .block
+ .pred_epochs
+ .first_block_heights[4];
+ let misbehaviors = vec![
+ Misbehavior {
+ r#type: 1,
+ validator: Some(Validator {
+ address: pkh1.clone(),
+ power: Default::default(),
+ }),
+ height: height.0 as i64,
+ time: Default::default(),
+ total_voting_power: Default::default(),
+ },
+ Misbehavior {
+ r#type: 2,
+ validator: Some(Validator {
+ address: pkh1.clone(),
+ power: Default::default(),
+ }),
+ height: height4.0 as i64,
+ time: Default::default(),
+ total_voting_power: Default::default(),
+ },
+ ];
+ next_block_for_inflation(
+ &mut shell,
+ pkh1.clone(),
+ votes.clone(),
+ Some(misbehaviors),
+ );
+ assert_eq!(current_epoch.0, 7_u64);
+ let enqueued_slashes_8 = enqueued_slashes_handle()
+ .at(&processing_epoch)
+ .at(&val1.address);
+ let enqueued_slashes_9 = enqueued_slashes_handle()
+ .at(&processing_epoch.next())
+ .at(&val1.address);
+
+ assert_eq!(enqueued_slashes_8.len(&shell.wl_storage).unwrap(), 2_u64);
+ assert_eq!(enqueued_slashes_9.len(&shell.wl_storage).unwrap(), 1_u64);
+ let last_slash =
+ namada_proof_of_stake::read_validator_last_slash_epoch(
+ &shell.wl_storage,
+ &val1.address,
+ )
+ .unwrap();
+ assert_eq!(last_slash, Some(Epoch(4)));
+ assert!(
+ namada_proof_of_stake::is_validator_frozen(
+ &shell.wl_storage,
+ &val1.address,
+ current_epoch,
+ ¶ms
+ )
+ .unwrap()
+ );
+ assert!(
+ namada_proof_of_stake::validator_slashes_handle(&val1.address)
+ .is_empty(&shell.wl_storage)
+ .unwrap()
+ );
+
+ let pre_stake_10 = namada_proof_of_stake::read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val1.address,
+ Epoch(10),
+ )
+ .unwrap()
+ .unwrap_or_default();
+ assert_eq!(
+ pre_stake_10,
+ initial_stake + del_1_amount
+ - self_unbond_1_amount
+ - del_unbond_1_amount
+ + self_bond_1_amount
+ - self_unbond_2_amount
+ + del_2_amount
+ );
+
+ println!("\nNow processing the infractions\n");
+
+ // Advance to epoch 9, where the infractions committed in epoch 3 will
+ // be processed
+ let votes = get_default_true_votes(
+ &shell.wl_storage,
+ shell.wl_storage.storage.block.epoch,
+ );
+ let _ = advance_epoch(&mut shell, &pkh1, &votes, None);
+ let votes = get_default_true_votes(
+ &shell.wl_storage,
+ shell.wl_storage.storage.block.epoch,
+ );
+ let current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
+ assert_eq!(current_epoch.0, 9_u64);
+
+ let val_stake_3 = namada_proof_of_stake::read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val1.address,
+ Epoch(3),
+ )
+ .unwrap()
+ .unwrap_or_default();
+ let val_stake_4 = namada_proof_of_stake::read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val1.address,
+ Epoch(4),
+ )
+ .unwrap()
+ .unwrap_or_default();
+
+ let tot_stake_3 = namada_proof_of_stake::read_total_stake(
+ &shell.wl_storage,
+ ¶ms,
+ Epoch(3),
+ )
+ .unwrap();
+ let tot_stake_4 = namada_proof_of_stake::read_total_stake(
+ &shell.wl_storage,
+ ¶ms,
+ Epoch(4),
+ )
+ .unwrap();
+
+ let vp_frac_3 = Decimal::from(val_stake_3) / Decimal::from(tot_stake_3);
+ let vp_frac_4 = Decimal::from(val_stake_4) / Decimal::from(tot_stake_4);
+ let tot_frac = dec!(2) * vp_frac_3 + vp_frac_4;
+ let cubic_rate =
+ std::cmp::min(Decimal::ONE, dec!(9) * tot_frac * tot_frac);
+ dbg!(&cubic_rate);
+
+ let equal_enough = |rate1: Decimal, rate2: Decimal| -> bool {
+ let tolerance = dec!(0.000000001);
+ (rate1 - rate2).abs() < tolerance
+ };
+
+ // There should be 2 slashes processed for the validator, each with rate
+ // equal to the cubic slashing rate
+ let val_slashes =
+ namada_proof_of_stake::validator_slashes_handle(&val1.address);
+ assert_eq!(val_slashes.len(&shell.wl_storage).unwrap(), 2u64);
+ let is_rate_good = val_slashes
+ .iter(&shell.wl_storage)
+ .unwrap()
+ .all(|s| equal_enough(s.unwrap().rate, cubic_rate));
+ assert!(is_rate_good);
+
+ // Check the amount of stake deducted from the futuremost epoch while
+ // processing the slashes
+ let post_stake_10 = namada_proof_of_stake::read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val1.address,
+ Epoch(10),
+ )
+ .unwrap()
+ .unwrap_or_default();
+ // The amount unbonded after the infraction that affected the deltas
+ // before processing is `del_unbond_1_amount + self_bond_1_amount -
+ // self_unbond_2_amount` (since this self-bond was enacted then unbonded
+ // all after the infraction). Thus, the additional deltas to be
+ // deducted is the (infraction stake - this) * rate
+ let slash_rate_3 = std::cmp::min(Decimal::ONE, dec!(2) * cubic_rate);
+ let exp_slashed_during_processing_9 = decimal_mult_amount(
+ slash_rate_3,
+ initial_stake + del_1_amount
+ - self_unbond_1_amount
+ - del_unbond_1_amount
+ + self_bond_1_amount
+ - self_unbond_2_amount,
+ );
+ assert_eq!(
+ pre_stake_10 - post_stake_10,
+ exp_slashed_during_processing_9
+ );
+
+ // Check that we can compute the stake at the pipeline epoch
+ // NOTE: may be off. by 1 namnam due to rounding;
+ let exp_pipeline_stake = decimal_mult_amount(
+ Decimal::ONE - slash_rate_3,
+ initial_stake + del_1_amount
+ - self_unbond_1_amount
+ - del_unbond_1_amount
+ + self_bond_1_amount
+ - self_unbond_2_amount,
+ ) + del_2_amount;
+ assert!(
+ (exp_pipeline_stake.change() - post_stake_10.change()).abs() <= 1
+ );
+
+ // Check the balance of the Slash Pool
+ // TODO: finish once implemented
+ // let slash_pool_balance: token::Amount = shell
+ // .wl_storage
+ // .read(&slash_balance_key)
+ // .expect("must be able to read")
+ // .unwrap_or_default();
+ // let exp_slashed_3 = decimal_mult_amount(
+ // std::cmp::min(Decimal::TWO * cubic_rate, Decimal::ONE),
+ // val_stake_3 - del_unbond_1_amount + self_bond_1_amount
+ // - self_unbond_2_amount,
+ // );
+ // assert_eq!(slash_pool_balance, exp_slashed_3);
+
+ let _pre_stake_11 = namada_proof_of_stake::read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val1.address,
+ Epoch(10),
+ )
+ .unwrap()
+ .unwrap_or_default();
+
+ // Advance to epoch 10, where the infraction committed in epoch 4 will
+ // be processed
+ let votes = get_default_true_votes(
+ &shell.wl_storage,
+ shell.wl_storage.storage.block.epoch,
+ );
+ let current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
+ assert_eq!(current_epoch.0, 10_u64);
+
+ // Check the balance of the Slash Pool
+ // TODO: finish once implemented
+ // let slash_pool_balance: token::Amount = shell
+ // .wl_storage
+ // .read(&slash_balance_key)
+ // .expect("must be able to read")
+ // .unwrap_or_default();
+
+ // let exp_slashed_4 = if dec!(2) * cubic_rate >= Decimal::ONE {
+ // token::Amount::default()
+ // } else if dec!(3) * cubic_rate >= Decimal::ONE {
+ // decimal_mult_amount(
+ // Decimal::ONE - dec!(2) * cubic_rate,
+ // val_stake_4 + self_bond_1_amount - self_unbond_2_amount,
+ // )
+ // } else {
+ // decimal_mult_amount(
+ // std::cmp::min(cubic_rate, Decimal::ONE),
+ // val_stake_4 + self_bond_1_amount - self_unbond_2_amount,
+ // )
+ // };
+ // dbg!(slash_pool_balance, exp_slashed_3 + exp_slashed_4);
+ // assert!(
+ // (slash_pool_balance.change()
+ // - (exp_slashed_3 + exp_slashed_4).change())
+ // .abs()
+ // <= 1
+ // );
+
+ let val_stake = read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val1.address,
+ current_epoch + params.pipeline_len,
+ )?
+ .unwrap_or_default();
+
+ let post_stake_11 = namada_proof_of_stake::read_validator_stake(
+ &shell.wl_storage,
+ ¶ms,
+ &val1.address,
+ Epoch(10),
+ )
+ .unwrap()
+ .unwrap_or_default();
+
+ assert_eq!(post_stake_11, val_stake);
+ // dbg!(&val_stake);
+ // dbg!(pre_stake_10 - post_stake_10);
+
+ // dbg!(&exp_slashed_during_processing_9);
+ // TODO: finish once implemented
+ // assert!(
+ // ((pre_stake_11 - post_stake_11).change() -
+ // exp_slashed_4.change()) .abs()
+ // <= 1
+ // );
+
+ // dbg!(&val_stake, &exp_stake);
+ // dbg!(exp_slashed_during_processing_8 +
+ // exp_slashed_during_processing_9); dbg!(
+ // val_stake_3
+ // - (exp_slashed_during_processing_8 +
+ // exp_slashed_during_processing_9)
+ // );
+
+ // let exp_stake = val_stake_3 - del_unbond_1_amount +
+ // self_bond_1_amount
+ // - self_unbond_2_amount
+ // + del_2_amount
+ // - exp_slashed_3
+ // - exp_slashed_4;
+
+ // assert!((exp_stake.change() - post_stake_11.change()).abs() <= 1);
+
+ for _ in 0..2 {
+ let votes = get_default_true_votes(
+ &shell.wl_storage,
+ shell.wl_storage.storage.block.epoch,
+ );
+ let _ = advance_epoch(&mut shell, &pkh1, &votes, None);
+ }
+ let current_epoch = shell.wl_storage.storage.block.epoch;
+ assert_eq!(current_epoch.0, 12_u64);
+
+ println!("\nCHECK BOND AND UNBOND DETAILS");
+ let details = namada_proof_of_stake::bonds_and_unbonds(
+ &shell.wl_storage,
+ None,
+ None,
+ )
+ .unwrap();
+
+ let del_id = BondId {
+ source: delegator.clone(),
+ validator: val1.address.clone(),
+ };
+ let self_id = BondId {
+ source: val1.address.clone(),
+ validator: val1.address.clone(),
+ };
+
+ let del_details = details.get(&del_id).unwrap();
+ let self_details = details.get(&self_id).unwrap();
+ // dbg!(del_details, self_details);
+
+ // Check slashes
+ assert_eq!(del_details.slashes, self_details.slashes);
+ assert_eq!(del_details.slashes.len(), 3);
+ assert_eq!(del_details.slashes[0].epoch, Epoch(3));
+ assert!(equal_enough(del_details.slashes[0].rate, cubic_rate));
+ assert_eq!(del_details.slashes[1].epoch, Epoch(3));
+ assert!(equal_enough(del_details.slashes[1].rate, cubic_rate));
+ assert_eq!(del_details.slashes[2].epoch, Epoch(4));
+ assert!(equal_enough(del_details.slashes[2].rate, cubic_rate));
+
+ // Check delegations
+ assert_eq!(del_details.bonds.len(), 2);
+ assert_eq!(del_details.bonds[0].start, Epoch(3));
+ assert_eq!(
+ del_details.bonds[0].amount,
+ del_1_amount - del_unbond_1_amount
+ );
+ // TODO: decimal mult issues should be resolved with PR 1282
+ assert!(
+ (del_details.bonds[0].slashed_amount.unwrap().change()
+ - decimal_mult_amount(
+ std::cmp::min(Decimal::ONE, dec!(3) * cubic_rate),
+ del_1_amount - del_unbond_1_amount
+ )
+ .change())
+ .abs()
+ <= 2
+ );
+ assert_eq!(del_details.bonds[1].start, Epoch(7));
+ assert_eq!(del_details.bonds[1].amount, del_2_amount);
+ assert_eq!(del_details.bonds[1].slashed_amount, None);
+
+ // Check self-bonds
+ assert_eq!(self_details.bonds.len(), 1);
+ assert_eq!(self_details.bonds[0].start, Epoch(0));
+ assert_eq!(
+ self_details.bonds[0].amount,
+ initial_stake - self_unbond_1_amount + self_bond_1_amount
+ - self_unbond_2_amount
+ );
+ // TODO: not sure why this is correct??? (with + self_bond_1_amount -
+ // self_unbond_2_amount)
+ // TODO: Make sure this is sound and what we expect
+ assert_eq!(
+ self_details.bonds[0].slashed_amount,
+ Some(decimal_mult_amount(
+ std::cmp::min(Decimal::ONE, dec!(3) * cubic_rate),
+ initial_stake - self_unbond_1_amount + self_bond_1_amount
+ - self_unbond_2_amount
+ ))
+ );
+
+ // Check delegation unbonds
+ assert_eq!(del_details.unbonds.len(), 1);
+ assert_eq!(del_details.unbonds[0].start, Epoch(3));
+ assert_eq!(del_details.unbonds[0].withdraw, Epoch(9));
+ assert_eq!(del_details.unbonds[0].amount, del_unbond_1_amount);
+ assert!(
+ (del_details.unbonds[0].slashed_amount.unwrap().change()
+ - decimal_mult_amount(
+ std::cmp::min(Decimal::ONE, dec!(2) * cubic_rate),
+ del_unbond_1_amount
+ )
+ .change())
+ .abs()
+ <= 1
+ );
+
+ // Check self-unbonds
+ assert_eq!(self_details.unbonds.len(), 3);
+ assert_eq!(self_details.unbonds[0].start, Epoch(0));
+ assert_eq!(self_details.unbonds[0].withdraw, Epoch(8));
+ assert_eq!(self_details.unbonds[1].start, Epoch(0));
+ assert_eq!(self_details.unbonds[1].withdraw, Epoch(11));
+ assert_eq!(self_details.unbonds[2].start, Epoch(5));
+ assert_eq!(self_details.unbonds[2].withdraw, Epoch(11));
+ assert_eq!(self_details.unbonds[0].amount, self_unbond_1_amount);
+ assert_eq!(self_details.unbonds[0].slashed_amount, None);
+ assert_eq!(
+ self_details.unbonds[1].amount,
+ self_unbond_2_amount - self_bond_1_amount
+ );
+ assert_eq!(
+ self_details.unbonds[1].slashed_amount,
+ Some(decimal_mult_amount(
+ std::cmp::min(Decimal::ONE, dec!(3) * cubic_rate),
+ self_unbond_2_amount - self_bond_1_amount
+ ))
+ );
+ assert_eq!(self_details.unbonds[2].amount, self_bond_1_amount);
+ assert_eq!(self_details.unbonds[2].slashed_amount, None);
+
+ println!("\nWITHDRAWING DELEGATION UNBOND");
+ // let slash_pool_balance_pre_withdraw = slash_pool_balance;
+ // Withdraw the delegation unbonds, which total to 18_000. This should
+ // only be affected by the slashes in epoch 3
+ let del_withdraw = namada_proof_of_stake::withdraw_tokens(
+ &mut shell.wl_storage,
+ Some(&delegator),
+ &val1.address,
+ current_epoch,
+ )
+ .unwrap();
+
+ let exp_del_withdraw_slashed_amount =
+ decimal_mult_amount(slash_rate_3, del_unbond_1_amount);
+ assert_eq!(
+ del_withdraw,
+ del_unbond_1_amount - exp_del_withdraw_slashed_amount
+ );
+
+ // TODO: finish once implemented
+ // Check the balance of the Slash Pool
+ // let slash_pool_balance: token::Amount = shell
+ // .wl_storage
+ // .read(&slash_balance_key)
+ // .expect("must be able to read")
+ // .unwrap_or_default();
+ // dbg!(del_withdraw, slash_pool_balance);
+ // assert_eq!(
+ // slash_pool_balance - slash_pool_balance_pre_withdraw,
+ // exp_del_withdraw_slashed_amount
+ // );
+
+ // println!("\nWITHDRAWING SELF UNBOND");
+ // Withdraw the self unbonds, which total 154_654 + 15_000 - 9_123. Only
+ // the (15_000 - 9_123) tokens are slashable.
+ // let self_withdraw = namada_proof_of_stake::withdraw_tokens(
+ // &mut shell.wl_storage,
+ // None,
+ // &val1.address,
+ // current_epoch,
+ // )
+ // .unwrap();
+
+ // let exp_self_withdraw_slashed_amount = decimal_mult_amount(
+ // std::cmp::min(dec!(3) * cubic_rate, Decimal::ONE),
+ // self_unbond_2_amount - self_bond_1_amount,
+ // );
+ // Check the balance of the Slash Pool
+ // let slash_pool_balance: token::Amount = shell
+ // .wl_storage
+ // .read(&slash_balance_key)
+ // .expect("must be able to read")
+ // .unwrap_or_default();
+
+ // dbg!(self_withdraw, slash_pool_balance);
+ // dbg!(
+ // decimal_mult_amount(dec!(2) * cubic_rate, val_stake_3)
+ // + decimal_mult_amount(cubic_rate, val_stake_4)
+ // );
+
+ // assert_eq!(
+ // exp_self_withdraw_slashed_amount,
+ // slash_pool_balance
+ // - slash_pool_balance_pre_withdraw
+ // - exp_del_withdraw_slashed_amount
+ // );
+
+ Ok(())
+ }
+
+ fn get_default_true_votes(storage: &S, epoch: Epoch) -> Vec
+ where
+ S: StorageRead,
+ {
+ let params = read_pos_params(storage).unwrap();
+ read_consensus_validator_set_addresses_with_stake(storage, epoch)
+ .unwrap()
+ .into_iter()
+ .map(|val| {
+ let pkh = get_pkh_from_address(
+ storage,
+ ¶ms,
+ val.address.clone(),
+ epoch,
+ );
+ VoteInfo {
+ validator: Some(Validator {
+ address: pkh,
+ power: u64::from(val.bonded_stake) as i64,
+ }),
+ signed_last_block: true,
+ }
+ })
+ .collect::>()
+ }
+
+ fn advance_epoch(
+ shell: &mut TestShell,
+ proposer_address: &[u8],
+ consensus_votes: &[VoteInfo],
+ misbehaviors: Option>,
+ ) -> Epoch {
+ let current_epoch = shell.wl_storage.storage.block.epoch;
+ loop {
+ next_block_for_inflation(
+ shell,
+ proposer_address.to_owned(),
+ consensus_votes.to_owned(),
+ misbehaviors.clone(),
+ );
+ if shell.wl_storage.storage.block.epoch == current_epoch.next() {
+ break;
+ }
+ }
+ shell.wl_storage.storage.block.epoch
+ }
+
+ fn get_pkh_from_address(
+ storage: &S,
+ params: &PosParams,
+ address: Address,
+ epoch: Epoch,
+ ) -> Vec
+ where
+ S: StorageRead,
+ {
+ let ck = validator_consensus_key_handle(&address)
+ .get(storage, epoch, params)
+ .unwrap()
+ .unwrap();
+ let hash_string = tm_consensus_key_raw_hash(&ck);
+ HEXUPPER.decode(hash_string.as_bytes()).unwrap()
+ }
}
diff --git a/apps/src/lib/node/ledger/shell/governance.rs b/apps/src/lib/node/ledger/shell/governance.rs
index dfdae4d04e..9ff5ebc279 100644
--- a/apps/src/lib/node/ledger/shell/governance.rs
+++ b/apps/src/lib/node/ledger/shell/governance.rs
@@ -12,6 +12,7 @@ use namada::ledger::storage::types::encode;
use namada::ledger::storage::{DBIter, StorageHasher, DB};
use namada::ledger::storage_api::{token, StorageWrite};
use namada::proof_of_stake::read_total_stake;
+use namada::proto::{Code, Data};
use namada::types::address::Address;
use namada::types::governance::{Council, Tally, TallyResult, VotePower};
use namada::types::storage::Epoch;
@@ -147,17 +148,13 @@ where
let proposal_code = shell.read_storage_key_bytes(&proposal_code_key);
match proposal_code {
Some(proposal_code) => {
- let tx = Tx::new(
- proposal_code,
- Some(encode(&id)),
- shell.chain_id.clone(),
- None,
- );
- let tx_type = TxType::Decrypted(DecryptedTx::Decrypted {
- tx,
+ let mut tx = Tx::new(TxType::Decrypted(DecryptedTx::Decrypted {
#[cfg(not(feature = "mainnet"))]
has_valid_pow: false,
- });
+ }));
+ tx.header.chain_id = shell.chain_id.clone();
+ tx.set_data(Data::new(encode(&id)));
+ tx.set_code(Code::new(proposal_code));
let pending_execution_key =
gov_storage::get_proposal_execution_key(id);
shell
@@ -165,7 +162,7 @@ where
.write(&pending_execution_key, ())
.expect("Should be able to write to storage.");
let tx_result = protocol::apply_tx(
- tx_type,
+ tx,
0, /* this is used to compute the fee
* based on the code size. We dont
* need it here. */
diff --git a/apps/src/lib/node/ledger/shell/init_chain.rs b/apps/src/lib/node/ledger/shell/init_chain.rs
index 58891c3b4e..5c77171277 100644
--- a/apps/src/lib/node/ledger/shell/init_chain.rs
+++ b/apps/src/lib/node/ledger/shell/init_chain.rs
@@ -33,7 +33,7 @@ where
pub fn init_chain(
&mut self,
init: request::InitChain,
- #[cfg(feature = "dev")] num_validators: u64,
+ #[cfg(any(test, feature = "dev"))] num_validators: u64,
) -> Result {
let mut response = response::InitChain::default();
let (current_chain_id, _) = self.wl_storage.storage.get_chain_id();
@@ -43,10 +43,10 @@ where
current_chain_id, init.chain_id
)));
}
- #[cfg(not(feature = "dev"))]
+ #[cfg(not(any(test, feature = "dev")))]
let genesis =
genesis::genesis(&self.base_dir, &self.wl_storage.storage.chain_id);
- #[cfg(not(feature = "dev"))]
+ #[cfg(not(any(test, feature = "dev")))]
{
let genesis_bytes = genesis.try_to_vec().unwrap();
let errors =
@@ -58,7 +58,7 @@ where
errors.into_iter().format(". ")
);
}
- #[cfg(feature = "dev")]
+ #[cfg(any(test, feature = "dev"))]
let genesis = genesis::genesis(num_validators);
let ts: protobuf::Timestamp = init.time.expect("Missing genesis time");
@@ -480,11 +480,9 @@ where
#[cfg(test)]
mod test {
use std::collections::BTreeMap;
- use std::str::FromStr;
use namada::ledger::storage::DBIter;
use namada::types::chain::ChainId;
- use namada::types::storage;
use crate::facade::tendermint_proto::abci::RequestInitChain;
use crate::facade::tendermint_proto::google::protobuf::Timestamp;
@@ -498,12 +496,11 @@ mod test {
// Collect all storage key-vals into a sorted map
let store_block_state = |shell: &TestShell| -> BTreeMap<_, _> {
- let prefix: storage::Key = FromStr::from_str("").unwrap();
shell
.wl_storage
.storage
.db
- .iter_prefix(&prefix)
+ .iter_optional_prefix(None)
.map(|(key, val, _gas)| (key, val))
.collect()
};
diff --git a/apps/src/lib/node/ledger/shell/mod.rs b/apps/src/lib/node/ledger/shell/mod.rs
index a83059edac..7c90997fce 100644
--- a/apps/src/lib/node/ledger/shell/mod.rs
+++ b/apps/src/lib/node/ledger/shell/mod.rs
@@ -30,15 +30,15 @@ use namada::ledger::pos::namada_proof_of_stake::types::{
};
use namada::ledger::storage::write_log::WriteLog;
use namada::ledger::storage::{
- DBIter, Sha256Hasher, Storage, StorageHasher, WlStorage, DB,
+ DBIter, Sha256Hasher, Storage, StorageHasher, TempWlStorage, WlStorage, DB,
};
-use namada::ledger::storage_api::{self, StorageRead};
+use namada::ledger::storage_api::{self, StorageRead, StorageWrite};
use namada::ledger::{ibc, pos, protocol, replay_protection};
-use namada::proof_of_stake::{self, read_pos_params, slash};
-use namada::proto::{self, Tx};
+use namada::proof_of_stake::{self, process_slashes, read_pos_params, slash};
+use namada::proto::{self, Section, Tx};
use namada::types::address::{masp, masp_tx_key, Address};
use namada::types::chain::ChainId;
-use namada::types::internal::WrapperTxInQueue;
+use namada::types::internal::TxInQueue;
use namada::types::key::*;
use namada::types::storage::{BlockHeight, Key, TxIndex};
use namada::types::time::{DateTimeUtc, TimeZone, Utc};
@@ -46,7 +46,7 @@ use namada::types::token::{self};
#[cfg(not(feature = "mainnet"))]
use namada::types::transaction::MIN_FEE;
use namada::types::transaction::{
- hash_tx, process_tx, verify_decrypted_correctly, AffineCurve, DecryptedTx,
+ hash_tx, verify_decrypted_correctly, AffineCurve, DecryptedTx,
EllipticCurve, PairingEngine, TxType,
};
use namada::types::{address, hash};
@@ -112,6 +112,8 @@ pub enum Error {
LoadingWasm(String),
#[error("Error reading from or writing to storage: {0}")]
StorageApi(#[from] storage_api::Error),
+ #[error("Transaction replay attempt: {0}")]
+ ReplayAttempt(String),
}
impl From for TxResult {
@@ -184,8 +186,7 @@ pub fn reset(config: config::Ledger) -> Result<()> {
res => res.map_err(Error::RemoveDB)?,
};
// reset Tendermint state
- tendermint_node::reset(config.tendermint_dir())
- .map_err(Error::Tendermint)?;
+ tendermint_node::reset(config.cometbft_dir()).map_err(Error::Tendermint)?;
Ok(())
}
@@ -193,7 +194,7 @@ pub fn rollback(config: config::Ledger) -> Result<()> {
// Rollback Tendermint state
tracing::info!("Rollback Tendermint state");
let tendermint_block_height =
- tendermint_node::rollback(config.tendermint_dir())
+ tendermint_node::rollback(config.cometbft_dir())
.map_err(Error::Tendermint)?;
// Rollback Namada state
@@ -293,7 +294,7 @@ where
let chain_id = config.chain_id;
let db_path = config.shell.db_dir(&chain_id);
let base_dir = config.shell.base_dir;
- let mode = config.tendermint.tendermint_mode;
+ let mode = config.shell.tendermint_mode;
let storage_read_past_height_limit =
config.shell.storage_read_past_height_limit;
if !Path::new(&base_dir).is_dir() {
@@ -411,7 +412,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.wl_storage.storage.tx_queue.iter()
}
@@ -491,7 +492,7 @@ where
}
/// Apply PoS slashes from the evidence
- fn slash(&mut self) {
+ fn record_slashes_from_evidence(&mut self) {
if !self.byzantine_validators.is_empty() {
let byzantine_validators =
mem::take(&mut self.byzantine_validators);
@@ -499,6 +500,7 @@ where
let pos_params = read_pos_params(&self.wl_storage).unwrap();
let current_epoch = self.wl_storage.storage.block.epoch;
for evidence in byzantine_validators {
+ // dbg!(&evidence);
tracing::info!("Processing evidence {evidence:?}.");
let evidence_height = match u64::try_from(evidence.height) {
Ok(height) => height,
@@ -526,7 +528,12 @@ where
continue;
}
};
- if evidence_epoch + pos_params.unbonding_len <= current_epoch {
+ // Disregard evidences that should have already been processed
+ // at this time
+ if evidence_epoch + pos_params.slash_processing_epoch_offset()
+ - pos_params.cubic_slashing_window_length
+ <= current_epoch
+ {
tracing::info!(
"Skipping outdated evidence from epoch \
{evidence_epoch}"
@@ -585,11 +592,13 @@ where
}
};
tracing::info!(
- "Slashing {} for {} in epoch {}, block height {}",
+ "Slashing {} for {} in epoch {}, block height {} (current \
+ epoch = {})",
validator,
slash_type,
evidence_epoch,
- evidence_height
+ evidence_height,
+ current_epoch
);
if let Err(err) = slash(
&mut self.wl_storage,
@@ -606,6 +615,19 @@ where
}
}
+ /// Process and apply slashes that have already been recorded for the
+ /// current epoch
+ fn process_slashes(&mut self) {
+ let current_epoch = self.wl_storage.storage.block.epoch;
+ if let Err(err) = process_slashes(&mut self.wl_storage, current_epoch) {
+ tracing::error!(
+ "Error while processing slashes queued for epoch {}: {}",
+ current_epoch,
+ err
+ );
+ }
+ }
+
/// INVARIANT: This method must be stateless.
#[cfg(feature = "abcipp")]
pub fn extend_vote(
@@ -642,12 +664,62 @@ where
tracing::info!(
"Committed block hash: {}, height: {}",
root,
- self.wl_storage.storage.last_height,
+ self.wl_storage.storage.get_last_block_height(),
);
response.data = root.0;
response
}
+ /// Checks that neither the wrapper nor the inner transaction have already
+ /// been applied. Requires a [`TempWlStorage`] to perform the check during
+ /// block construction and validation
+ pub fn replay_protection_checks(
+ &self,
+ wrapper: &Tx,
+ tx_bytes: &[u8],
+ temp_wl_storage: &mut TempWlStorage,
+ ) -> Result<()> {
+ let inner_tx_hash =
+ wrapper.clone().update_header(TxType::Raw).header_hash();
+ let inner_hash_key = replay_protection::get_tx_hash_key(&inner_tx_hash);
+ if temp_wl_storage
+ .has_key(&inner_hash_key)
+ .expect("Error while checking inner tx hash key in storage")
+ {
+ return Err(Error::ReplayAttempt(format!(
+ "Inner transaction hash {} already in storage",
+ &inner_tx_hash,
+ )));
+ }
+
+ // Write inner hash to WAL
+ temp_wl_storage
+ .write(&inner_hash_key, ())
+ .expect("Couldn't write inner transaction hash to write log");
+
+ let tx =
+ Tx::try_from(tx_bytes).expect("Deserialization shouldn't fail");
+ let wrapper_hash = tx.header_hash();
+ let wrapper_hash_key =
+ replay_protection::get_tx_hash_key(&wrapper_hash);
+ if temp_wl_storage
+ .has_key(&wrapper_hash_key)
+ .expect("Error while checking wrapper tx hash key in storage")
+ {
+ return Err(Error::ReplayAttempt(format!(
+ "Wrapper transaction hash {} already in storage",
+ wrapper_hash
+ )));
+ }
+
+ // Write wrapper hash to WAL
+ temp_wl_storage
+ .write(&wrapper_hash_key, ())
+ .expect("Couldn't write wrapper tx hash to write log");
+
+ Ok(())
+ }
+
/// Validate a transaction request. On success, the transaction will
/// included in the mempool and propagated to peers, otherwise it will be
/// rejected.
@@ -676,17 +748,17 @@ where
};
// Tx chain id
- if tx.chain_id != self.chain_id {
+ if tx.header.chain_id != self.chain_id {
response.code = ErrorCodes::InvalidChainId.into();
response.log = format!(
"Tx carries a wrong chain id: expected {}, found {}",
- self.chain_id, tx.chain_id
+ self.chain_id, tx.header.chain_id
);
return response;
}
// Tx expiration
- if let Some(exp) = tx.expiration {
+ if let Some(exp) = tx.header.expiration {
let last_block_timestamp = self.get_block_timestamp(None);
if last_block_timestamp > exp {
@@ -700,8 +772,8 @@ where
}
// Tx signature check
- let tx_type = match process_tx(tx) {
- Ok(ty) => ty,
+ let tx_type = match tx.validate_header() {
+ Ok(()) => tx.header(),
Err(msg) => {
response.code = ErrorCodes::InvalidSig.into();
response.log = msg.to_string();
@@ -710,10 +782,13 @@ where
};
// Tx type check
- if let TxType::Wrapper(wrapper) = tx_type {
+ if let TxType::Wrapper(wrapper) = tx_type.tx_type {
// Replay protection check
+ let mut inner_tx = tx;
+ inner_tx.update_header(TxType::Raw);
+ let inner_tx_hash = &inner_tx.header_hash();
let inner_hash_key =
- replay_protection::get_tx_hash_key(&wrapper.tx_hash);
+ replay_protection::get_tx_hash_key(inner_tx_hash);
if self
.wl_storage
.storage
@@ -725,14 +800,14 @@ where
response.log = format!(
"Inner transaction hash {} already in storage, replay \
attempt",
- wrapper.tx_hash
+ inner_tx_hash
);
return response;
}
let tx =
Tx::try_from(tx_bytes).expect("Deserialization shouldn't fail");
- let wrapper_hash = hash::Hash(tx.unsigned_hash());
+ let wrapper_hash = hash::Hash(tx.header_hash().0);
let wrapper_hash_key =
replay_protection::get_tx_hash_key(&wrapper_hash);
if self
@@ -796,13 +871,6 @@ 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,
- #[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(),
@@ -933,6 +1001,7 @@ mod test_utils {
use namada::ledger::storage::mockdb::MockDB;
use namada::ledger::storage::{update_allowed_conversions, Sha256Hasher};
+ use namada::proto::{Code, Data};
use namada::types::address::init_token_storage;
use namada::types::chain::ChainId;
use namada::types::hash::Hash;
@@ -1042,7 +1111,7 @@ mod test_utils {
pub fn init_chain(
&mut self,
req: RequestInitChain,
- #[cfg(feature = "dev")] num_validators: u64,
+ num_validators: u64,
) {
self.shell
.init_chain(req, num_validators)
@@ -1090,16 +1159,12 @@ mod test_utils {
/// Add a wrapper tx to the queue of txs to be decrypted
/// in the current block proposal
#[cfg(test)]
- pub fn enqueue_tx(&mut self, wrapper: WrapperTx) {
- self.shell
- .wl_storage
- .storage
- .tx_queue
- .push(WrapperTxInQueue {
- tx: wrapper,
- #[cfg(not(feature = "mainnet"))]
- has_valid_pow: false,
- });
+ pub fn enqueue_tx(&mut self, tx: Tx) {
+ self.shell.wl_storage.storage.tx_queue.push(TxInQueue {
+ tx,
+ #[cfg(not(feature = "mainnet"))]
+ has_valid_pow: false,
+ });
}
}
@@ -1174,13 +1239,7 @@ mod test_utils {
init_token_storage(&mut shell.wl_storage, 60);
let keypair = gen_keypair();
// enqueue a wrapper tx
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: native_token,
@@ -1188,12 +1247,15 @@ mod test_utils {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- shell.wl_storage.storage.tx_queue.push(WrapperTxInQueue {
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ wrapper.encrypt(&Default::default());
+
+ shell.wl_storage.storage.tx_queue.push(TxInQueue {
tx: wrapper,
#[cfg(not(feature = "mainnet"))]
has_valid_pow: false,
@@ -1231,7 +1293,7 @@ mod test_utils {
#[cfg(test)]
mod test_mempool_validate {
use namada::proof_of_stake::Epoch;
- use namada::proto::SignedTxData;
+ use namada::proto::{Code, Data, Section, Signature, Tx};
use namada::types::transaction::{Fee, WrapperTx};
use super::test_utils::TestShell;
@@ -1244,41 +1306,23 @@ mod test_mempool_validate {
let keypair = super::test_utils::gen_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
-
- let mut wrapper = WrapperTx::new(
- Fee {
- amount: 100.into(),
- token: shell.wl_storage.storage.native_token.clone(),
- },
- &keypair,
- Epoch(0),
- 0.into(),
- tx,
- Default::default(),
- #[cfg(not(feature = "mainnet"))]
- None,
- )
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Wrapper signing failed");
-
- let unsigned_wrapper = if let Some(Ok(SignedTxData {
- data: Some(data),
- sig: _,
- })) = wrapper
- .data
- .take()
- .map(|data| SignedTxData::try_from_slice(&data[..]))
- {
- Tx::new(vec![], Some(data), shell.chain_id.clone(), None)
- } else {
- panic!("Test failed")
- };
+ let mut unsigned_wrapper =
+ Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: 100.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair,
+ Epoch(0),
+ 0.into(),
+ #[cfg(not(feature = "mainnet"))]
+ None,
+ ))));
+ unsigned_wrapper.header.chain_id = shell.chain_id.clone();
+ unsigned_wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ unsigned_wrapper
+ .set_data(Data::new("transaction data".as_bytes().to_owned()));
+ unsigned_wrapper.encrypt(&Default::default());
let mut result = shell.mempool_validate(
unsigned_wrapper.to_bytes().as_ref(),
@@ -1299,67 +1343,33 @@ mod test_mempool_validate {
let keypair = super::test_utils::gen_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
-
- let mut wrapper = WrapperTx::new(
- Fee {
- amount: 100.into(),
- token: shell.wl_storage.storage.native_token.clone(),
- },
+ let mut invalid_wrapper =
+ Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: 100.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair,
+ Epoch(0),
+ 0.into(),
+ #[cfg(not(feature = "mainnet"))]
+ None,
+ ))));
+ invalid_wrapper.header.chain_id = shell.chain_id.clone();
+ invalid_wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ invalid_wrapper
+ .set_data(Data::new("transaction data".as_bytes().to_owned()));
+ invalid_wrapper.add_section(Section::Signature(Signature::new(
+ &invalid_wrapper.header_hash(),
&keypair,
- Epoch(0),
- 0.into(),
- tx,
- Default::default(),
- #[cfg(not(feature = "mainnet"))]
- None,
- )
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Wrapper signing failed");
-
- let invalid_wrapper = if let Some(Ok(SignedTxData {
- data: Some(data),
- sig,
- })) = wrapper
- .data
- .take()
- .map(|data| SignedTxData::try_from_slice(&data[..]))
- {
- let mut new_wrapper = if let TxType::Wrapper(wrapper) =
- ::deserialize(&mut data.as_ref())
- .expect("Test failed")
- {
- wrapper
- } else {
- panic!("Test failed")
- };
+ )));
+ invalid_wrapper.encrypt(&Default::default());
- // we mount a malleability attack to try and remove the fee
- new_wrapper.fee.amount = 0.into();
- let new_data = TxType::Wrapper(new_wrapper)
- .try_to_vec()
- .expect("Test failed");
- Tx::new(
- vec![],
- Some(
- SignedTxData {
- sig,
- data: Some(new_data),
- }
- .try_to_vec()
- .expect("Test failed"),
- ),
- shell.chain_id.clone(),
- None,
- )
- } else {
- panic!("Test failed");
- };
+ // we mount a malleability attack to try and remove the fee
+ let mut new_wrapper =
+ invalid_wrapper.header().wrapper().expect("Test failed");
+ new_wrapper.fee.amount = 0.into();
+ invalid_wrapper.update_header(TxType::Wrapper(Box::new(new_wrapper)));
let mut result = shell.mempool_validate(
invalid_wrapper.to_bytes().as_ref(),
@@ -1379,12 +1389,9 @@ mod test_mempool_validate {
let (shell, _) = TestShell::new();
// Test Raw TxType
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- None,
- shell.chain_id.clone(),
- None,
- );
+ let mut tx = Tx::new(TxType::Raw);
+ tx.header.chain_id = shell.chain_id.clone();
+ tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
let result = shell.mempool_validate(
tx.to_bytes().as_ref(),
@@ -1402,14 +1409,7 @@ mod test_mempool_validate {
let keypair = super::test_utils::gen_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
-
- let wrapper = WrapperTx::new(
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 100.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -1417,27 +1417,26 @@ mod test_mempool_validate {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- )
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Wrapper signing failed");
-
- let tx_type = match process_tx(wrapper.clone()).expect("Test failed") {
- TxType::Wrapper(t) => t,
- _ => panic!("Test failed"),
- };
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ wrapper.add_section(Section::Signature(Signature::new(
+ &wrapper.header_hash(),
+ &keypair,
+ )));
+ wrapper.encrypt(&Default::default());
// Write wrapper hash to storage
- let wrapper_hash = hash::Hash(wrapper.unsigned_hash());
+ let wrapper_hash = wrapper.header_hash();
let wrapper_hash_key =
replay_protection::get_tx_hash_key(&wrapper_hash);
shell
.wl_storage
.storage
- .write(&wrapper_hash_key, &wrapper_hash)
+ .write(&wrapper_hash_key, wrapper_hash)
.expect("Test failed");
// Try wrapper tx replay attack
@@ -1469,13 +1468,14 @@ mod test_mempool_validate {
)
);
+ let inner_tx_hash =
+ wrapper.clone().update_header(TxType::Raw).header_hash();
// Write inner hash in storage
- let inner_hash_key =
- replay_protection::get_tx_hash_key(&tx_type.tx_hash);
+ let inner_hash_key = replay_protection::get_tx_hash_key(&inner_tx_hash);
shell
.wl_storage
.storage
- .write(&inner_hash_key, &tx_type.tx_hash)
+ .write(&inner_hash_key, inner_tx_hash)
.expect("Test failed");
// Try inner tx replay attack
@@ -1488,7 +1488,7 @@ mod test_mempool_validate {
result.log,
format!(
"Inner transaction hash {} already in storage, replay attempt",
- tx_type.tx_hash
+ inner_tx_hash
)
);
@@ -1501,7 +1501,7 @@ mod test_mempool_validate {
result.log,
format!(
"Inner transaction hash {} already in storage, replay attempt",
- tx_type.tx_hash
+ inner_tx_hash
)
)
}
@@ -1514,13 +1514,14 @@ mod test_mempool_validate {
let keypair = super::test_utils::gen_keypair();
let wrong_chain_id = ChainId("Wrong chain id".to_string());
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- wrong_chain_id.clone(),
- None,
- )
- .sign(&keypair);
+ let mut tx = Tx::new(TxType::Raw);
+ tx.header.chain_id = wrong_chain_id.clone();
+ tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ tx.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ tx.add_section(Section::Signature(Signature::new(
+ &tx.header_hash(),
+ &keypair,
+ )));
let result = shell.mempool_validate(
tx.to_bytes().as_ref(),
@@ -1543,13 +1544,15 @@ mod test_mempool_validate {
let keypair = super::test_utils::gen_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- Some(DateTimeUtc::now()),
- )
- .sign(&keypair);
+ let mut tx = Tx::new(TxType::Raw);
+ tx.header.expiration = Some(DateTimeUtc::now());
+ tx.header.chain_id = shell.chain_id.clone();
+ tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ tx.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ tx.add_section(Section::Signature(Signature::new(
+ &tx.header_hash(),
+ &keypair,
+ )));
let result = shell.mempool_validate(
tx.to_bytes().as_ref(),
diff --git a/apps/src/lib/node/ledger/shell/prepare_proposal.rs b/apps/src/lib/node/ledger/shell/prepare_proposal.rs
index d48d5cfcec..9a9aa58491 100644
--- a/apps/src/lib/node/ledger/shell/prepare_proposal.rs
+++ b/apps/src/lib/node/ledger/shell/prepare_proposal.rs
@@ -1,14 +1,15 @@
//! Implementation of the [`RequestPrepareProposal`] ABCI++ method for the Shell
use namada::core::hints;
-use namada::ledger::storage::{DBIter, StorageHasher, DB};
+use namada::ledger::storage::{DBIter, StorageHasher, TempWlStorage, DB};
use namada::proof_of_stake::pos_queries::PosQueries;
use namada::proto::Tx;
-use namada::types::internal::WrapperTxInQueue;
+use namada::types::internal::TxInQueue;
use namada::types::time::DateTimeUtc;
-use namada::types::transaction::tx_types::TxType;
use namada::types::transaction::wrapper::wrapper_tx::PairingEngine;
-use namada::types::transaction::{AffineCurve, DecryptedTx, EllipticCurve};
+use namada::types::transaction::{
+ AffineCurve, DecryptedTx, EllipticCurve, TxType,
+};
use super::super::*;
#[allow(unused_imports)]
@@ -21,8 +22,9 @@ use super::block_space_alloc::{AllocFailure, BlockSpaceAllocator};
#[cfg(feature = "abcipp")]
use crate::facade::tendermint_proto::abci::ExtendedCommitInfo;
use crate::facade::tendermint_proto::abci::RequestPrepareProposal;
+#[cfg(feature = "abcipp")]
+use crate::facade::tendermint_proto::abci::{tx_record::TxAction, TxRecord};
use crate::facade::tendermint_proto::google::protobuf::Timestamp;
-use crate::node::ledger::shell::{process_tx, ShellMode};
use crate::node::ledger::shims::abcipp_shim_types::shim::{response, TxBytes};
impl Shell
@@ -42,33 +44,30 @@ where
&self,
req: RequestPrepareProposal,
) -> response::PrepareProposal {
- let txs = if let ShellMode::Validator { .. } = self.mode {
- // start counting allotted space for txs
- let alloc = self.get_encrypted_txs_allocator();
-
- // add encrypted txs
- let (encrypted_txs, alloc) =
- self.build_encrypted_txs(alloc, &req.txs, &req.time);
- let mut txs = encrypted_txs;
-
- // decrypt the wrapper txs included in the previous block
- let (mut decrypted_txs, alloc) = self.build_decrypted_txs(alloc);
- txs.append(&mut decrypted_txs);
-
- // add vote extension protocol txs
- let mut protocol_txs = self.build_protocol_txs(
- alloc,
- #[cfg(feature = "abcipp")]
- req.local_last_commit,
- #[cfg(not(feature = "abcipp"))]
- &req.txs,
- );
- txs.append(&mut protocol_txs);
+ // start counting allotted space for txs
+ let alloc = self.get_encrypted_txs_allocator();
+ // add encrypted txs
+ let (encrypted_txs, alloc) = self.build_encrypted_txs(
+ alloc,
+ TempWlStorage::new(&self.wl_storage.storage),
+ &req.txs,
+ &req.time,
+ );
+ let mut txs = encrypted_txs;
- txs
- } else {
- vec![]
- };
+ // decrypt the wrapper txs included in the previous block
+ let (mut decrypted_txs, alloc) = self.build_decrypted_txs(alloc);
+ txs.append(&mut decrypted_txs);
+
+ // add vote extension protocol txs
+ let mut protocol_txs = self.build_protocol_txs(
+ alloc,
+ #[cfg(feature = "abcipp")]
+ req.local_last_commit,
+ #[cfg(not(feature = "abcipp"))]
+ &req.txs,
+ );
+ txs.append(&mut protocol_txs);
tracing::info!(
height = req.height,
@@ -119,6 +118,7 @@ where
fn build_encrypted_txs(
&self,
mut alloc: EncryptedTxBatchAllocator,
+ mut temp_wl_storage: TempWlStorage,
txs: &[TxBytes],
block_time: &Option,
) -> (Vec, BlockSpaceAllocator) {
@@ -135,10 +135,10 @@ where
// If tx doesn't have an expiration it is valid. If time cannot be
// retrieved from block default to last block datetime which has
// already been checked by mempool_validate, so it's valid
- if let (Some(block_time), Some(exp)) = (block_time.as_ref(), &tx.expiration) {
+ if let (Some(block_time), Some(exp)) = (block_time.as_ref(), &tx.header.expiration) {
if block_time > exp { return None }
}
- if let Ok(TxType::Wrapper(_)) = process_tx(tx) {
+ if tx.validate_header().is_ok() && tx.header().wrapper().is_some() && self.replay_protection_checks(&tx, tx_bytes.as_slice(), &mut temp_wl_storage).is_ok() {
return Some(tx_bytes.clone());
}
}
@@ -195,7 +195,6 @@ where
// TODO: This should not be hardcoded
let privkey =
::G2Affine::prime_subgroup_generator();
-
let pos_queries = self.wl_storage.pos_queries();
let txs = self
.wl_storage
@@ -203,20 +202,30 @@ where
.tx_queue
.iter()
.map(
- |WrapperTxInQueue {
+ |TxInQueue {
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,
+ }| {
+ let mut tx = tx.clone();
+ match tx.decrypt(privkey).ok()
+ {
+ Some(()) => {
+ tx.update_header(TxType::Decrypted(DecryptedTx::Decrypted {
+ #[cfg(not(feature = "mainnet"))]
+ has_valid_pow: *has_valid_pow,
+ }));
+ tx
+ },
+ // An absent or undecryptable inner_tx are both
+ // treated as undecryptable
+ None => {
+ tx.update_header(TxType::Decrypted(
+ DecryptedTx::Undecryptable
+ ));
+ tx
},
- _ => DecryptedTx::Undecryptable(tx.clone()),
- })
- .to_bytes()
+ }.to_bytes()
},
)
// TODO: make sure all decrypted txs are accepted
@@ -271,7 +280,9 @@ where
mod test_prepare_proposal {
use borsh::BorshSerialize;
+ use namada::ledger::replay_protection;
use namada::proof_of_stake::Epoch;
+ use namada::proto::{Code, Data, Header, Section, Signature};
use namada::types::transaction::{Fee, WrapperTx};
use super::*;
@@ -283,12 +294,10 @@ mod test_prepare_proposal {
#[test]
fn test_prepare_proposal_rejects_non_wrapper_tx() {
let (shell, _) = test_utils::setup(1);
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction_data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
+ let mut tx = Tx::new(TxType::Decrypted(DecryptedTx::Decrypted {
+ has_valid_pow: true,
+ }));
+ tx.header.chain_id = shell.chain_id.clone();
let req = RequestPrepareProposal {
txs: vec![tx.to_bytes()],
..Default::default()
@@ -303,36 +312,23 @@ mod test_prepare_proposal {
fn test_error_in_processing_tx() {
let (shell, _) = test_utils::setup(1);
let keypair = gen_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction_data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
// an unsigned wrapper will cause an error in processing
- let wrapper = Tx::new(
- "".as_bytes().to_owned(),
- Some(
- WrapperTx::new(
- Fee {
- amount: 0.into(),
- token: shell.wl_storage.storage.native_token.clone(),
- },
- &keypair,
- Epoch(0),
- 0.into(),
- tx,
- Default::default(),
- #[cfg(not(feature = "mainnet"))]
- None,
- )
- .try_to_vec()
- .expect("Test failed"),
- ),
- shell.chain_id.clone(),
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: 0.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair,
+ Epoch(0),
+ 0.into(),
+ #[cfg(not(feature = "mainnet"))]
None,
- )
- .to_bytes();
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper.set_data(Data::new("transaction_data".as_bytes().to_owned()));
+ wrapper.encrypt(&Default::default());
+ let wrapper = wrapper.to_bytes();
#[allow(clippy::redundant_clone)]
let req = RequestPrepareProposal {
txs: vec![wrapper.clone()],
@@ -358,18 +354,7 @@ mod test_prepare_proposal {
// create a request with two new wrappers from mempool and
// two wrappers from the previous block to be decrypted
for i in 0..2 {
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some(format!("transaction data: {}", i).as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- expected_decrypted.push(Tx::from(DecryptedTx::Decrypted {
- tx: tx.clone(),
- #[cfg(not(feature = "mainnet"))]
- has_valid_pow: false,
- }));
- let wrapper_tx = WrapperTx::new(
+ let mut tx = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -377,54 +362,161 @@ mod test_prepare_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- let wrapper = wrapper_tx
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Test failed");
- shell.enqueue_tx(wrapper_tx);
- expected_wrapper.push(wrapper.clone());
- req.txs.push(wrapper.to_bytes());
+ ))));
+ tx.header.chain_id = shell.chain_id.clone();
+ tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ tx.set_data(Data::new(
+ format!("transaction data: {}", i).as_bytes().to_owned(),
+ ));
+ tx.add_section(Section::Signature(Signature::new(
+ &tx.header_hash(),
+ &keypair,
+ )));
+ tx.encrypt(&Default::default());
+
+ shell.enqueue_tx(tx.clone());
+ expected_wrapper.push(tx.clone());
+ req.txs.push(tx.to_bytes());
+ tx.update_header(TxType::Decrypted(DecryptedTx::Decrypted {
+ #[cfg(not(feature = "mainnet"))]
+ has_valid_pow: false,
+ }));
+ expected_decrypted.push(tx.clone());
}
- let expected_txs: Vec = expected_wrapper
+ // we extract the inner data from the txs for testing
+ // equality since otherwise changes in timestamps would
+ // fail the test
+ let expected_txs: Vec = expected_wrapper
.into_iter()
.chain(expected_decrypted.into_iter())
- // we extract the inner data from the txs for testing
- // equality since otherwise changes in timestamps would
- // fail the test
- .map(|tx| tx.data.expect("Test failed"))
+ .map(|tx| tx.header)
.collect();
- let received: Vec = shell
+ let received: Vec = shell
.prepare_proposal(req)
.txs
.into_iter()
.map(|tx_bytes| {
Tx::try_from(tx_bytes.as_slice())
.expect("Test failed")
- .data
- .expect("Test failed")
+ .header
})
.collect();
// check that the order of the txs is correct
- assert_eq!(received, expected_txs);
+ assert_eq!(
+ received
+ .iter()
+ .map(|x| x.try_to_vec().unwrap())
+ .collect::>(),
+ expected_txs
+ .iter()
+ .map(|x| x.try_to_vec().unwrap())
+ .collect::>(),
+ );
}
- /// Test that expired wrapper transactions are not included in the block
+ /// Test that if the unsigned wrapper tx hash is known (replay attack), the
+ /// transaction is not included in the block
#[test]
- fn test_expired_wrapper_tx() {
+ fn test_wrapper_tx_hash() {
+ let (mut shell, _) = test_utils::setup(1);
+
+ let keypair = crate::wallet::defaults::daewon_keypair();
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: 0.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair,
+ Epoch(0),
+ 0.into(),
+ #[cfg(not(feature = "mainnet"))]
+ None,
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ wrapper.add_section(Section::Signature(Signature::new(
+ &wrapper.header_hash(),
+ &keypair,
+ )));
+ wrapper.encrypt(&Default::default());
+
+ // Write wrapper hash to storage
+ let wrapper_unsigned_hash = wrapper.header_hash();
+ let hash_key =
+ replay_protection::get_tx_hash_key(&wrapper_unsigned_hash);
+ shell
+ .wl_storage
+ .storage
+ .write(&hash_key, vec![])
+ .expect("Test failed");
+
+ let req = RequestPrepareProposal {
+ txs: vec![wrapper.to_bytes()],
+ ..Default::default()
+ };
+
+ let received =
+ shell.prepare_proposal(req).txs.into_iter().map(|tx_bytes| {
+ Tx::try_from(tx_bytes.as_slice())
+ .expect("Test failed")
+ .data()
+ .expect("Test failed")
+ });
+ assert_eq!(received.len(), 0);
+ }
+
+ /// Test that if two identical wrapper txs are proposed for this block, only
+ /// one gets accepted
+ #[test]
+ fn test_wrapper_tx_hash_same_block() {
let (shell, _) = test_utils::setup(1);
- let keypair = gen_keypair();
- let tx_time = DateTimeUtc::now();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
+
+ let keypair = crate::wallet::defaults::daewon_keypair();
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: 0.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair,
+ Epoch(0),
+ 0.into(),
+ #[cfg(not(feature = "mainnet"))]
None,
- );
- let wrapper_tx = WrapperTx::new(
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ wrapper.add_section(Section::Signature(Signature::new(
+ &wrapper.header_hash(),
+ &keypair,
+ )));
+ wrapper.encrypt(&Default::default());
+
+ let req = RequestPrepareProposal {
+ txs: vec![wrapper.to_bytes(); 2],
+ ..Default::default()
+ };
+ let received =
+ shell.prepare_proposal(req).txs.into_iter().map(|tx_bytes| {
+ Tx::try_from(tx_bytes.as_slice())
+ .expect("Test failed")
+ .data()
+ .expect("Test failed")
+ });
+ assert_eq!(received.len(), 1);
+ }
+
+ /// Test that if the unsigned inner tx hash is known (replay attack), the
+ /// transaction is not included in the block
+ #[test]
+ fn test_inner_tx_hash() {
+ let (mut shell, _) = test_utils::setup(1);
+
+ let keypair = crate::wallet::defaults::daewon_keypair();
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -432,15 +524,138 @@ mod test_prepare_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- let wrapper = wrapper_tx
- .sign(&keypair, shell.chain_id.clone(), Some(tx_time))
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ wrapper.add_section(Section::Signature(Signature::new(
+ &wrapper.header_hash(),
+ &keypair,
+ )));
+ wrapper.encrypt(&Default::default());
+ let inner_unsigned_hash =
+ wrapper.clone().update_header(TxType::Raw).header_hash();
+
+ // Write inner hash to storage
+ let hash_key = replay_protection::get_tx_hash_key(&inner_unsigned_hash);
+ shell
+ .wl_storage
+ .storage
+ .write(&hash_key, vec![])
.expect("Test failed");
+ let req = RequestPrepareProposal {
+ txs: vec![wrapper.to_bytes()],
+ ..Default::default()
+ };
+
+ let received =
+ shell.prepare_proposal(req).txs.into_iter().map(|tx_bytes| {
+ Tx::try_from(tx_bytes.as_slice())
+ .expect("Test failed")
+ .data()
+ .expect("Test failed")
+ });
+ assert_eq!(received.len(), 0);
+ }
+
+ /// Test that if two identical decrypted txs are proposed for this block,
+ /// only one gets accepted
+ #[test]
+ fn test_inner_tx_hash_same_block() {
+ let (shell, _) = test_utils::setup(1);
+
+ let keypair = crate::wallet::defaults::daewon_keypair();
+ let keypair_2 = crate::wallet::defaults::daewon_keypair();
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: 0.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair,
+ Epoch(0),
+ 0.into(),
+ #[cfg(not(feature = "mainnet"))]
+ None,
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ let tx_code = Code::new("wasm_code".as_bytes().to_owned());
+ wrapper.set_code(tx_code.clone());
+ let tx_data = Data::new("transaction data".as_bytes().to_owned());
+ wrapper.set_data(tx_data.clone());
+ wrapper.add_section(Section::Signature(Signature::new(
+ &wrapper.header_hash(),
+ &keypair,
+ )));
+ wrapper.encrypt(&Default::default());
+
+ let mut new_wrapper =
+ Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: 0.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair_2,
+ Epoch(0),
+ 0.into(),
+ #[cfg(not(feature = "mainnet"))]
+ None,
+ ))));
+ new_wrapper.header.chain_id = shell.chain_id.clone();
+ new_wrapper.header.timestamp = wrapper.header.timestamp;
+ new_wrapper.set_code(tx_code);
+ new_wrapper.set_data(tx_data);
+ new_wrapper.add_section(Section::Signature(Signature::new(
+ &new_wrapper.header_hash(),
+ &keypair,
+ )));
+ new_wrapper.encrypt(&Default::default());
+
+ let req = RequestPrepareProposal {
+ txs: vec![wrapper.to_bytes(), new_wrapper.to_bytes()],
+ ..Default::default()
+ };
+ let received =
+ shell.prepare_proposal(req).txs.into_iter().map(|tx_bytes| {
+ Tx::try_from(tx_bytes.as_slice())
+ .expect("Test failed")
+ .data()
+ .expect("Test failed")
+ });
+ assert_eq!(received.len(), 1);
+ }
+
+ /// Test that expired wrapper transactions are not included in the block
+ #[test]
+ fn test_expired_wrapper_tx() {
+ let (shell, _) = test_utils::setup(1);
+ let keypair = gen_keypair();
+ let tx_time = DateTimeUtc::now();
+ let mut wrapper_tx =
+ Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: 0.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair,
+ Epoch(0),
+ 0.into(),
+ #[cfg(not(feature = "mainnet"))]
+ None,
+ ))));
+ wrapper_tx.header.chain_id = shell.chain_id.clone();
+ wrapper_tx.header.expiration = Some(tx_time);
+ wrapper_tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper_tx
+ .set_data(Data::new("transaction data".as_bytes().to_owned()));
+ wrapper_tx.add_section(Section::Signature(Signature::new(
+ &wrapper_tx.header_hash(),
+ &keypair,
+ )));
+ wrapper_tx.encrypt(&Default::default());
+
let time = DateTimeUtc::now();
let block_time =
namada::core::tendermint_proto::google::protobuf::Timestamp {
@@ -448,13 +663,13 @@ mod test_prepare_proposal {
nanos: time.0.timestamp_subsec_nanos() as i32,
};
let req = RequestPrepareProposal {
- txs: vec![wrapper.to_bytes()],
+ txs: vec![wrapper_tx.to_bytes()],
max_tx_bytes: 0,
time: Some(block_time),
..Default::default()
};
let result = shell.prepare_proposal(req);
eprintln!("Proposal: {:?}", result.txs);
- assert!(result.txs.is_empty());
+ assert_eq!(result.txs.len(), 0);
}
}
diff --git a/apps/src/lib/node/ledger/shell/process_proposal.rs b/apps/src/lib/node/ledger/shell/process_proposal.rs
index acc57e5979..2837ac6600 100644
--- a/apps/src/lib/node/ledger/shell/process_proposal.rs
+++ b/apps/src/lib/node/ledger/shell/process_proposal.rs
@@ -4,10 +4,9 @@
use data_encoding::HEXUPPER;
use namada::core::hints;
use namada::core::ledger::storage::WlStorage;
-use namada::core::types::hash::Hash;
use namada::ledger::storage::TempWlStorage;
use namada::proof_of_stake::pos_queries::PosQueries;
-use namada::types::internal::WrapperTxInQueue;
+use namada::types::internal::TxInQueue;
use super::*;
use crate::facade::tendermint_proto::abci::response_process_proposal::ProposalStatus;
@@ -149,11 +148,16 @@ where
&mut temp_wl_storage,
block_time,
);
- if let ErrorCodes::Ok =
- ErrorCodes::from_u32(result.code).unwrap()
- {
+ let error_code = ErrorCodes::from_u32(result.code).unwrap();
+ if let ErrorCodes::Ok = error_code {
temp_wl_storage.write_log.commit_tx();
} else {
+ tracing::info!(
+ "Process proposal rejected an invalid tx. Error code: \
+ {:?}, info: {}",
+ error_code,
+ result.info
+ );
temp_wl_storage.write_log.drop_tx();
}
result
@@ -189,7 +193,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,
metadata: &mut ValidationMeta,
temp_wl_storage: &mut TempWlStorage,
block_time: DateTimeUtc,
@@ -225,17 +229,17 @@ where
})
},
|tx| {
- let tx_chain_id = tx.chain_id.clone();
- let tx_expiration = tx.expiration;
- let tx_type = process_tx(tx).map_err(|err| {
+ let tx_chain_id = tx.header.chain_id.clone();
+ let tx_expiration = tx.header.expiration;
+ if let Err(err) = tx.validate_header() {
// This occurs if the wrapper / protocol tx signature is
// invalid
- TxResult {
+ return Err(TxResult {
code: ErrorCodes::InvalidSig.into(),
info: err.to_string(),
- }
- })?;
- Ok((tx_chain_id, tx_expiration, tx_type))
+ });
+ }
+ Ok((tx_chain_id, tx_expiration, tx))
},
);
let (tx_chain_id, tx_expiration, tx) = match maybe_tx {
@@ -246,9 +250,15 @@ where
// TODO: This should not be hardcoded
let privkey = ::G2Affine::prime_subgroup_generator();
- match tx {
+ if let Err(err) = tx.validate_header() {
+ return TxResult {
+ code: ErrorCodes::InvalidSig.into(),
+ info: err.to_string(),
+ };
+ }
+ match tx.header().tx_type {
// If it is a raw transaction, we do no further validation
- TxType::Raw(_) => TxResult {
+ TxType::Raw => TxResult {
code: ErrorCodes::InvalidTx.into(),
info: "Transaction rejected: Non-encrypted transactions are \
not supported"
@@ -286,11 +296,19 @@ where
.into(),
}
}
- TxType::Decrypted(tx) => {
+ TxType::Decrypted(tx_header) => {
metadata.has_decrypted_txs = true;
match tx_queue_iter.next() {
Some(wrapper) => {
- if wrapper.tx.tx_hash != tx.hash_commitment() {
+ let mut inner_tx = tx;
+ inner_tx.update_header(TxType::Raw);
+ if wrapper
+ .tx
+ .clone()
+ .update_header(TxType::Raw)
+ .header_hash()
+ != inner_tx.header_hash()
+ {
TxResult {
code: ErrorCodes::InvalidOrder.into(),
info: "Process proposal rejected a decrypted \
@@ -298,41 +316,38 @@ where
determined in the previous block"
.into(),
}
- } else if verify_decrypted_correctly(&tx, privkey) {
- if let DecryptedTx::Decrypted {
- tx,
- has_valid_pow: _,
- } = tx
- {
- // Tx chain id
- if tx.chain_id != self.chain_id {
+ } else if verify_decrypted_correctly(
+ &tx_header,
+ wrapper.tx.clone(),
+ privkey,
+ ) {
+ // Tx chain id
+ if wrapper.tx.header.chain_id != self.chain_id {
+ return TxResult {
+ code: ErrorCodes::InvalidDecryptedChainId
+ .into(),
+ info: format!(
+ "Decrypted tx carries a wrong chain \
+ id: expected {}, found {}",
+ self.chain_id,
+ wrapper.tx.header.chain_id
+ ),
+ };
+ }
+
+ // Tx expiration
+ if let Some(exp) = wrapper.tx.header.expiration {
+ if block_time > exp {
return TxResult {
- code:
- ErrorCodes::InvalidDecryptedChainId
- .into(),
+ code: ErrorCodes::ExpiredDecryptedTx
+ .into(),
info: format!(
- "Decrypted tx carries a wrong \
- chain id: expected {}, found {}",
- self.chain_id, tx.chain_id
+ "Decrypted tx expired at {:#?}, \
+ block time: {:#?}",
+ exp, block_time
),
};
}
-
- // Tx expiration
- if let Some(exp) = tx.expiration {
- if block_time > exp {
- return TxResult {
- code:
- ErrorCodes::ExpiredDecryptedTx
- .into(),
- info: format!(
- "Decrypted tx expired at \
- {:#?}, block time: {:#?}",
- exp, block_time
- ),
- };
- }
- }
}
TxResult {
code: ErrorCodes::Ok.into(),
@@ -419,7 +434,7 @@ where
}
// validate the ciphertext via Ferveo
- if !wrapper.validate_ciphertext() {
+ if !tx.validate_ciphertext() {
TxResult {
code: ErrorCodes::InvalidTx.into(),
info: format!(
@@ -429,54 +444,17 @@ where
}
} else {
// Replay protection checks
- let inner_hash_key =
- replay_protection::get_tx_hash_key(&wrapper.tx_hash);
- if temp_wl_storage.has_key(&inner_hash_key).expect(
- "Error while checking inner tx hash key in storage",
+ if let Err(e) = self.replay_protection_checks(
+ &tx,
+ tx_bytes,
+ temp_wl_storage,
) {
return TxResult {
code: ErrorCodes::ReplayTx.into(),
- info: format!(
- "Inner transaction hash {} already in \
- storage, replay attempt",
- &wrapper.tx_hash
- ),
+ info: e.to_string(),
};
}
- // Write inner hash to WAL
- temp_wl_storage
- .write_log
- .write(&inner_hash_key, vec![])
- .expect(
- "Couldn't write inner transaction hash to write \
- log",
- );
-
- let tx = Tx::try_from(tx_bytes)
- .expect("Deserialization shouldn't fail");
- let wrapper_hash = Hash(tx.unsigned_hash());
- let wrapper_hash_key =
- replay_protection::get_tx_hash_key(&wrapper_hash);
- if temp_wl_storage.has_key(&wrapper_hash_key).expect(
- "Error while checking wrapper tx hash key in storage",
- ) {
- return TxResult {
- code: ErrorCodes::ReplayTx.into(),
- info: format!(
- "Wrapper transaction hash {} already in \
- storage, replay attempt",
- wrapper_hash
- ),
- };
- }
-
- // Write wrapper hash to WAL
- temp_wl_storage
- .write_log
- .write(&wrapper_hash_key, vec![])
- .expect("Couldn't write wrapper tx hash to write log");
-
// If the public key corresponds to the MASP sentinel
// transaction key, then the fee payer is effectively
// the MASP, otherwise derive
@@ -537,16 +515,14 @@ where
/// are covered by the e2e tests.
#[cfg(test)]
mod test_process_proposal {
- use borsh::BorshDeserialize;
use namada::ledger::parameters::storage::get_wrapper_tx_fees_key;
- use namada::proto::SignedTxData;
+ use namada::proto::{Code, Data, Section, Signature};
use namada::types::hash::Hash;
use namada::types::key::*;
use namada::types::storage::Epoch;
use namada::types::token::Amount;
- use namada::types::transaction::encrypted::EncryptedTx;
- use namada::types::transaction::protocol::ProtocolTxType;
- use namada::types::transaction::{EncryptionKey, Fee, WrapperTx, MIN_FEE};
+ use namada::types::transaction::protocol::{ProtocolTx, ProtocolTxType};
+ use namada::types::transaction::{Fee, WrapperTx, MIN_FEE};
use super::*;
use crate::node::ledger::shell::test_utils::{
@@ -559,13 +535,7 @@ mod test_process_proposal {
fn test_unsigned_wrapper_rejected() {
let (mut shell, _) = test_utils::setup(1);
let keypair = gen_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
+ let mut outer_tx = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -573,18 +543,14 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- let tx = Tx::new(
- vec![],
- Some(TxType::Wrapper(wrapper).try_to_vec().expect("Test failed")),
- shell.chain_id.clone(),
- None,
- )
- .to_bytes();
+ ))));
+ outer_tx.header.chain_id = shell.chain_id.clone();
+ outer_tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ outer_tx.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ outer_tx.encrypt(&Default::default());
+ let tx = outer_tx.to_bytes();
#[allow(clippy::redundant_clone)]
let request = ProcessProposal {
txs: vec![tx.clone()],
@@ -599,7 +565,10 @@ mod test_process_proposal {
);
assert_eq!(
response[0].result.info,
- String::from("Wrapper transactions must be signed")
+ String::from(
+ "WrapperTx signature verification failed: Transaction \
+ doesn't have any data with a signature."
+ )
);
}
}
@@ -611,14 +580,7 @@ mod test_process_proposal {
fn test_wrapper_bad_signature_rejected() {
let (mut shell, _) = test_utils::setup(1);
let keypair = gen_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let timestamp = tx.timestamp;
- let mut wrapper = WrapperTx::new(
+ let mut outer_tx = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 100.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -626,51 +588,23 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- )
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Test failed");
- let new_tx = if let Some(Ok(SignedTxData {
- data: Some(data),
- sig,
- })) = wrapper
- .data
- .take()
- .map(|data| SignedTxData::try_from_slice(&data[..]))
- {
- let mut new_wrapper = if let TxType::Wrapper(wrapper) =
- ::deserialize(&mut data.as_ref())
- .expect("Test failed")
- {
- wrapper
- } else {
- panic!("Test failed")
- };
-
+ ))));
+ outer_tx.header.chain_id = shell.chain_id.clone();
+ outer_tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ outer_tx.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ outer_tx.add_section(Section::Signature(Signature::new(
+ &outer_tx.header_hash(),
+ &keypair,
+ )));
+ outer_tx.encrypt(&Default::default());
+ let mut new_tx = outer_tx.clone();
+ if let TxType::Wrapper(wrapper) = &mut new_tx.header.tx_type {
// we mount a malleability attack to try and remove the fee
- new_wrapper.fee.amount = 0.into();
- let new_data = TxType::Wrapper(new_wrapper)
- .try_to_vec()
- .expect("Test failed");
- Tx {
- code_or_hash: vec![],
- data: Some(
- SignedTxData {
- sig,
- data: Some(new_data),
- }
- .try_to_vec()
- .expect("Test failed"),
- ),
- timestamp,
- chain_id: shell.chain_id.clone(),
- expiration: None,
- }
+ wrapper.fee.amount = 0.into();
} else {
- panic!("Test failed");
+ panic!("Test failed")
};
let request = ProcessProposal {
txs: vec![new_tx.to_bytes()],
@@ -679,8 +613,9 @@ mod test_process_proposal {
match shell.process_proposal(request) {
Ok(_) => panic!("Test failed"),
Err(TestError::RejectProposal(response)) => {
- let expected_error =
- "Signature verification failed: Invalid signature";
+ let expected_error = "WrapperTx signature verification \
+ failed: Transaction doesn't have any \
+ data with a signature.";
assert_eq!(
response[0].result.code,
u32::from(ErrorCodes::InvalidSig)
@@ -709,13 +644,7 @@ mod test_process_proposal {
)
.unwrap();
let keypair = gen_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
+ let mut outer_tx = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 1.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -723,15 +652,20 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- )
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Test failed");
+ ))));
+ outer_tx.header.chain_id = shell.chain_id.clone();
+ outer_tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ outer_tx.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ outer_tx.add_section(Section::Signature(Signature::new(
+ &outer_tx.header_hash(),
+ &keypair,
+ )));
+ outer_tx.encrypt(&Default::default());
+
let request = ProcessProposal {
- txs: vec![wrapper.to_bytes()],
+ txs: vec![outer_tx.to_bytes()],
};
match shell.process_proposal(request) {
@@ -777,13 +711,7 @@ mod test_process_proposal {
)
.unwrap();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
+ let mut outer_tx = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: Amount::whole(1_000_100),
token: shell.wl_storage.storage.native_token.clone(),
@@ -791,16 +719,20 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- )
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Test failed");
+ ))));
+ outer_tx.header.chain_id = shell.chain_id.clone();
+ outer_tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ outer_tx.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ outer_tx.add_section(Section::Signature(Signature::new(
+ &outer_tx.header_hash(),
+ &keypair,
+ )));
+ outer_tx.encrypt(&Default::default());
let request = ProcessProposal {
- txs: vec![wrapper.to_bytes()],
+ txs: vec![outer_tx.to_bytes()],
};
match shell.process_proposal(request) {
@@ -829,34 +761,31 @@ mod test_process_proposal {
let keypair = gen_keypair();
let mut txs = vec![];
for i in 0..3 {
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some(format!("transaction data: {}", i).as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
- Fee {
- amount: i.into(),
- token: shell.wl_storage.storage.native_token.clone(),
- },
- &keypair,
- Epoch(0),
- 0.into(),
- tx.clone(),
- Default::default(),
- #[cfg(not(feature = "mainnet"))]
- None,
- );
- shell.enqueue_tx(wrapper);
- let mut decrypted_tx =
- Tx::from(TxType::Decrypted(DecryptedTx::Decrypted {
- tx,
+ let mut outer_tx =
+ Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
+ Fee {
+ amount: i.into(),
+ token: shell.wl_storage.storage.native_token.clone(),
+ },
+ &keypair,
+ Epoch(0),
+ 0.into(),
#[cfg(not(feature = "mainnet"))]
- has_valid_pow: false,
- }));
- decrypted_tx.chain_id = shell.chain_id.clone();
- txs.push(decrypted_tx);
+ None,
+ ))));
+ outer_tx.header.chain_id = shell.chain_id.clone();
+ outer_tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ outer_tx.set_data(Data::new(
+ format!("transaction data: {}", i).as_bytes().to_owned(),
+ ));
+ outer_tx.encrypt(&Default::default());
+ shell.enqueue_tx(outer_tx.clone());
+
+ outer_tx.update_header(TxType::Decrypted(DecryptedTx::Decrypted {
+ #[cfg(not(feature = "mainnet"))]
+ has_valid_pow: false,
+ }));
+ txs.push(outer_tx);
}
let response = {
let request = ProcessProposal {
@@ -892,13 +821,7 @@ mod test_process_proposal {
let (mut shell, _) = test_utils::setup(1);
let keypair = gen_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
+ let mut tx = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -906,17 +829,16 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- shell.enqueue_tx(wrapper.clone());
-
- let mut tx =
- Tx::from(TxType::Decrypted(DecryptedTx::Undecryptable(wrapper)));
- tx.chain_id = shell.chain_id.clone();
-
+ ))));
+ tx.header.chain_id = shell.chain_id.clone();
+ tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ tx.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ tx.encrypt(&Default::default());
+ shell.enqueue_tx(tx.clone());
+
+ tx.header.tx_type = TxType::Decrypted(DecryptedTx::Undecryptable);
let request = ProcessProposal {
txs: vec![tx.to_bytes()],
};
@@ -947,13 +869,7 @@ mod test_process_proposal {
let (mut shell, _) = test_utils::setup(1);
let keypair = crate::wallet::defaults::daewon_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let mut wrapper = WrapperTx::new(
+ let mut tx = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -961,20 +877,19 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- wrapper.tx_hash = Hash([0; 32]);
+ ))));
+ tx.header.chain_id = shell.chain_id.clone();
+ tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ tx.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ tx.set_code_sechash(Hash([0u8; 32]));
+ tx.set_data_sechash(Hash([0u8; 32]));
+ tx.encrypt(&Default::default());
- shell.enqueue_tx(wrapper.clone());
- let mut tx = Tx::from(TxType::Decrypted(DecryptedTx::Undecryptable(
- #[allow(clippy::redundant_clone)]
- wrapper.clone(),
- )));
- tx.chain_id = shell.chain_id.clone();
+ shell.enqueue_tx(tx.clone());
+ tx.header.tx_type = TxType::Decrypted(DecryptedTx::Undecryptable);
let request = ProcessProposal {
txs: vec![tx.to_bytes()],
};
@@ -997,10 +912,7 @@ mod test_process_proposal {
fn test_undecryptable() {
let (mut shell, _) = test_utils::setup(1);
let keypair = crate::wallet::defaults::daewon_keypair();
- let pubkey = EncryptionKey::default();
// not valid tx bytes
- let tx = "garbage data".as_bytes().to_owned();
- let inner_tx = EncryptedTx::encrypt(&tx, pubkey);
let wrapper = WrapperTx {
fee: Fee {
amount: 0.into(),
@@ -1009,21 +921,18 @@ mod test_process_proposal {
pk: keypair.ref_to(),
epoch: Epoch(0),
gas_limit: 0.into(),
- inner_tx,
- tx_hash: hash_tx(&tx),
#[cfg(not(feature = "mainnet"))]
pow_solution: None,
};
- shell.enqueue_tx(wrapper.clone());
- let mut signed =
- Tx::from(TxType::Decrypted(DecryptedTx::Undecryptable(
- #[allow(clippy::redundant_clone)]
- wrapper.clone(),
- )));
- signed.chain_id = shell.chain_id.clone();
+ let tx = Tx::new(TxType::Wrapper(Box::new(wrapper)));
+ let mut decrypted = tx.clone();
+ decrypted.update_header(TxType::Decrypted(DecryptedTx::Undecryptable));
+
+ shell.enqueue_tx(tx);
+
let request = ProcessProposal {
- txs: vec![signed.to_bytes()],
+ txs: vec![decrypted.to_bytes()],
};
let response = if let [resp] = shell
.process_proposal(request)
@@ -1042,20 +951,13 @@ mod test_process_proposal {
#[test]
fn test_too_many_decrypted_txs() {
let (mut shell, _) = test_utils::setup(1);
-
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
-
- let mut tx = Tx::from(TxType::Decrypted(DecryptedTx::Decrypted {
- tx,
+ let mut tx = Tx::new(TxType::Decrypted(DecryptedTx::Decrypted {
#[cfg(not(feature = "mainnet"))]
has_valid_pow: false,
}));
- tx.chain_id = shell.chain_id.clone();
+ tx.header.chain_id = shell.chain_id.clone();
+ tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ tx.set_data(Data::new("transaction data".as_bytes().to_owned()));
let request = ProcessProposal {
txs: vec![tx.to_bytes()],
@@ -1083,14 +985,11 @@ mod test_process_proposal {
fn test_raw_tx_rejected() {
let (mut shell, _) = test_utils::setup(1);
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let mut tx = Tx::from(TxType::Raw(tx));
- tx.chain_id = shell.chain_id.clone();
+ let mut tx = Tx::new(TxType::Raw);
+ tx.header.chain_id = shell.chain_id.clone();
+ tx.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ tx.set_data(Data::new("transaction data".as_bytes().to_owned()));
+
let request = ProcessProposal {
txs: vec![tx.to_bytes()],
};
@@ -1121,13 +1020,7 @@ mod test_process_proposal {
let keypair = crate::wallet::defaults::daewon_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -1135,17 +1028,20 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- let signed = wrapper
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Test failed");
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper.add_section(Section::Signature(Signature::new(
+ &wrapper.header_hash(),
+ &keypair,
+ )));
+ wrapper.encrypt(&Default::default());
// Write wrapper hash to storage
- let wrapper_unsigned_hash = Hash(signed.unsigned_hash());
+ let wrapper_unsigned_hash = wrapper.header_hash();
let hash_key =
replay_protection::get_tx_hash_key(&wrapper_unsigned_hash);
shell
@@ -1156,8 +1052,9 @@ mod test_process_proposal {
// Run validation
let request = ProcessProposal {
- txs: vec![signed.to_bytes()],
+ txs: vec![wrapper.to_bytes()],
};
+
match shell.process_proposal(request) {
Ok(_) => panic!("Test failed"),
Err(TestError::RejectProposal(response)) => {
@@ -1168,8 +1065,8 @@ mod test_process_proposal {
assert_eq!(
response[0].result.info,
format!(
- "Wrapper transaction hash {} already in storage, \
- replay attempt",
+ "Transaction replay attempt: Wrapper transaction hash \
+ {} already in storage",
wrapper_unsigned_hash
)
);
@@ -1195,13 +1092,7 @@ mod test_process_proposal {
.write(&balance_key, Amount::whole(1000).try_to_vec().unwrap())
.unwrap();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -1209,18 +1100,21 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- let signed = wrapper
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Test failed");
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ wrapper.add_section(Section::Signature(Signature::new(
+ &wrapper.header_hash(),
+ &keypair,
+ )));
+ wrapper.encrypt(&Default::default());
// Run validation
let request = ProcessProposal {
- txs: vec![signed.to_bytes(); 2],
+ txs: vec![wrapper.to_bytes(); 2],
};
match shell.process_proposal(request) {
Ok(_) => panic!("Test failed"),
@@ -1236,9 +1130,12 @@ mod test_process_proposal {
assert_eq!(
response[1].result.info,
format!(
- "Inner transaction hash {} already in storage, replay \
- attempt",
- wrapper.tx_hash
+ "Transaction replay attempt: Inner transaction hash \
+ {} already in storage",
+ wrapper
+ .clone()
+ .update_header(TxType::Raw)
+ .header_hash(),
)
);
}
@@ -1253,13 +1150,7 @@ mod test_process_proposal {
let keypair = crate::wallet::defaults::daewon_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -1267,15 +1158,19 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- let inner_unsigned_hash = wrapper.tx_hash.clone();
- let signed = wrapper
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Test failed");
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ wrapper.add_section(Section::Signature(Signature::new(
+ &wrapper.header_hash(),
+ &keypair,
+ )));
+ wrapper.encrypt(&Default::default());
+ let inner_unsigned_hash =
+ wrapper.clone().update_header(TxType::Raw).header_hash();
// Write inner hash to storage
let hash_key = replay_protection::get_tx_hash_key(&inner_unsigned_hash);
@@ -1287,7 +1182,7 @@ mod test_process_proposal {
// Run validation
let request = ProcessProposal {
- txs: vec![signed.to_bytes()],
+ txs: vec![wrapper.to_bytes()],
};
match shell.process_proposal(request) {
Ok(_) => panic!("Test failed"),
@@ -1299,8 +1194,8 @@ mod test_process_proposal {
assert_eq!(
response[0].result.info,
format!(
- "Inner transaction hash {} already in storage, replay \
- attempt",
+ "Transaction replay attempt: Inner transaction hash \
+ {} already in storage",
inner_unsigned_hash
)
);
@@ -1339,13 +1234,7 @@ mod test_process_proposal {
.write(&balance_key, Amount::whole(1000).try_to_vec().unwrap())
.unwrap();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -1353,17 +1242,22 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx.clone(),
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- let inner_unsigned_hash = wrapper.tx_hash.clone();
- let signed = wrapper
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Test failed");
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ let mut new_wrapper = wrapper.clone();
+ wrapper.add_section(Section::Signature(Signature::new(
+ &wrapper.header_hash(),
+ &keypair,
+ )));
+ wrapper.encrypt(&Default::default());
+ let inner_unsigned_hash =
+ wrapper.clone().update_header(TxType::Raw).header_hash();
- let new_wrapper = WrapperTx::new(
+ new_wrapper.update_header(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -1371,18 +1265,18 @@ mod test_process_proposal {
&keypair_2,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- let new_signed = new_wrapper
- .sign(&keypair, shell.chain_id.clone(), None)
- .expect("Test failed");
+ ))));
+ new_wrapper.add_section(Section::Signature(Signature::new(
+ &new_wrapper.header_hash(),
+ &keypair,
+ )));
+ new_wrapper.encrypt(&Default::default());
// Run validation
let request = ProcessProposal {
- txs: vec![signed.to_bytes(), new_signed.to_bytes()],
+ txs: vec![wrapper.to_bytes(), new_wrapper.to_bytes()],
};
match shell.process_proposal(request) {
Ok(_) => panic!("Test failed"),
@@ -1395,8 +1289,8 @@ mod test_process_proposal {
assert_eq!(
response[1].result.info,
format!(
- "Inner transaction hash {} already in storage, replay \
- attempt",
+ "Transaction replay attempt: Inner transaction hash \
+ {} already in storage",
inner_unsigned_hash
)
);
@@ -1407,17 +1301,11 @@ mod test_process_proposal {
/// Test that a wrapper or protocol transaction with a mismatching chain id
/// causes the entire block to be rejected
#[test]
- fn test_wong_chain_id() {
+ fn test_wrong_chain_id() {
let (mut shell, _) = test_utils::setup(1);
let keypair = crate::wallet::defaults::daewon_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -1425,25 +1313,32 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx.clone(),
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
+ ))));
let wrong_chain_id = ChainId("Wrong chain id".to_string());
- let signed = wrapper
- .sign(&keypair, wrong_chain_id.clone(), None)
- .expect("Test failed");
+ wrapper.header.chain_id = wrong_chain_id.clone();
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ let mut protocol_tx = wrapper.clone();
+ wrapper.add_section(Section::Signature(Signature::new(
+ &wrapper.header_hash(),
+ &keypair,
+ )));
+ wrapper.encrypt(&Default::default());
- let protocol_tx = ProtocolTxType::EthereumStateUpdate(tx).sign(
- &keypair.ref_to(),
+ protocol_tx.update_header(TxType::Protocol(Box::new(ProtocolTx {
+ pk: keypair.ref_to(),
+ tx: ProtocolTxType::EthereumStateUpdate,
+ })));
+ protocol_tx.add_section(Section::Signature(Signature::new(
+ &protocol_tx.header_hash(),
&keypair,
- wrong_chain_id.clone(),
- );
+ )));
// Run validation
let request = ProcessProposal {
- txs: vec![signed.to_bytes(), protocol_tx.to_bytes()],
+ txs: vec![wrapper.to_bytes(), protocol_tx.to_bytes()],
};
match shell.process_proposal(request) {
Ok(_) => panic!("Test failed"),
@@ -1469,24 +1364,12 @@ mod test_process_proposal {
/// Test that a decrypted transaction with a mismatching chain id gets
/// rejected without rejecting the entire block
#[test]
- fn test_decrypted_wong_chain_id() {
+ fn test_decrypted_wrong_chain_id() {
let (mut shell, _) = test_utils::setup(1);
let keypair = crate::wallet::defaults::daewon_keypair();
let wrong_chain_id = ChainId("Wrong chain id".to_string());
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("new transaction data".as_bytes().to_owned()),
- wrong_chain_id.clone(),
- None,
- );
- let decrypted: Tx = DecryptedTx::Decrypted {
- tx: tx.clone(),
- has_valid_pow: false,
- }
- .into();
- let signed_decrypted = decrypted.sign(&keypair);
- let wrapper = WrapperTx::new(
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -1494,12 +1377,24 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- let wrapper_in_queue = WrapperTxInQueue {
+ ))));
+ wrapper.header.chain_id = wrong_chain_id.clone();
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper
+ .set_data(Data::new("new transaction data".as_bytes().to_owned()));
+ let mut decrypted = wrapper.clone();
+ wrapper.encrypt(&Default::default());
+
+ decrypted.update_header(TxType::Decrypted(DecryptedTx::Decrypted {
+ has_valid_pow: false,
+ }));
+ decrypted.add_section(Section::Signature(Signature::new(
+ &decrypted.header_hash(),
+ &keypair,
+ )));
+ let wrapper_in_queue = TxInQueue {
tx: wrapper,
has_valid_pow: false,
};
@@ -1507,7 +1402,7 @@ mod test_process_proposal {
// Run validation
let request = ProcessProposal {
- txs: vec![signed_decrypted.to_bytes()],
+ txs: vec![decrypted.to_bytes()],
};
match shell.process_proposal(request) {
@@ -1535,13 +1430,7 @@ mod test_process_proposal {
let (mut shell, _) = test_utils::setup(1);
let keypair = crate::wallet::defaults::daewon_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- None,
- );
- let wrapper = WrapperTx::new(
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -1549,18 +1438,22 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- let signed = wrapper
- .sign(&keypair, shell.chain_id.clone(), Some(DateTimeUtc::now()))
- .expect("Test failed");
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.header.expiration = Some(DateTimeUtc::now());
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper.set_data(Data::new("transaction data".as_bytes().to_owned()));
+ wrapper.add_section(Section::Signature(Signature::new(
+ &wrapper.header_hash(),
+ &keypair,
+ )));
+ wrapper.encrypt(&Default::default());
// Run validation
let request = ProcessProposal {
- txs: vec![signed.to_bytes()],
+ txs: vec![wrapper.to_bytes()],
};
match shell.process_proposal(request) {
Ok(_) => panic!("Test failed"),
@@ -1580,19 +1473,7 @@ mod test_process_proposal {
let (mut shell, _) = test_utils::setup(1);
let keypair = crate::wallet::defaults::daewon_keypair();
- let tx = Tx::new(
- "wasm_code".as_bytes().to_owned(),
- Some("new transaction data".as_bytes().to_owned()),
- shell.chain_id.clone(),
- Some(DateTimeUtc::now()),
- );
- let decrypted: Tx = DecryptedTx::Decrypted {
- tx: tx.clone(),
- has_valid_pow: false,
- }
- .into();
- let signed_decrypted = decrypted.sign(&keypair);
- let wrapper = WrapperTx::new(
+ let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Fee {
amount: 0.into(),
token: shell.wl_storage.storage.native_token.clone(),
@@ -1600,12 +1481,25 @@ mod test_process_proposal {
&keypair,
Epoch(0),
0.into(),
- tx,
- Default::default(),
#[cfg(not(feature = "mainnet"))]
None,
- );
- let wrapper_in_queue = WrapperTxInQueue {
+ ))));
+ wrapper.header.chain_id = shell.chain_id.clone();
+ wrapper.header.expiration = Some(DateTimeUtc::now());
+ wrapper.set_code(Code::new("wasm_code".as_bytes().to_owned()));
+ wrapper
+ .set_data(Data::new("new transaction data".as_bytes().to_owned()));
+ let mut decrypted = wrapper.clone();
+ wrapper.encrypt(&Default::default());
+
+ decrypted.update_header(TxType::Decrypted(DecryptedTx::Decrypted {
+ has_valid_pow: false,
+ }));
+ decrypted.add_section(Section::Signature(Signature::new(
+ &decrypted.header_hash(),
+ &keypair,
+ )));
+ let wrapper_in_queue = TxInQueue {
tx: wrapper,
has_valid_pow: false,
};
@@ -1613,7 +1507,7 @@ mod test_process_proposal {
// Run validation
let request = ProcessProposal {
- txs: vec![signed_decrypted.to_bytes()],
+ txs: vec![decrypted.to_bytes()],
};
match shell.process_proposal(request) {
Ok(response) => {
diff --git a/apps/src/lib/node/ledger/shell/stats.rs b/apps/src/lib/node/ledger/shell/stats.rs
index f4c548c231..0a677ed576 100644
--- a/apps/src/lib/node/ledger/shell/stats.rs
+++ b/apps/src/lib/node/ledger/shell/stats.rs
@@ -9,6 +9,7 @@ pub struct InternalStats {
vp_cache_size: (usize, usize),
tx_cache_size: (usize, usize),
tx_executed: HashMap,
+ wrapper_txs: u64,
}
impl InternalStats {
@@ -50,15 +51,21 @@ impl InternalStats {
info.strip_suffix(", ").unwrap().to_string()
}
}
+
+ pub fn increment_wrapper_txs(&mut self) {
+ self.wrapper_txs += 1;
+ }
}
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 {} - {}",
+ "Applied {} transactions. Wrappers: {}, successful inner txs: {}, \
+ rejected inner txs: {}, errored inner txs: {}, vp cache size: {} \
+ - {}, tx cache size {} - {}",
self.successful_tx + self.rejected_txs + self.errored_txs,
+ self.wrapper_txs,
self.successful_tx,
self.rejected_txs,
self.errored_txs,
diff --git a/apps/src/lib/node/ledger/shims/abcipp_shim.rs b/apps/src/lib/node/ledger/shims/abcipp_shim.rs
index 05ffbf8de0..7bb02a6aef 100644
--- a/apps/src/lib/node/ledger/shims/abcipp_shim.rs
+++ b/apps/src/lib/node/ledger/shims/abcipp_shim.rs
@@ -186,7 +186,7 @@ impl AbcippShim {
let mut end_block_request: FinalizeBlock =
begin_block_request.into();
let hash = self.get_hash();
- end_block_request.hash = BlockHash::from(hash.clone());
+ end_block_request.hash = BlockHash::from(hash);
end_block_request.txs = txs;
self.service
.call(Request::FinalizeBlock(end_block_request))
diff --git a/apps/src/lib/node/ledger/shims/abcipp_shim_types.rs b/apps/src/lib/node/ledger/shims/abcipp_shim_types.rs
index c94ba2e1d9..d1cd190e1d 100644
--- a/apps/src/lib/node/ledger/shims/abcipp_shim_types.rs
+++ b/apps/src/lib/node/ledger/shims/abcipp_shim_types.rs
@@ -1,22 +1,12 @@
-#[cfg(not(feature = "abcipp"))]
-use tower_abci::{Request, Response};
#[cfg(feature = "abcipp")]
use tower_abci_abcipp::{Request, Response};
+#[cfg(not(feature = "abcipp"))]
+use crate::facade::tower_abci::{Request, Response};
+
pub mod shim {
use std::convert::TryFrom;
- #[cfg(not(feature = "abcipp"))]
- use tendermint_proto::abci::{
- RequestApplySnapshotChunk, RequestCheckTx, RequestCommit, RequestEcho,
- RequestFlush, RequestInfo, RequestInitChain, RequestListSnapshots,
- RequestLoadSnapshotChunk, RequestOfferSnapshot, RequestPrepareProposal,
- RequestProcessProposal, RequestQuery, ResponseApplySnapshotChunk,
- ResponseCheckTx, ResponseCommit, ResponseEcho, ResponseEndBlock,
- ResponseFlush, ResponseInfo, ResponseInitChain, ResponseListSnapshots,
- ResponseLoadSnapshotChunk, ResponseOfferSnapshot,
- ResponsePrepareProposal, ResponseQuery, VoteInfo,
- };
#[cfg(feature = "abcipp")]
use tendermint_proto_abcipp::abci::{
RequestApplySnapshotChunk, RequestCheckTx, RequestCommit, RequestEcho,
@@ -33,6 +23,17 @@ pub mod shim {
use thiserror::Error;
use super::{Request as Req, Response as Resp};
+ #[cfg(not(feature = "abcipp"))]
+ use crate::facade::tendermint_proto::abci::{
+ RequestApplySnapshotChunk, RequestCheckTx, RequestCommit, RequestEcho,
+ RequestFlush, RequestInfo, RequestInitChain, RequestListSnapshots,
+ RequestLoadSnapshotChunk, RequestOfferSnapshot, RequestPrepareProposal,
+ RequestProcessProposal, RequestQuery, ResponseApplySnapshotChunk,
+ ResponseCheckTx, ResponseCommit, ResponseEcho, ResponseEndBlock,
+ ResponseFlush, ResponseInfo, ResponseInitChain, ResponseListSnapshots,
+ ResponseLoadSnapshotChunk, ResponseOfferSnapshot,
+ ResponsePrepareProposal, ResponseQuery, VoteInfo,
+ };
use crate::node::ledger::shell;
pub type TxBytes = Vec;
@@ -199,14 +200,14 @@ pub mod shim {
use namada::types::hash::Hash;
use namada::types::storage::{BlockHash, Header};
use namada::types::time::DateTimeUtc;
- #[cfg(not(feature = "abcipp"))]
- use tendermint_proto::abci::Misbehavior as Evidence;
#[cfg(feature = "abcipp")]
use tendermint_proto_abcipp::abci::{
Misbehavior as Evidence, RequestFinalizeBlock,
};
use super::VoteInfo;
+ #[cfg(not(feature = "abcipp"))]
+ use crate::facade::tendermint_proto::abci::Misbehavior as Evidence;
pub struct VerifyHeader;
@@ -423,7 +424,9 @@ pub mod shim {
}
#[cfg(not(feature = "abcipp"))]
- impl From for tendermint_proto::abci::ResponseEndBlock {
+ impl From
+ for crate::facade::tendermint_proto::abci::ResponseEndBlock
+ {
fn from(resp: FinalizeBlock) -> Self {
Self {
events: resp
diff --git a/apps/src/lib/node/ledger/storage/mod.rs b/apps/src/lib/node/ledger/storage/mod.rs
index 95f947a4b7..e6d060e533 100644
--- a/apps/src/lib/node/ledger/storage/mod.rs
+++ b/apps/src/lib/node/ledger/storage/mod.rs
@@ -248,7 +248,7 @@ mod tests {
// insert
let vp1 = Hash::sha256("vp1".as_bytes());
- storage.write(&key, vp1.clone()).expect("write failed");
+ storage.write(&key, vp1).expect("write failed");
// check
let (vp_code_hash, gas) =
@@ -356,14 +356,16 @@ mod tests {
let is_last_write = blocks_write_value.last().unwrap().1;
// The upper bound is arbitrary.
- for height in storage.last_height.0..storage.last_height.0 + 10 {
+ for height in storage.get_last_block_height().0
+ ..storage.get_last_block_height().0 + 10
+ {
let height = BlockHeight::from(height);
let (value_bytes, _gas) = storage.read_with_height(&key, height)?;
if is_last_write {
let value_bytes =
value_bytes.expect("Should have been written");
let value: BlockHeight = types::decode(value_bytes).unwrap();
- assert_eq!(value, storage.last_height);
+ assert_eq!(value, storage.get_last_block_height());
} else if value_bytes.is_some() {
let value: BlockHeight =
types::decode(value_bytes.unwrap()).unwrap();
diff --git a/apps/src/lib/node/ledger/storage/rocksdb.rs b/apps/src/lib/node/ledger/storage/rocksdb.rs
index 9d54bc6de3..6108cdf289 100644
--- a/apps/src/lib/node/ledger/storage/rocksdb.rs
+++ b/apps/src/lib/node/ledger/storage/rocksdb.rs
@@ -23,6 +23,7 @@
//! - `root`: root hash
//! - `store`: the tree's store
//! - `hash`: block hash
+//! - `time`: block time
//! - `epoch`: block epoch
//! - `address_gen`: established address generator
//! - `header`: block's header
@@ -412,9 +413,8 @@ impl RocksDB {
let batch = Mutex::new(batch);
tracing::info!("Restoring previous hight subspace diffs");
- self.iter_prefix(&Key::default())
- .par_bridge()
- .try_for_each(|(key, _value, _gas)| -> Result<()> {
+ self.iter_optional_prefix(None).par_bridge().try_for_each(
+ |(key, _value, _gas)| -> Result<()> {
// Restore previous height diff if present, otherwise delete the
// subspace key
let subspace_cf = self.get_column_family(SUBSPACE_CF)?;
@@ -432,7 +432,8 @@ impl RocksDB {
}
Ok(())
- })?;
+ },
+ )?;
tracing::info!("Deleting keys prepended with the last height");
let mut batch = batch.into_inner().unwrap();
@@ -537,6 +538,19 @@ impl DB for RocksDB {
return Ok(None);
}
};
+ let update_epoch_blocks_delay: Option = match self
+ .0
+ .get_cf(state_cf, "update_epoch_blocks_delay")
+ .map_err(|e| Error::DBError(e.into_string()))?
+ {
+ Some(bytes) => types::decode(bytes).map_err(Error::CodingError)?,
+ None => {
+ tracing::error!(
+ "Couldn't load epoch update block delay from the DB"
+ );
+ return Ok(None);
+ }
+ };
let tx_queue: TxQueue = match self
.0
.get_cf(state_cf, "tx_queue")
@@ -557,6 +571,7 @@ impl DB for RocksDB {
read_opts.set_iterate_upper_bound(next_height_prefix);
let mut merkle_tree_stores = MerkleTreeStoresRead::default();
let mut hash = None;
+ let mut time = None;
let mut epoch = None;
let mut pred_epochs = None;
let mut address_gen = None;
@@ -605,6 +620,11 @@ impl DB for RocksDB {
types::decode(bytes).map_err(Error::CodingError)?,
)
}
+ "time" => {
+ time = Some(
+ types::decode(bytes).map_err(Error::CodingError)?,
+ )
+ }
"epoch" => {
epoch = Some(
types::decode(bytes).map_err(Error::CodingError)?,
@@ -625,21 +645,27 @@ impl DB for RocksDB {
None => unknown_key_error(path)?,
}
}
- match (hash, epoch, pred_epochs, address_gen) {
- (Some(hash), Some(epoch), Some(pred_epochs), Some(address_gen)) => {
- Ok(Some(BlockStateRead {
- merkle_tree_stores,
- hash,
- height,
- epoch,
- pred_epochs,
- results,
- next_epoch_min_start_height,
- next_epoch_min_start_time,
- address_gen,
- tx_queue,
- }))
- }
+ match (hash, time, epoch, pred_epochs, address_gen) {
+ (
+ Some(hash),
+ Some(time),
+ Some(epoch),
+ Some(pred_epochs),
+ Some(address_gen),
+ ) => Ok(Some(BlockStateRead {
+ merkle_tree_stores,
+ hash,
+ height,
+ time,
+ epoch,
+ pred_epochs,
+ results,
+ next_epoch_min_start_height,
+ next_epoch_min_start_time,
+ update_epoch_blocks_delay,
+ address_gen,
+ tx_queue,
+ })),
_ => Err(Error::Temporary {
error: "Essential data couldn't be read from the DB"
.to_string(),
@@ -658,12 +684,14 @@ impl DB for RocksDB {
header,
hash,
height,
+ time,
epoch,
pred_epochs,
- results,
next_epoch_min_start_height,
next_epoch_min_start_time,
+ update_epoch_blocks_delay,
address_gen,
+ results,
tx_queue,
}: BlockStateWrite = state;
@@ -704,6 +732,24 @@ impl DB for RocksDB {
"next_epoch_min_start_time",
types::encode(&next_epoch_min_start_time),
);
+ if let Some(current_value) = self
+ .0
+ .get_cf(state_cf, "update_epoch_blocks_delay")
+ .map_err(|e| Error::DBError(e.into_string()))?
+ {
+ // Write the predecessor value for rollback
+ batch.0.put_cf(
+ state_cf,
+ "pred/update_epoch_blocks_delay",
+ current_value,
+ );
+ }
+ batch.0.put_cf(
+ state_cf,
+ "update_epoch_blocks_delay",
+ types::encode(&update_epoch_blocks_delay),
+ );
+
// Tx queue
if let Some(pred_tx_queue) = self
.0
@@ -770,6 +816,15 @@ impl DB for RocksDB {
.0
.put_cf(block_cf, key.to_string(), types::encode(&hash));
}
+ // Block time
+ {
+ let key = prefix_key
+ .push(&"time".to_owned())
+ .map_err(Error::KeyError)?;
+ batch
+ .0
+ .put_cf(block_cf, key.to_string(), types::encode(&time));
+ }
// Block epoch
{
let key = prefix_key
@@ -1188,9 +1243,9 @@ impl DB for RocksDB {
impl<'iter> DBIter<'iter> for RocksDB {
type PrefixIter = PersistentPrefixIterator<'iter>;
- fn iter_prefix(
+ fn iter_optional_prefix(
&'iter self,
- prefix: &Key,
+ prefix: Option<&Key>,
) -> PersistentPrefixIterator<'iter> {
iter_subspace_prefix(self, prefix)
}
@@ -1228,13 +1283,17 @@ impl<'iter> DBIter<'iter> for RocksDB {
fn iter_subspace_prefix<'iter>(
db: &'iter RocksDB,
- prefix: &Key,
+ prefix: Option<&Key>,
) -> PersistentPrefixIterator<'iter> {
let subspace_cf = db
.get_column_family(SUBSPACE_CF)
.expect("{SUBSPACE_CF} column family should exist");
let db_prefix = "".to_owned();
- iter_prefix(db, subspace_cf, db_prefix, prefix.to_string())
+ let prefix_string = match prefix {
+ Some(prefix) => prefix.to_string(),
+ None => "".to_string(),
+ };
+ iter_prefix(db, subspace_cf, db_prefix, prefix_string)
}
fn iter_diffs_prefix(
@@ -1407,11 +1466,13 @@ mod test {
let merkle_tree = MerkleTree::::default();
let merkle_tree_stores = merkle_tree.stores();
let hash = BlockHash::default();
+ let time = DateTimeUtc::now();
let epoch = Epoch::default();
let pred_epochs = Epochs::default();
let height = BlockHeight::default();
let next_epoch_min_start_height = BlockHeight::default();
let next_epoch_min_start_time = DateTimeUtc::now();
+ let update_epoch_blocks_delay = None;
let address_gen = EstablishedAddressGen::new("whatever");
let tx_queue = TxQueue::default();
let results = BlockResults::default();
@@ -1420,11 +1481,13 @@ mod test {
header: None,
hash: &hash,
height,
+ time,
epoch,
results: &results,
pred_epochs: &pred_epochs,
next_epoch_min_start_height,
next_epoch_min_start_time,
+ update_epoch_blocks_delay,
address_gen: &address_gen,
tx_queue: &tx_queue,
};
diff --git a/apps/src/lib/node/ledger/tendermint_node.rs b/apps/src/lib/node/ledger/tendermint_node.rs
index 63c9cd40c2..2bd5168ffa 100644
--- a/apps/src/lib/node/ledger/tendermint_node.rs
+++ b/apps/src/lib/node/ledger/tendermint_node.rs
@@ -9,8 +9,6 @@ use namada::types::key::*;
use namada::types::storage::BlockHeight;
use namada::types::time::DateTimeUtc;
use serde_json::json;
-#[cfg(feature = "abciplus")]
-use tendermint::Moniker;
#[cfg(feature = "abcipp")]
use tendermint_abcipp::Moniker;
use thiserror::Error;
@@ -20,32 +18,33 @@ use tokio::process::Command;
use crate::cli::namada_version;
use crate::config;
+#[cfg(feature = "abciplus")]
+use crate::facade::tendermint::Moniker;
use crate::facade::tendermint::{block, Genesis};
-use crate::facade::tendermint_config::net::Address as TendermintAddress;
use crate::facade::tendermint_config::{
- Error as TendermintError, TendermintConfig, TxIndexConfig, TxIndexer,
+ Error as TendermintError, TendermintConfig,
};
/// Env. var to output Tendermint log to stdout
-pub const ENV_VAR_TM_STDOUT: &str = "NAMADA_TM_STDOUT";
+pub const ENV_VAR_TM_STDOUT: &str = "NAMADA_CMT_STDOUT";
#[derive(Error, Debug)]
pub enum Error {
- #[error("Failed to initialize Tendermint: {0}")]
+ #[error("Failed to initialize CometBFT: {0}")]
Init(std::io::Error),
- #[error("Failed to load Tendermint config file: {0}")]
+ #[error("Failed to load CometBFT config file: {0}")]
LoadConfig(TendermintError),
- #[error("Failed to open Tendermint config for writing: {0}")]
+ #[error("Failed to open CometBFT config for writing: {0}")]
OpenWriteConfig(std::io::Error),
- #[error("Failed to serialize Tendermint config TOML to string: {0}")]
+ #[error("Failed to serialize CometBFT config TOML to string: {0}")]
ConfigSerializeToml(toml::ser::Error),
- #[error("Failed to write Tendermint config: {0}")]
+ #[error("Failed to write CometBFT config: {0}")]
WriteConfig(std::io::Error),
- #[error("Failed to start up Tendermint node: {0}")]
+ #[error("Failed to start up CometBFT node: {0}")]
StartUp(std::io::Error),
#[error("{0}")]
Runtime(String),
- #[error("Failed to rollback tendermint state: {0}")]
+ #[error("Failed to rollback CometBFT state: {0}")]
RollBack(String),
#[error("Failed to convert to String: {0:?}")]
TendermintPath(std::ffi::OsString),
@@ -53,17 +52,17 @@ pub enum Error {
pub type Result = std::result::Result;
-/// Check if the TENDERMINT env var has been set and use that as the
-/// location of the tendermint binary. Otherwise, assume it is on path
+/// Check if the COMET env var has been set and use that as the
+/// location of the COMET binary. Otherwise, assume it is on path
///
/// Returns an error if the env var is defined but not a valid Unicode.
fn from_env_or_default() -> Result {
- match std::env::var("TENDERMINT") {
+ match std::env::var("COMETBFT") {
Ok(path) => {
- tracing::info!("Using tendermint path from env variable: {}", path);
+ tracing::info!("Using CometBFT path from env variable: {}", path);
Ok(path)
}
- Err(std::env::VarError::NotPresent) => Ok(String::from("tendermint")),
+ Err(std::env::VarError::NotPresent) => Ok(String::from("cometbft")),
Err(std::env::VarError::NotUnicode(msg)) => {
Err(Error::TendermintPath(msg))
}
@@ -75,15 +74,15 @@ pub async fn run(
home_dir: PathBuf,
chain_id: ChainId,
genesis_time: DateTimeUtc,
- ledger_address: String,
- config: config::Tendermint,
+ proxy_app_address: String,
+ config: config::Ledger,
abort_recv: tokio::sync::oneshot::Receiver<
tokio::sync::oneshot::Sender<()>,
>,
) -> Result<()> {
let home_dir_string = home_dir.to_string_lossy().to_string();
let tendermint_path = from_env_or_default()?;
- let mode = config.tendermint_mode.to_str().to_owned();
+ let mode = config.shell.tendermint_mode.to_str().to_owned();
#[cfg(feature = "dev")]
// This has to be checked before we run tendermint init
@@ -115,13 +114,13 @@ pub async fn run(
#[cfg(not(feature = "abcipp"))]
write_tm_genesis(&home_dir, chain_id, genesis_time).await;
- update_tendermint_config(&home_dir, config).await?;
+ update_tendermint_config(&home_dir, config.cometbft).await?;
let mut tendermint_node = Command::new(&tendermint_path);
tendermint_node.args([
"start",
"--proxy_app",
- &ledger_address,
+ &proxy_app_address,
"--home",
&home_dir_string,
]);
@@ -138,7 +137,7 @@ pub async fn run(
.kill_on_drop(true)
.spawn()
.map_err(Error::StartUp)?;
- tracing::info!("Tendermint node started");
+ tracing::info!("CometBFT node started");
tokio::select! {
status = tendermint_node.wait() => {
@@ -348,24 +347,16 @@ pub fn write_validator_state(home_dir: impl AsRef) {
async fn update_tendermint_config(
home_dir: impl AsRef,
- tendermint_config: config::Tendermint,
+ config: TendermintConfig,
) -> Result<()> {
let home_dir = home_dir.as_ref();
let path = home_dir.join("config").join("config.toml");
- let mut config =
- TendermintConfig::load_toml_file(&path).map_err(Error::LoadConfig)?;
+ let mut config = config.clone();
config.moniker =
Moniker::from_str(&format!("{}-{}", config.moniker, namada_version()))
.expect("Invalid moniker");
- config.p2p.laddr =
- TendermintAddress::from_str(&tendermint_config.p2p_address.to_string())
- .unwrap();
- config.p2p.persistent_peers = tendermint_config.p2p_persistent_peers;
- config.p2p.pex = tendermint_config.p2p_pex;
- config.p2p.allow_duplicate_ip = tendermint_config.p2p_allow_duplicate_ip;
-
// In "dev", only produce blocks when there are txs or when the AppHash
// changes
config.consensus.create_empty_blocks = true; // !cfg!(feature = "dev");
@@ -375,36 +366,10 @@ async fn update_tendermint_config(
// again in the future.
config.mempool.keep_invalid_txs_in_cache = false;
- config.rpc.laddr =
- TendermintAddress::from_str(&tendermint_config.rpc_address.to_string())
- .unwrap();
// Bumped from the default `1_000_000`, because some WASMs can be
// quite large
config.rpc.max_body_bytes = 2_000_000;
- config.instrumentation.prometheus =
- tendermint_config.instrumentation_prometheus;
- config.instrumentation.prometheus_listen_addr = tendermint_config
- .instrumentation_prometheus_listen_addr
- .to_string();
- config.instrumentation.namespace =
- tendermint_config.instrumentation_namespace;
-
- #[cfg(feature = "abciplus")]
- {
- config.consensus.timeout_commit =
- tendermint_config.consensus_timeout_commit;
- }
-
- let indexer = if tendermint_config.tx_index {
- TxIndexer::Kv
- } else {
- TxIndexer::Null
- };
- #[cfg(feature = "abcipp")]
- let indexer = [indexer];
- config.tx_index = TxIndexConfig { indexer };
-
let mut file = OpenOptions::new()
.write(true)
.truncate(true)
@@ -474,8 +439,8 @@ async fn write_tm_genesis(
)
});
let data = serde_json::to_vec_pretty(&genesis)
- .expect("Couldn't encode the Tendermint genesis file");
+ .expect("Couldn't encode the CometBFT genesis file");
file.write_all(&data[..])
.await
- .expect("Couldn't write the Tendermint genesis file");
+ .expect("Couldn't write the CometBFT genesis file");
}
diff --git a/apps/src/lib/wallet/defaults.rs b/apps/src/lib/wallet/defaults.rs
index 95d1fe035b..c9d37c9e86 100644
--- a/apps/src/lib/wallet/defaults.rs
+++ b/apps/src/lib/wallet/defaults.rs
@@ -1,6 +1,6 @@
//! Default addresses and keys.
-#[cfg(feature = "dev")]
+#[cfg(any(test, feature = "dev"))]
pub use dev::{
addresses, albert_address, albert_keypair, bertha_address, bertha_keypair,
christel_address, christel_keypair, daewon_address, daewon_keypair, keys,
@@ -68,7 +68,7 @@ pub fn addresses_from_genesis(genesis: GenesisConfig) -> Vec<(Alias, Address)> {
addresses
}
-#[cfg(feature = "dev")]
+#[cfg(any(test, feature = "dev"))]
mod dev {
use std::collections::HashMap;
diff --git a/apps/src/lib/wallet/keys.rs b/apps/src/lib/wallet/keys.rs
deleted file mode 100644
index 8b13789179..0000000000
--- a/apps/src/lib/wallet/keys.rs
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/apps/src/lib/wallet/mod.rs b/apps/src/lib/wallet/mod.rs
index 04aae73dc6..5e97d1bd68 100644
--- a/apps/src/lib/wallet/mod.rs
+++ b/apps/src/lib/wallet/mod.rs
@@ -1,5 +1,4 @@
pub mod defaults;
-mod keys;
pub mod pre_genesis;
mod store;
@@ -7,15 +6,16 @@ use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::{env, fs};
+use namada::bip39::{Language, Mnemonic};
pub use namada::ledger::wallet::alias::Alias;
use namada::ledger::wallet::{
- ConfirmationResponse, FindKeyError, Wallet, WalletUtils,
-};
-pub use namada::ledger::wallet::{
- DecryptionError, StoredKeypair, ValidatorData, ValidatorKeys,
+ ConfirmationResponse, FindKeyError, GenRestoreKeyError, Wallet, WalletUtils,
};
+pub use namada::ledger::wallet::{ValidatorData, ValidatorKeys};
use namada::types::key::*;
+use rand_core::OsRng;
pub use store::wallet_file;
+use zeroize::Zeroizing;
use crate::cli;
use crate::config::genesis::genesis_config::GenesisConfig;
@@ -24,28 +24,57 @@ use crate::config::genesis::genesis_config::GenesisConfig;
pub struct CliWalletUtils;
impl WalletUtils for CliWalletUtils {
+ type Rng = OsRng;
type Storage = PathBuf;
- /// Read the password for encryption/decryption from the file/env/stdin.
- /// Panics if all options are empty/invalid.
- fn read_password(prompt_msg: &str) -> String {
+ fn read_decryption_password() -> Zeroizing {
+ match env::var("NAMADA_WALLET_PASSWORD_FILE") {
+ Ok(path) => Zeroizing::new(
+ fs::read_to_string(path)
+ .expect("Something went wrong reading the file"),
+ ),
+ Err(_) => match env::var("NAMADA_WALLET_PASSWORD") {
+ Ok(password) => Zeroizing::new(password),
+ Err(_) => {
+ let prompt = "Enter your decryption password: ";
+ rpassword::read_password_from_tty(Some(prompt))
+ .map(Zeroizing::new)
+ .expect("Failed reading password from tty.")
+ }
+ },
+ }
+ }
+
+ fn read_encryption_password() -> Zeroizing {
let pwd = match env::var("NAMADA_WALLET_PASSWORD_FILE") {
- Ok(path) => fs::read_to_string(path)
- .expect("Something went wrong reading the file"),
+ Ok(path) => Zeroizing::new(
+ fs::read_to_string(path)
+ .expect("Something went wrong reading the file"),
+ ),
Err(_) => match env::var("NAMADA_WALLET_PASSWORD") {
- Ok(password) => password,
- Err(_) => rpassword::read_password_from_tty(Some(prompt_msg))
- .unwrap_or_default(),
+ Ok(password) => Zeroizing::new(password),
+ Err(_) => {
+ let prompt = "Enter your encryption password: ";
+ read_and_confirm_passphrase_tty(prompt).unwrap_or_else(
+ |e| {
+ eprintln!("{e}");
+ eprintln!(
+ "Action cancelled, no changes persisted."
+ );
+ cli::safe_exit(1)
+ },
+ )
+ }
},
};
- if pwd.is_empty() {
+ if pwd.as_str().is_empty() {
eprintln!("Password cannot be empty");
+ eprintln!("Action cancelled, no changes persisted.");
cli::safe_exit(1)
}
pwd
}
- /// Read an alias from the file/env/stdin.
fn read_alias(prompt_msg: &str) -> String {
print!("Choose an alias for {}: ", prompt_msg);
io::stdout().flush().unwrap();
@@ -54,6 +83,26 @@ impl WalletUtils for CliWalletUtils {
alias.trim().to_owned()
}
+ fn read_mnemonic_code() -> Result {
+ let phrase = get_secure_user_input("Input mnemonic code: ")
+ .map_err(|_| GenRestoreKeyError::MnemonicInputError)?;
+ Mnemonic::from_phrase(phrase.as_ref(), Language::English)
+ .map_err(|_| GenRestoreKeyError::MnemonicInputError)
+ }
+
+ fn read_mnemonic_passphrase(confirm: bool) -> Zeroizing {
+ let prompt = "Enter BIP39 passphrase (empty for none): ";
+ let result = if confirm {
+ read_and_confirm_passphrase_tty(prompt)
+ } else {
+ rpassword::read_password_from_tty(Some(prompt)).map(Zeroizing::new)
+ };
+ result.unwrap_or_else(|e| {
+ eprintln!("{}", e);
+ cli::safe_exit(1);
+ })
+ }
+
// The given alias has been selected but conflicts with another alias in
// the store. Offer the user to either replace existing mapping, alter the
// chosen alias to a name of their chosing, or cancel the aliasing.
@@ -101,6 +150,38 @@ impl WalletUtils for CliWalletUtils {
}
}
+fn get_secure_user_input(request: S) -> std::io::Result>
+where
+ S: std::fmt::Display,
+{
+ print!("{} ", request);
+ std::io::stdout().flush()?;
+
+ let mut response = Zeroizing::default();
+ std::io::stdin().read_line(&mut response)?;
+ Ok(response)
+}
+
+pub fn read_and_confirm_passphrase_tty(
+ prompt: &str,
+) -> Result, std::io::Error> {
+ let passphrase =
+ rpassword::read_password_from_tty(Some(prompt)).map(Zeroizing::new)?;
+ if !passphrase.is_empty() {
+ let confirmed = rpassword::read_password_from_tty(Some(
+ "Enter same passphrase again: ",
+ ))
+ .map(Zeroizing::new)?;
+ if confirmed != passphrase {
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::InvalidInput,
+ "Passphrases did not match",
+ ));
+ }
+ }
+ Ok(passphrase)
+}
+
/// Generate keypair
/// for signing protocol txs and for the DKG (which will also be stored)
/// A protocol keypair may be optionally provided, indicating that
@@ -183,28 +264,38 @@ pub fn load_or_new_from_genesis(
Wallet::::new(store_dir.to_path_buf(), store)
}
-/// Read the password for encryption from the file/env/stdin with
-/// confirmation.
-pub fn read_and_confirm_pwd(unsafe_dont_encrypt: bool) -> Option {
- let password = if unsafe_dont_encrypt {
+/// Read the password for encryption from the file/env/stdin, with
+/// confirmation if read from stdin.
+pub fn read_and_confirm_encryption_password(
+ unsafe_dont_encrypt: bool,
+) -> Option> {
+ if unsafe_dont_encrypt {
println!("Warning: The keypair will NOT be encrypted.");
None
} else {
- Some(CliWalletUtils::read_password(
- "Enter your encryption password: ",
- ))
- };
- // Bis repetita for confirmation.
- let to_confirm = if unsafe_dont_encrypt {
- None
- } else {
- Some(CliWalletUtils::read_password(
- "To confirm, please enter the same encryption password once more: ",
- ))
- };
- if to_confirm != password {
- eprintln!("Your two inputs do not match!");
- cli::safe_exit(1)
+ Some(CliWalletUtils::read_encryption_password())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use namada::bip39::MnemonicType;
+ use namada::ledger::wallet::WalletUtils;
+ use rand_core;
+
+ use super::CliWalletUtils;
+
+ #[test]
+ fn test_generate_mnemonic() {
+ const MNEMONIC_TYPE: MnemonicType = MnemonicType::Words12;
+
+ let mut rng = rand_core::OsRng;
+ let mnemonic1 =
+ CliWalletUtils::generate_mnemonic_code(MNEMONIC_TYPE, &mut rng)
+ .unwrap();
+ let mnemonic2 =
+ CliWalletUtils::generate_mnemonic_code(MNEMONIC_TYPE, &mut rng)
+ .unwrap();
+ assert_ne!(mnemonic1.into_phrase(), mnemonic2.into_phrase());
}
- password
}
diff --git a/apps/src/lib/wallet/pre_genesis.rs b/apps/src/lib/wallet/pre_genesis.rs
index 12209d5674..55638ab31e 100644
--- a/apps/src/lib/wallet/pre_genesis.rs
+++ b/apps/src/lib/wallet/pre_genesis.rs
@@ -8,9 +8,10 @@ use namada::ledger::wallet::pre_genesis::{
};
use namada::ledger::wallet::{gen_key_to_store, WalletUtils};
use namada::types::key::SchemeType;
+use zeroize::Zeroizing;
use crate::wallet::store::gen_validator_keys;
-use crate::wallet::{read_and_confirm_pwd, CliWalletUtils};
+use crate::wallet::{read_and_confirm_encryption_password, CliWalletUtils};
/// Validator pre-genesis wallet file name
const VALIDATOR_FILE_NAME: &str = "wallet.toml";
@@ -27,7 +28,7 @@ pub fn gen_and_store(
unsafe_dont_encrypt: bool,
store_dir: &Path,
) -> std::io::Result {
- let password = read_and_confirm_pwd(unsafe_dont_encrypt);
+ let password = read_and_confirm_encryption_password(unsafe_dont_encrypt);
let validator = gen(scheme, password);
let data = validator.store.encode();
let wallet_path = validator_file_name(store_dir);
@@ -66,9 +67,7 @@ pub fn load(store_dir: &Path) -> Result {
|| store.consensus_key.is_encrypted()
|| store.account_key.is_encrypted()
{
- Some(CliWalletUtils::read_password(
- "Enter decryption password: ",
- ))
+ Some(CliWalletUtils::read_decryption_password())
} else {
None
};
@@ -99,17 +98,20 @@ pub fn load(store_dir: &Path) -> Result {
/// Generate a new [`ValidatorWallet`] with required pre-genesis keys. Will
/// prompt for password when `!unsafe_dont_encrypt`.
-fn gen(scheme: SchemeType, password: Option) -> ValidatorWallet {
- let (account_key, account_sk) = gen_key_to_store(scheme, &password);
+fn gen(
+ scheme: SchemeType,
+ password: Option>,
+) -> ValidatorWallet {
+ let (account_key, account_sk) = gen_key_to_store(scheme, password.clone());
let (consensus_key, consensus_sk) = gen_key_to_store(
// Note that TM only allows ed25519 for consensus key
SchemeType::Ed25519,
- &password,
+ password.clone(),
);
let (tendermint_node_key, tendermint_node_sk) = gen_key_to_store(
// Note that TM only allows ed25519 for node IDs
SchemeType::Ed25519,
- &password,
+ password,
);
let validator_keys = gen_validator_keys(None, scheme);
let store = ValidatorStore {
diff --git a/apps/src/lib/wallet/store.rs b/apps/src/lib/wallet/store.rs
index fcdcfb24d9..4b2fcfa9ed 100644
--- a/apps/src/lib/wallet/store.rs
+++ b/apps/src/lib/wallet/store.rs
@@ -12,7 +12,7 @@ use file_lock::{FileLock, FileOptions};
use namada::ledger::wallet::store::AddressVpType;
#[cfg(feature = "dev")]
use namada::ledger::wallet::StoredKeypair;
-use namada::ledger::wallet::{gen_sk, Store, ValidatorKeys};
+use namada::ledger::wallet::{gen_sk_rng, Store, ValidatorKeys};
#[cfg(not(feature = "dev"))]
use namada::types::address::Address;
use namada::types::key::*;
@@ -169,7 +169,8 @@ pub fn gen_validator_keys(
protocol_keypair: Option,
scheme: SchemeType,
) -> ValidatorKeys {
- let protocol_keypair = protocol_keypair.unwrap_or_else(|| gen_sk(scheme));
+ let protocol_keypair =
+ protocol_keypair.unwrap_or_else(|| gen_sk_rng(scheme));
let dkg_keypair = ferveo_common::Keypair::::new(
&mut StdRng::from_entropy(),
);
diff --git a/core/Cargo.toml b/core/Cargo.toml
index 0e98344216..45e1bc7976 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -1,13 +1,19 @@
[package]
-authors = ["Heliax AG "]
-edition = "2021"
-license = "GPL-3.0"
name = "namada_core"
+description = "Namada core"
resolver = "2"
-version = "0.16.0"
+authors.workspace = true
+edition.workspace = true
+documentation.workspace = true
+homepage.workspace = true
+keywords.workspace = true
+license.workspace = true
+readme.workspace = true
+repository.workspace = true
+version.workspace = true
[features]
-default = []
+default = ["abciplus", "ferveo-tpke"]
mainnet = []
ferveo-tpke = [
"ferveo",
@@ -25,12 +31,6 @@ secp256k1-sign-verify = [
"libsecp256k1/hmac",
]
-abcipp = [
- "ibc-proto-abcipp",
- "ibc-abcipp",
- "tendermint-abcipp",
- "tendermint-proto-abcipp",
-]
abciplus = [
"ibc",
"ibc-proto",
@@ -42,10 +42,6 @@ ibc-mocks = [
"ibc/mocks",
"ibc/std",
]
-ibc-mocks-abcipp = [
- "ibc-abcipp/mocks",
- "ibc-abcipp/std",
-]
# for integration tests and test utilies
testing = [
@@ -56,61 +52,53 @@ testing = [
[dependencies]
namada_macros = {path = "../macros"}
-ark-bls12-381 = {version = "0.3"}
+ark-bls12-381.workspace = true
ark-ec = {version = "0.3", optional = true}
-ark-serialize = {version = "0.3"}
-# We switch off "blake2b" because it cannot be compiled to wasm
-# branch = "bat/arse-merkle-tree"
-arse-merkle-tree = {package = "sparse-merkle-tree", git = "https://github.com/heliaxdev/sparse-merkle-tree", rev = "e086b235ed6e68929bf73f617dd61cd17b000a56", default-features = false, features = ["std", "borsh"]}
-bech32 = "0.8.0"
-bellman = "0.11.2"
-borsh = "0.9.0"
-chrono = {version = "0.4.22", default-features = false, features = ["clock", "std"]}
-data-encoding = "2.3.2"
-derivative = "2.2.0"
-ed25519-consensus = "1.2.0"
+ark-serialize.workspace = true
+arse-merkle-tree.workspace = true
+bech32.workspace = true
+borsh.workspace = true
+chrono.workspace = true
+data-encoding.workspace = true
+derivative.workspace = true
+ed25519-consensus.workspace = true
ferveo = {optional = true, git = "https://github.com/anoma/ferveo", rev = "e5abd0acc938da90140351a65a26472eb495ce4d"}
ferveo-common = {git = "https://github.com/anoma/ferveo", rev = "e5abd0acc938da90140351a65a26472eb495ce4d"}
tpke = {package = "group-threshold-cryptography", optional = true, git = "https://github.com/anoma/ferveo", rev = "e5abd0acc938da90140351a65a26472eb495ce4d"}
# TODO using the same version of tendermint-rs as we do here.
-ibc = {version = "0.36.0", default-features = false, features = ["serde"], optional = true}
-ibc-proto = {version = "0.26.0", default-features = false, optional = true}
-ibc-abcipp = {package = "ibc", git = "https://github.com/heliaxdev/cosmos-ibc-rs", rev = "db14744bfba6239cc5f58345ff90f8b7d42637d6", default-features = false, features = ["serde"], optional = true}
-ibc-proto-abcipp = {package = "ibc-proto", git = "https://github.com/heliaxdev/ibc-proto-rs", rev = "dd8ba23110a144ffe2074a0b889676468266435a", default-features = false, optional = true}
-ics23 = "0.9.0"
-index-set = {git = "https://github.com/heliaxdev/index-set", tag = "v0.7.1", features = ["serialize-borsh", "serialize-serde"]}
-itertools = "0.10.0"
-libsecp256k1 = {git = "https://github.com/heliaxdev/libsecp256k1", rev = "bbb3bd44a49db361f21d9db80f9a087c194c0ae9", default-features = false, features = ["std", "static-context"]}
-masp_primitives = { git = "https://github.com/anoma/masp", rev = "bee40fc465f6afbd10558d12fe96eb1742eee45c" }
-proptest = {git = "https://github.com/heliaxdev/proptest", rev = "8f1b4abe7ebd35c0781bf9a00a4ee59833ffa2a1", optional = true}
-prost = "0.11.6"
-prost-types = "0.11.6"
+ibc = {git = "https://github.com/heliaxdev/cosmos-ibc-rs.git", rev = "e71bc2cc79f8c2b32e970d95312f251398c93d9e", default-features = false, features = ["serde"], optional = true}
+ibc-proto = {git = "https://github.com/heliaxdev/ibc-proto-rs.git", rev = "6f4038fcf4981f1ed70771d1cd89931267f917af", default-features = false, optional = true}
+ics23.workspace = true
+index-set.workspace = true
+itertools.workspace = true
+libsecp256k1.workspace = true
+masp_primitives.workspace = true
+proptest = {version = "1.2.0", optional = true}
+prost.workspace = true
+prost-types.workspace = true
rand = {version = "0.8", optional = true}
rand_core = {version = "0.6", optional = true}
rayon = {version = "=1.5.3", optional = true}
-rust_decimal = { version = "=1.26.1", features = ["borsh"] }
-rust_decimal_macros = "=1.26.1"
-serde = {version = "1.0.125", features = ["derive"]}
-serde_json = "1.0.62"
-sha2 = "0.9.3"
-tendermint = {version = "0.23.6", optional = true}
-tendermint-proto = {version = "0.23.6", optional = true}
-tendermint-abcipp = {package = "tendermint", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", optional = true}
-tendermint-proto-abcipp = {package = "tendermint-proto", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", optional = true}
-thiserror = "1.0.38"
-tracing = "0.1.30"
-zeroize = {version = "1.5.5", features = ["zeroize_derive"]}
+rust_decimal.workspace = true
+rust_decimal_macros.workspace = true
+serde.workspace = true
+serde_json.workspace = true
+sha2.workspace = true
+tendermint = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "02b256829e80f8cfecf3fa0d625c2a76c79cd043", optional = true}
+tendermint-proto = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "02b256829e80f8cfecf3fa0d625c2a76c79cd043", optional = true}
+thiserror.workspace = true
+tracing.workspace = true
+zeroize.workspace = true
[dev-dependencies]
-assert_matches = "1.5.0"
-libsecp256k1 = {git = "https://github.com/heliaxdev/libsecp256k1", rev = "bbb3bd44a49db361f21d9db80f9a087c194c0ae9"}
-pretty_assertions = "0.7.2"
-# A fork with state machine testing
-proptest = {git = "https://github.com/heliaxdev/proptest", rev = "8f1b4abe7ebd35c0781bf9a00a4ee59833ffa2a1"}
-rand = {version = "0.8"}
-rand_core = {version = "0.6"}
-test-log = {version = "0.2.7", default-features = false, features = ["trace"]}
-tracing-subscriber = {version = "0.3.7", default-features = false, features = ["env-filter", "fmt"]}
+assert_matches.workspace = true
+libsecp256k1 = {workspace = true, features = ["hmac"]}
+pretty_assertions.workspace = true
+proptest.workspace = true
+rand.workspace = true
+rand_core.workspace = true
+test-log.workspace = true
+tracing-subscriber.workspace = true
[build-dependencies]
-tonic-build = "0.8.4"
+tonic-build.workspace = true
diff --git a/core/proptest-regressions/ledger/storage/mod.txt b/core/proptest-regressions/ledger/storage/mod.txt
new file mode 100644
index 0000000000..5e452257c0
--- /dev/null
+++ b/core/proptest-regressions/ledger/storage/mod.txt
@@ -0,0 +1,2 @@
+cc 2c5330b824e07348ee588e53138f5df5895149db6b11f98343380b663c8c344c
+
diff --git a/core/src/ledger/ibc/storage.rs b/core/src/ledger/ibc/storage.rs
index fab224e755..bee874bb0e 100644
--- a/core/src/ledger/ibc/storage.rs
+++ b/core/src/ledger/ibc/storage.rs
@@ -16,7 +16,7 @@ use crate::ibc::core::ics24_host::path::{
ReceiptPath, SeqAckPath, SeqRecvPath, SeqSendPath,
};
use crate::ibc::core::ics24_host::Path;
-use crate::types::address::{Address, InternalAddress, HASH_LEN};
+use crate::types::address::{Address, InternalAddress, HASH_HEX_LEN};
use crate::types::storage::{self, DbKeySeg, Key, KeySeg};
const CLIENTS_COUNTER: &str = "clients/counter";
@@ -500,7 +500,7 @@ pub fn token_hash_from_denom(denom: impl AsRef) -> Result