Compare commits

...

14 Commits

Author SHA1 Message Date
ar e5b2d8ba35 Attempts to fix dependabot groups 2024-04-25 12:30:23 -04:00
Arya e5d4d739b7
add(consensus/network): Adds `new_regtest()` constructors to `testnet::Parameters` and `Network` (#8413)
* minor cleanup and rename

* Adds an empty NetworkParameters struct to Network::Testnet variant, updates production code.

* Updates tests

* Adds `NetworkKind` and uses it instead of `Network` in `HistoryTreeParts` and `transparent::Address`

* Adds a [network.testnet_parameters] section to the config, uses `NetworkKind` as zebra_network::Config::network field type, and converts 'Network' to `NetworkKind` before serializing

* Applies some suggestions from code review

* Applies suggestions from code review

* returns b58 prefix constants directly to remove From<NetworkKind> impl for zcash_primitives::consensus::Network

* Applies more suggestions from code review.

* moves conversions to zcash_primitives::consensus::Network to where they're used.

* Apply suggestions from code review

Co-authored-by: Marek <mail@marek.onl>

* rename `network` variables and method names typed as NetworkKind to `network_kind`

* use only test block heights for the network associated with them

* Applies more suggestions from code review.

* Rename `NetworkParameters` to `Parameters` and move it a new `testnet` module

* adds activation heights field

* updates stored test config, adds a quicker test for checking that stored configs can be parsed, adds an intermediate representation of activation heights

* implement Parameters for Network

* Passes &Network directly instead of converting to zp_consensus::Network where there were conversions

* fixes a bad merge (removes a network conversion in zcash_note_encryption)

* Adds a test for the Parameters impl for zebra_chain::Network

* fixes doc links

* - Makes the `activation_heights` config field optional by adding a #[serde(default)]
- Panics if a non-zero activation height is provided for the `Genesis` network upgrade
- Always sets the `Genesis` and `BeforeOverwinter` network upgrade activation heights to 0 and 1, `BeforeOverwinter` could be overwritten by a later network upgrade
- Makes the `activation_heights` field on `Parameters` private, adds/uses an accessor method instead, and adds a builder struct and `build()` method

* small refactor of activation_heights() method

* check that activation heights are in the right order

* Updates `NetworkUpgrade::activation_height()` to return the height of the next NetworkUpgrade if it doesn't find the activation height of `&self`

* checks that the miner address is of TestnetKind on Regtest and update assertion message

* Adds a DNetworkUpgradeActivationHeights struct for better control over how activation heights can be configured

* moves all ordered network upgrades to a constant, adds a no_duplicates test, moves struct with activation heights outside deserialization impl and accepts it in `ParametersBuilder::activation_heights()` instead of a Vec

* panics if any network upgrades are configured to activate at Height(0) because it's reserved for Genesis

* Simplifies the `ParametersBuilder::activation_heights()` method and removes an unnecessary test.

* Adds Sapling HRPs as fields on testnet params. (#8398)

* Applies suggestions from code review.

* Update zebra-chain/src/parameters/network_upgrade.rs

Co-authored-by: Marek <mail@marek.onl>

* Adds `network_name` field and accessor method on `Parameters`, uses it in the `Display` impl for `Network`

* Removes unnecessary `.filter()`

* adds constraints on valid network names and a test

* adds config field for setting network name, adds "with_" prefix to ParameterBuilder setter methods

* Adds `MainnetKind`, `TestnetKind`, and `RegtestKind` to reserved network names

* updates stored test configs and fixes `network_name()` docs

* Adds a `new_regtest()` method on `Network` and `testnet::Parameters`, updates config deserialization to return an error if the initial_testnet_peers include any default initial peers AND contain configured activation heights

* Updates `activates_network_upgrades_correctly` test to check Regtest activation heights (and default Mainnet/Testnet)

* Refactors if-let & match statement into general match statement, removes constraint against including `testnet_parameters` field/section in the config when using `Mainnet` or `Regtest`

* Removes outdated TODO

* Restores `testnet_parameters` section of the latest stored config.

* Adds `with_sapling_hrps()` method and uses it to set the Regtest HRPs in `new_regtest()`.

Adds a test for Sapling HRP validation

* Checks that default Mainnet/Testnet/Regtest Sapling HRPs pass validation in `with_sapling_hrps()`

* Uses the correct constant in test

* Adds `is_regtest()` methods

* Updates test docs

* drop custom panic hooks after expected panics

---------

Co-authored-by: Marek <mail@marek.onl>
2024-04-25 04:04:05 +00:00
Arya e95a70de7a
increases timeout duration waiting on done notification in non-blocking logger test (#8462) 2024-04-24 20:28:17 +00:00
Arya ee9ab3162a
fixes concurrency bug in z_get_treestate RPC method (#8460) 2024-04-24 20:27:56 +00:00
Alfredo Garcia d869ec6fe4
change(release): Adjust estimated release interval and end of support (#8429)
* change estimated release interval and end of support

* update readme
2024-04-24 19:22:07 +00:00
Alfredo Garcia 5f69870235
bump(deps): Update what we can from the prod group of deps (#8423)
* update partially the prod group of deps

* update prod deps
2024-04-24 13:54:00 +00:00
Arya 275e99ec72
add(chain): Adds a `network_name` field to `testnet::Parameters` (#8411)
* minor cleanup and rename

* Adds an empty NetworkParameters struct to Network::Testnet variant, updates production code.

* Updates tests

* Adds `NetworkKind` and uses it instead of `Network` in `HistoryTreeParts` and `transparent::Address`

* Adds a [network.testnet_parameters] section to the config, uses `NetworkKind` as zebra_network::Config::network field type, and converts 'Network' to `NetworkKind` before serializing

* Applies some suggestions from code review

* Applies suggestions from code review

* returns b58 prefix constants directly to remove From<NetworkKind> impl for zcash_primitives::consensus::Network

* Applies more suggestions from code review.

* moves conversions to zcash_primitives::consensus::Network to where they're used.

* Apply suggestions from code review

Co-authored-by: Marek <mail@marek.onl>

* rename `network` variables and method names typed as NetworkKind to `network_kind`

* use only test block heights for the network associated with them

* Applies more suggestions from code review.

* Rename `NetworkParameters` to `Parameters` and move it a new `testnet` module

* adds activation heights field

* updates stored test config, adds a quicker test for checking that stored configs can be parsed, adds an intermediate representation of activation heights

* implement Parameters for Network

* Passes &Network directly instead of converting to zp_consensus::Network where there were conversions

* fixes a bad merge (removes a network conversion in zcash_note_encryption)

* Adds a test for the Parameters impl for zebra_chain::Network

* fixes doc links

* - Makes the `activation_heights` config field optional by adding a #[serde(default)]
- Panics if a non-zero activation height is provided for the `Genesis` network upgrade
- Always sets the `Genesis` and `BeforeOverwinter` network upgrade activation heights to 0 and 1, `BeforeOverwinter` could be overwritten by a later network upgrade
- Makes the `activation_heights` field on `Parameters` private, adds/uses an accessor method instead, and adds a builder struct and `build()` method

* small refactor of activation_heights() method

* check that activation heights are in the right order

* Updates `NetworkUpgrade::activation_height()` to return the height of the next NetworkUpgrade if it doesn't find the activation height of `&self`

* checks that the miner address is of TestnetKind on Regtest and update assertion message

* Adds a DNetworkUpgradeActivationHeights struct for better control over how activation heights can be configured

* moves all ordered network upgrades to a constant, adds a no_duplicates test, moves struct with activation heights outside deserialization impl and accepts it in `ParametersBuilder::activation_heights()` instead of a Vec

* panics if any network upgrades are configured to activate at Height(0) because it's reserved for Genesis

* Simplifies the `ParametersBuilder::activation_heights()` method and removes an unnecessary test.

* Adds Sapling HRPs as fields on testnet params. (#8398)

* Applies suggestions from code review.

* Update zebra-chain/src/parameters/network_upgrade.rs

Co-authored-by: Marek <mail@marek.onl>

* Adds `network_name` field and accessor method on `Parameters`, uses it in the `Display` impl for `Network`

* Removes unnecessary `.filter()`

* adds constraints on valid network names and a test

* adds config field for setting network name, adds "with_" prefix to ParameterBuilder setter methods

* Adds `MainnetKind`, `TestnetKind`, and `RegtestKind` to reserved network names

* updates stored test configs and fixes `network_name()` docs

---------

Co-authored-by: Marek <mail@marek.onl>
2024-04-24 11:03:37 +00:00
Alfredo Garcia 8cf0b7a36a
bump(zcash_script): Bump zcash script v0.1.15 and restore Windows support (#8393)
* update zcash_script and zcash_primitives

* restore windows support

* add a windows config file

* try exact output from CI

* ignore config test in windows

* disable test for windows

* remove test for windows

* change zcash_script branch to release

* bump top the last zcash_script release version

* restore `rejection_restores_internal_state_genesis` test

* fix typo in test name and enable single thread on windows

* disable single thread
2024-04-22 22:07:04 +00:00
dependabot[bot] 74319ec477
build(deps): bump rustls from 0.21.10 to 0.21.11 in the cargo group (#8418)
Bumps the cargo group with 1 update: [rustls](https://github.com/rustls/rustls).


Updates `rustls` from 0.21.10 to 0.21.11
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustls/rustls/compare/v/0.21.10...v/0.21.11)

---
updated-dependencies:
- dependency-name: rustls
  dependency-type: indirect
  dependency-group: cargo
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-22 19:32:06 +00:00
Marek 2ba837470e
Bump `chrono` from 0.4.34 to 0.4.38 (#8400)
* Bump `chrono` from 0.4.34 to 0.4.38

* Stop using the deprecated `from_timestamp_opt`

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-04-19 23:23:57 +00:00
dependabot[bot] f1334a8378
build(deps): bump the devops group with 2 updates (#8408)
Bumps the devops group with 2 updates: [reviewdog/action-actionlint](https://github.com/reviewdog/action-actionlint) and [baptiste0928/cargo-install](https://github.com/baptiste0928/cargo-install).


Updates `reviewdog/action-actionlint` from 1.43.0 to 1.44.0
- [Release notes](https://github.com/reviewdog/action-actionlint/releases)
- [Commits](https://github.com/reviewdog/action-actionlint/compare/v1.43.0...v1.44.0)

Updates `baptiste0928/cargo-install` from 3.0.1 to 3.1.0
- [Release notes](https://github.com/baptiste0928/cargo-install/releases)
- [Changelog](https://github.com/baptiste0928/cargo-install/blob/main/CHANGELOG.md)
- [Commits](https://github.com/baptiste0928/cargo-install/compare/v3.0.1...v3.1.0)

---
updated-dependencies:
- dependency-name: reviewdog/action-actionlint
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: devops
- dependency-name: baptiste0928/cargo-install
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: devops
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-19 09:25:56 +00:00
Arya f8c153991b
add(consensus): Add `activation_heights` field to `NetworkParameters` and implement `Parameters` for `Network` (#8383)
* minor cleanup and rename

* Adds an empty NetworkParameters struct to Network::Testnet variant, updates production code.

* Updates tests

* Adds `NetworkKind` and uses it instead of `Network` in `HistoryTreeParts` and `transparent::Address`

* Adds a [network.testnet_parameters] section to the config, uses `NetworkKind` as zebra_network::Config::network field type, and converts 'Network' to `NetworkKind` before serializing

* Applies some suggestions from code review

* Applies suggestions from code review

* returns b58 prefix constants directly to remove From<NetworkKind> impl for zcash_primitives::consensus::Network

* Applies more suggestions from code review.

* moves conversions to zcash_primitives::consensus::Network to where they're used.

* Apply suggestions from code review

Co-authored-by: Marek <mail@marek.onl>

* rename `network` variables and method names typed as NetworkKind to `network_kind`

* use only test block heights for the network associated with them

* Applies more suggestions from code review.

* Rename `NetworkParameters` to `Parameters` and move it a new `testnet` module

* adds activation heights field

* updates stored test config, adds a quicker test for checking that stored configs can be parsed, adds an intermediate representation of activation heights

* implement Parameters for Network

* Passes &Network directly instead of converting to zp_consensus::Network where there were conversions

* fixes a bad merge (removes a network conversion in zcash_note_encryption)

* Adds a test for the Parameters impl for zebra_chain::Network

* fixes doc links

* - Makes the `activation_heights` config field optional by adding a #[serde(default)]
- Panics if a non-zero activation height is provided for the `Genesis` network upgrade
- Always sets the `Genesis` and `BeforeOverwinter` network upgrade activation heights to 0 and 1, `BeforeOverwinter` could be overwritten by a later network upgrade
- Makes the `activation_heights` field on `Parameters` private, adds/uses an accessor method instead, and adds a builder struct and `build()` method

* small refactor of activation_heights() method

* check that activation heights are in the right order

* Updates `NetworkUpgrade::activation_height()` to return the height of the next NetworkUpgrade if it doesn't find the activation height of `&self`

* checks that the miner address is of TestnetKind on Regtest and update assertion message

* Adds a DNetworkUpgradeActivationHeights struct for better control over how activation heights can be configured

* moves all ordered network upgrades to a constant, adds a no_duplicates test, moves struct with activation heights outside deserialization impl and accepts it in `ParametersBuilder::activation_heights()` instead of a Vec

* panics if any network upgrades are configured to activate at Height(0) because it's reserved for Genesis

* Simplifies the `ParametersBuilder::activation_heights()` method and removes an unnecessary test.

* Adds Sapling HRPs as fields on testnet params. (#8398)

* Applies suggestions from code review.

* Update zebra-chain/src/parameters/network_upgrade.rs

Co-authored-by: Marek <mail@marek.onl>

---------

Co-authored-by: Marek <mail@marek.onl>
2024-04-19 01:20:34 +00:00
Alfredo Garcia 887d4a2457
fix(beta-toolchain): Warnings (#8404)
* fix beta imports and other warnings

* clippy lints beta

* move attributes to after docs

Co-authored-by: Marek <mail@marek.onl>

* move some code to test module

* implement display instead of direct tostring for LongPollId

Co-authored-by: Arya <aryasolhi@gmail.com>

* fix typo

---------

Co-authored-by: Marek <mail@marek.onl>
Co-authored-by: Arya <aryasolhi@gmail.com>
2024-04-18 01:45:22 +00:00
Alfredo Garcia 2995ea087b
send ping to ES server before inserting data (#8409) 2024-04-17 19:09:16 +00:00
125 changed files with 1317 additions and 523 deletions

View File

@ -19,11 +19,21 @@ updates:
ecc:
patterns:
# deliberately include zcash_script (even though it is maintained by ZF)
- "zcash_*|orchard|halo2*|incrementalmerkletree|bridgetree|equihash"
- "zcash_*
- "orchard"
- "halo2*"
- "incrementalmerkletree"
- "bridgetree"
- "equihash"
prod:
dependency-type: "production"
exclude-patterns:
- "zcash_*|orchard|halo2*|incrementalmerkletree|bridgetree|equihash"
- "zcash_*
- "orchard"
- "halo2*"
- "incrementalmerkletree"
- "bridgetree"
- "equihash"
dev:
dependency-type: "development"
# Devops section

View File

@ -151,7 +151,7 @@ jobs:
steps:
- uses: actions/checkout@v4.1.2
- name: actionlint
uses: reviewdog/action-actionlint@v1.43.0
uses: reviewdog/action-actionlint@v1.44.0
with:
level: warning
fail_on_error: false

View File

@ -78,8 +78,7 @@ jobs:
strategy:
fail-fast: false
matrix:
# TODO: Windows was removed for now, see https://github.com/ZcashFoundation/zebra/issues/3801
os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest, macos-latest, windows-latest]
rust: [stable, beta]
# TODO: When vars.EXPERIMENTAL_FEATURES has features in it, add it here.
# Or work out a way to trim the space from the variable: GitHub doesn't allow empty variables.
@ -281,7 +280,7 @@ jobs:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain=stable --profile=minimal
- name: Install cargo-machete
uses: baptiste0928/cargo-install@v3.0.1
uses: baptiste0928/cargo-install@v3.1.0
with:
crate: cargo-machete

View File

@ -85,7 +85,7 @@ jobs:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain=stable --profile=minimal
- name: Install cargo-release
uses: baptiste0928/cargo-install@v3.0.1
uses: baptiste0928/cargo-install@v3.1.0
with:
crate: cargo-release

View File

@ -239,7 +239,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -250,7 +250,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -415,7 +415,7 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
"syn 2.0.59",
"syn 2.0.60",
"which",
]
@ -705,9 +705,9 @@ dependencies = [
[[package]]
name = "chrono"
version = "0.4.34"
version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b"
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
@ -811,7 +811,7 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -1072,14 +1072,14 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
name = "cxx"
version = "1.0.107"
version = "1.0.113"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe98ba1789d56fb3db3bee5e032774d4f421b685de7ba703643584ba24effbe"
checksum = "048948e14bc2c2652ec606c8e3bb913407f0187288fb351a0b2d972beaf12070"
dependencies = [
"cc",
"cxxbridge-flags",
@ -1089,31 +1089,31 @@ dependencies = [
[[package]]
name = "cxx-gen"
version = "0.7.117"
version = "0.7.121"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54b629c0d006c7e44c1444dd17d18a458c9390d32276b758ac7abd21a75c99b0"
checksum = "383ecb9f96a536a1c7a2a61c5786f583da84f9240da149d78d005a4413c9a71e"
dependencies = [
"codespan-reporting",
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
name = "cxxbridge-flags"
version = "1.0.107"
version = "1.0.113"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20888d9e1d2298e2ff473cee30efe7d5036e437857ab68bbfea84c74dba91da2"
checksum = "af40b0467c68d3d9fb7550ef984edc8ad47252f703ef0f1f2d1052e0e4af8793"
[[package]]
name = "cxxbridge-macro"
version = "1.0.107"
version = "1.0.113"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fa16a70dd58129e4dfffdff535fb1bce66673f7bbeec4a5a1765a504e1ccd84"
checksum = "7743446286141c9f6d4497c493c01234eb848e14d2e20866ae9811eae0630cb9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -1161,7 +1161,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim 0.10.0",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -1183,7 +1183,7 @@ checksum = "c5a91391accf613803c2a9bf9abccdbaa07c54b4244a5b64883f9c3c137c86be"
dependencies = [
"darling_core 0.20.6",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -1256,7 +1256,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -1561,7 +1561,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -2629,7 +2629,7 @@ checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -3064,7 +3064,7 @@ dependencies = [
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -3105,7 +3105,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -3206,7 +3206,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5"
dependencies = [
"proc-macro2",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -3329,7 +3329,7 @@ dependencies = [
"prost",
"prost-types",
"regex",
"syn 2.0.59",
"syn 2.0.60",
"tempfile",
"which",
]
@ -3344,7 +3344,7 @@ dependencies = [
"itertools 0.12.1",
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -3809,9 +3809,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.21.10"
version = "0.21.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4"
dependencies = [
"log",
"ring 0.17.8",
@ -4028,9 +4028,9 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.197"
version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc"
dependencies = [
"serde_derive",
]
@ -4046,20 +4046,20 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.197"
version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
name = "serde_json"
version = "1.0.115"
version = "1.0.116"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
dependencies = [
"indexmap 2.2.6",
"itoa",
@ -4137,7 +4137,7 @@ dependencies = [
"darling 0.20.6",
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -4366,9 +4366,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.59"
version = "2.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a"
checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
dependencies = [
"proc-macro2",
"quote",
@ -4452,29 +4452,29 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.58"
version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.58"
version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
name = "thread-priority"
version = "0.16.0"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a617e9eeeb20448b01a8e2427fb80dfbc9c49d79a1de3b11f25731edbf547e3c"
checksum = "599e8e829c2314b750ecade9309ecc6cf9a48c2e62fe25680b6c1d2172463ca3"
dependencies = [
"bitflags 2.5.0",
"cfg-if 1.0.0",
@ -4590,7 +4590,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -4774,7 +4774,7 @@ dependencies = [
"proc-macro2",
"prost-build",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -4787,7 +4787,7 @@ dependencies = [
"proc-macro2",
"prost-build",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -4917,7 +4917,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -5355,7 +5355,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
"wasm-bindgen-shared",
]
@ -5389,7 +5389,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -5670,9 +5670,9 @@ dependencies = [
[[package]]
name = "zcash_client_backend"
version = "0.10.0-rc.4"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc33f71747a93d509f7e1c047961e359a271bdf4869cc07f7f65ee1ba7df8c2"
checksum = "d6a382af39be9ee5a3788157145c404b7cd19acc440903f6c34b09fb44f0e991"
dependencies = [
"base64 0.21.7",
"bech32",
@ -5737,9 +5737,9 @@ dependencies = [
[[package]]
name = "zcash_primitives"
version = "0.13.0-rc.1"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc4391d9325e0a51a7cbff02b5c4b5472d66087bd9c903ddb12dea7ec22f3e0"
checksum = "d17e4c94ca8d69d2fcf2be97522da5732a580eb2125cda3b150761952f8df8e6"
dependencies = [
"aes",
"bip0039",
@ -5773,9 +5773,9 @@ dependencies = [
[[package]]
name = "zcash_proofs"
version = "0.13.0-rc.1"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48f22eff3bdc382327ef28f809024ddc89ec6d903ba71be629b2cbea34afdda2"
checksum = "df0c99f65a840ff256c106b28d67d702d9759d206112473d4982c92003262406"
dependencies = [
"bellman",
"blake2b_simd",
@ -5804,9 +5804,9 @@ dependencies = [
[[package]]
name = "zcash_script"
version = "0.1.14"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8deff8ea47cbe2a008abefedc1a2d9c0e48a87844379759ace270a0b53353c71"
checksum = "9e3de6aece21108f502f724183955d244e02338613eaa4f9010386c63618a3a8"
dependencies = [
"bellman",
"bindgen",
@ -6187,7 +6187,7 @@ dependencies = [
"serde_json",
"serde_yaml",
"structopt",
"syn 2.0.59",
"syn 2.0.60",
"thiserror",
"tinyvec",
"tokio",
@ -6288,7 +6288,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -6308,5 +6308,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]

View File

@ -68,7 +68,7 @@ Zebra is tested with the latest `stable` Rust version. Earlier versions are not
supported or tested. Any Zebra release can start depending on new features in the
latest stable Rust.
Every few weeks, we release a [new Zebra version](https://github.com/ZcashFoundation/zebra/releases).
Around every 4 weeks, we release a [new Zebra version](https://github.com/ZcashFoundation/zebra/releases).
Below are quick summaries for installing the dependencies on your machine.

View File

@ -33,7 +33,7 @@ The pre-release version is denoted by appending a hyphen and a series of dot sep
### Supported Releases
Every Zebra version released by the Zcash Foundation is supported up to a specific height. Currently we support each version for about **16 weeks** but this can change from release to release.
Every Zebra version released by the Zcash Foundation is supported up to a specific height. Currently we support each version for about **20 weeks** but this can change from release to release.
When the Zcash chain reaches this end of support height, `zebrad` will shut down and the binary will refuse to start.
@ -95,7 +95,7 @@ In general, expect the following release cycle:
* A major release for each network upgrade, whenever there are breaking changes to Zebra (by API, severe bugs or other kind of upgrades)
* Minor releases for significant new Zebra features or severe bug fixes
* A patch release every few weeks
* A patch release around every 4 weeks
This cadence of releases gives eager developers access to new features as soon as they are fully developed and pass through our code review and integration testing processes, while maintaining the stability and reliability of the platform for production users that prefer to receive features after they have been validated by Zcash and other developers that use the pre-release builds.

View File

@ -97,21 +97,21 @@ orchard = "0.6.0"
zcash_encoding = "0.2.0"
zcash_history = "0.4.0"
zcash_note_encryption = "0.4.0"
zcash_primitives = { version = "0.13.0-rc.1", features = ["transparent-inputs"] }
zcash_primitives = { version = "0.13.0", features = ["transparent-inputs"] }
# Time
chrono = { version = "0.4.34", default-features = false, features = ["clock", "std", "serde"] }
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std", "serde"] }
humantime = "2.1.0"
# Error Handling & Formatting
displaydoc = "0.2.4"
static_assertions = "1.1.0"
thiserror = "1.0.58"
thiserror = "1.0.59"
tracing = "0.1.39"
# Serialization
hex = { version = "0.4.3", features = ["serde"] }
serde = { version = "1.0.196", features = ["serde_derive", "rc"] }
serde = { version = "1.0.198", features = ["serde_derive", "rc"] }
serde_with = "3.7.0"
serde-big-array = "0.5.1"
@ -126,7 +126,7 @@ redjubjub = "0.7.0"
reddsa = "0.5.1"
# Production feature json-conversion
serde_json = { version = "1.0.115", optional = true }
serde_json = { version = "1.0.116", optional = true }
# Production feature async-error and testing feature proptest-impl
tokio = { version = "1.37.0", optional = true }

View File

@ -1,22 +1,13 @@
//! Randomised property testing for [`Block`]s.
use std::{collections::HashMap, sync::Arc};
use proptest::{
arbitrary::{any, Arbitrary},
prelude::*,
};
use proptest::prelude::*;
use crate::{
amount::NonNegative,
block,
fmt::{HexDebug, SummaryDebug},
history_tree::HistoryTree,
parameters::{
Network,
NetworkUpgrade::{self, *},
GENESIS_PREVIOUS_BLOCK_HASH,
},
parameters::{NetworkUpgrade::*, GENESIS_PREVIOUS_BLOCK_HASH},
serialization,
transaction::arbitrary::MAX_ARBITRARY_ITEMS,
transparent::{

View File

@ -1,6 +1,6 @@
//! Generate large transparent blocks and transactions for testing.
use chrono::{DateTime, NaiveDateTime, Utc};
use chrono::DateTime;
use std::sync::Arc;
use crate::{
@ -42,18 +42,6 @@ pub fn transaction() -> (Transaction, Vec<u8>) {
(transaction, transaction_bytes)
}
/// Returns a generated transparent lock time, and its canonical serialized bytes.
pub fn lock_time() -> (LockTime, Vec<u8>) {
let lock_time = LockTime::Time(DateTime::<Utc>::from_naive_utc_and_offset(
NaiveDateTime::from_timestamp_opt(61, 0)
.expect("in-range number of seconds and valid nanosecond"),
Utc,
));
let lock_time_bytes = lock_time.zcash_serialize_to_vec().unwrap();
(lock_time, lock_time_bytes)
}
/// Returns a generated transparent input, and its canonical serialized bytes.
pub fn input() -> (transparent::Input, Vec<u8>) {
// Some of the test vectors are in a non-canonical format,
@ -182,8 +170,8 @@ fn single_transaction_block_many_inputs(oversized: bool) -> Block {
// A block header
let (block_header, block_header_bytes) = block_header();
// A LockTime
let (lock_time, lock_time_bytes) = lock_time();
let lock_time = LockTime::Time(DateTime::from_timestamp(61, 0).unwrap());
let lock_time_bytes = lock_time.zcash_serialize_to_vec().unwrap();
// Calculate the number of inputs we need,
// subtracting the bytes used to serialize the expected input count,
@ -256,8 +244,8 @@ fn single_transaction_block_many_outputs(oversized: bool) -> Block {
// A block header
let (block_header, block_header_bytes) = block_header();
// A LockTime
let (lock_time, lock_time_bytes) = lock_time();
let lock_time = LockTime::Time(DateTime::from_timestamp(61, 0).unwrap());
let lock_time_bytes = lock_time.zcash_serialize_to_vec().unwrap();
// Calculate the number of outputs we need,
// subtracting the bytes used to serialize the expected output count,

View File

@ -2,21 +2,19 @@
use std::{env, io::ErrorKind};
use proptest::{arbitrary::any, prelude::*, test_runner::Config};
use proptest::{prelude::*, test_runner::Config};
use hex::{FromHex, ToHex};
use zebra_test::prelude::*;
use crate::{
parameters::{Network, GENESIS_PREVIOUS_BLOCK_HASH},
parameters::GENESIS_PREVIOUS_BLOCK_HASH,
serialization::{SerializationError, ZcashDeserializeInto, ZcashSerialize},
LedgerState,
};
use super::super::{
arbitrary::{allow_all_transparent_coinbase_spends, PREVOUTS_CHAIN_HEIGHT},
serialize::MAX_BLOCK_BYTES,
*,
};

View File

@ -1,4 +1,4 @@
use std::{convert::TryFrom, io};
use std::io;
use halo2::pasta::pallas;
use reddsa::orchard::SpendAuth;

View File

@ -7,7 +7,7 @@ use group::{
use halo2::pasta::pallas;
use reddsa::{orchard::SpendAuth, Signature, SigningKey, VerificationKey, VerificationKeyBytes};
use proptest::{arbitrary::any, array, collection::vec, prelude::*};
use proptest::{array, collection::vec, prelude::*};
use super::{
keys::*, note, tree, Action, AuthorizedAction, Flags, NoteCommitment, ValueCommitment,

View File

@ -1,4 +1,4 @@
use proptest::{arbitrary::any, collection::vec, prelude::*};
use proptest::{collection::vec, prelude::*};
use super::*;

View File

@ -8,7 +8,7 @@ use std::{
use byteorder::{ReadBytesExt, WriteBytesExt};
use halo2::pasta::pallas;
use reddsa::{self, orchard::Binding, orchard::SpendAuth, Signature};
use reddsa::{orchard::Binding, orchard::SpendAuth, Signature};
use crate::{
amount::{Amount, NegativeAllowed},

View File

@ -19,7 +19,7 @@ use std::{
};
use bitvec::prelude::*;
use bridgetree::{self, NonEmptyFrontier};
use bridgetree::NonEmptyFrontier;
use halo2::pasta::{group::ff::PrimeField, pallas};
use hex::ToHex;
use incrementalmerkletree::Hashable;

View File

@ -2,7 +2,7 @@
use proptest::prelude::*;
use super::NetworkUpgrade;
use super::{Network, NetworkUpgrade};
impl NetworkUpgrade {
/// Generates network upgrades.
@ -32,3 +32,13 @@ impl NetworkUpgrade {
.boxed()
}
}
impl Arbitrary for Network {
type Parameters = ();
fn arbitrary_with(_args: ()) -> Self::Strategy {
prop_oneof![Just(Self::Mainnet), Just(Self::new_default_testnet())].boxed()
}
type Strategy = BoxedStrategy<Self>;
}

View File

@ -4,17 +4,16 @@ use std::{fmt, str::FromStr, sync::Arc};
use thiserror::Error;
use zcash_primitives::constants;
use zcash_primitives::{consensus as zp_consensus, constants as zp_constants};
use crate::{
block::{self, Height, HeightDiff},
parameters::NetworkUpgrade::Canopy,
parameters::NetworkUpgrade,
};
pub mod testnet;
use self::testnet::ConfiguredActivationHeights;
#[cfg(any(test, feature = "proptest-impl"))]
use proptest_derive::Arbitrary;
pub mod testnet;
#[cfg(test)]
mod tests;
@ -81,7 +80,6 @@ impl From<Network> for NetworkKind {
/// An enum describing the possible network choices.
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Serialize)]
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
#[serde(into = "NetworkKind")]
pub enum Network {
/// The production mainnet.
@ -98,8 +96,8 @@ impl NetworkKind {
/// pay-to-public-key-hash payment addresses for the network.
pub fn b58_pubkey_address_prefix(self) -> [u8; 2] {
match self {
Self::Mainnet => constants::mainnet::B58_PUBKEY_ADDRESS_PREFIX,
Self::Testnet | Self::Regtest => constants::testnet::B58_PUBKEY_ADDRESS_PREFIX,
Self::Mainnet => zp_constants::mainnet::B58_PUBKEY_ADDRESS_PREFIX,
Self::Testnet | Self::Regtest => zp_constants::testnet::B58_PUBKEY_ADDRESS_PREFIX,
}
}
@ -107,8 +105,8 @@ impl NetworkKind {
/// payment addresses for the network.
pub fn b58_script_address_prefix(self) -> [u8; 2] {
match self {
Self::Mainnet => constants::mainnet::B58_SCRIPT_ADDRESS_PREFIX,
Self::Testnet | Self::Regtest => constants::testnet::B58_SCRIPT_ADDRESS_PREFIX,
Self::Mainnet => zp_constants::mainnet::B58_SCRIPT_ADDRESS_PREFIX,
Self::Testnet | Self::Regtest => zp_constants::testnet::B58_SCRIPT_ADDRESS_PREFIX,
}
}
@ -142,15 +140,11 @@ impl fmt::Display for NetworkKind {
}
}
impl From<&Network> for &'static str {
fn from(network: &Network) -> &'static str {
impl<'a> From<&'a Network> for &'a str {
fn from(network: &'a Network) -> &'a str {
match network {
Network::Mainnet => "Mainnet",
// TODO:
// - Add a `name` field to use here instead of checking `is_default_testnet()`
// - zcashd calls the Regtest cache dir 'regtest' (#8327).
Network::Testnet(params) if params.is_default_testnet() => "Testnet",
Network::Testnet(_params) => "UnknownTestnet",
Network::Testnet(params) => params.network_name(),
}
}
}
@ -172,6 +166,11 @@ impl Network {
Self::Testnet(Arc::new(params))
}
/// Creates a new [`Network::Testnet`] with `Regtest` parameters and the provided network upgrade activation heights.
pub fn new_regtest(activation_heights: ConfiguredActivationHeights) -> Self {
Self::new_configured_testnet(testnet::Parameters::new_regtest(activation_heights))
}
/// Returns true if the network is the default Testnet, or false otherwise.
pub fn is_default_testnet(&self) -> bool {
if let Self::Testnet(params) = self {
@ -181,6 +180,15 @@ impl Network {
}
}
/// Returns true if the network is Regtest, or false otherwise.
pub fn is_regtest(&self) -> bool {
if let Self::Testnet(params) = self {
params.is_regtest()
} else {
false
}
}
/// Returns the [`NetworkKind`] for this network.
pub fn kind(&self) -> NetworkKind {
match self {
@ -231,7 +239,7 @@ impl Network {
//
// See the `ZIP_212_GRACE_PERIOD_DURATION` documentation for more information.
let canopy_activation = Canopy
let canopy_activation = NetworkUpgrade::Canopy
.activation_height(self)
.expect("Canopy activation height must be present for both networks");
@ -279,3 +287,70 @@ impl FromStr for Network {
#[derive(Clone, Debug, Error)]
#[error("Invalid network: {0}")]
pub struct InvalidNetworkError(String);
impl zp_consensus::Parameters for Network {
fn activation_height(
&self,
nu: zcash_primitives::consensus::NetworkUpgrade,
) -> Option<zcash_primitives::consensus::BlockHeight> {
let target_nu = match nu {
zp_consensus::NetworkUpgrade::Overwinter => NetworkUpgrade::Overwinter,
zp_consensus::NetworkUpgrade::Sapling => NetworkUpgrade::Sapling,
zp_consensus::NetworkUpgrade::Blossom => NetworkUpgrade::Blossom,
zp_consensus::NetworkUpgrade::Heartwood => NetworkUpgrade::Heartwood,
zp_consensus::NetworkUpgrade::Canopy => NetworkUpgrade::Canopy,
zp_consensus::NetworkUpgrade::Nu5 => NetworkUpgrade::Nu5,
};
// Heights are hard-coded below Height::MAX or checked when the config is parsed.
target_nu
.activation_height(self)
.map(|Height(h)| zp_consensus::BlockHeight::from_u32(h))
}
fn coin_type(&self) -> u32 {
match self {
Network::Mainnet => zp_constants::mainnet::COIN_TYPE,
// The regtest cointype reuses the testnet cointype,
// See <https://github.com/satoshilabs/slips/blob/master/slip-0044.md>
Network::Testnet(_) => zp_constants::testnet::COIN_TYPE,
}
}
fn address_network(&self) -> Option<zcash_address::Network> {
match self {
Network::Mainnet => Some(zcash_address::Network::Main),
// TODO: Check if network is `Regtest` first, and if it is, return `zcash_address::Network::Regtest`
Network::Testnet(_params) => Some(zcash_address::Network::Test),
}
}
fn hrp_sapling_extended_spending_key(&self) -> &str {
match self {
Network::Mainnet => zp_constants::mainnet::HRP_SAPLING_EXTENDED_SPENDING_KEY,
Network::Testnet(params) => params.hrp_sapling_extended_spending_key(),
}
}
fn hrp_sapling_extended_full_viewing_key(&self) -> &str {
match self {
Network::Mainnet => zp_constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
Network::Testnet(params) => params.hrp_sapling_extended_full_viewing_key(),
}
}
fn hrp_sapling_payment_address(&self) -> &str {
match self {
Network::Mainnet => zp_constants::mainnet::HRP_SAPLING_PAYMENT_ADDRESS,
Network::Testnet(params) => params.hrp_sapling_payment_address(),
}
}
fn b58_pubkey_address_prefix(&self) -> [u8; 2] {
self.kind().b58_pubkey_address_prefix()
}
fn b58_script_address_prefix(&self) -> [u8; 2] {
self.kind().b58_script_address_prefix()
}
}

View File

@ -1,16 +1,334 @@
//! Types and implementation for Testnet consensus parameters
use std::{collections::BTreeMap, fmt};
#[cfg(any(test, feature = "proptest-impl"))]
use proptest_derive::Arbitrary;
use zcash_primitives::constants as zp_constants;
use crate::{
block::Height,
parameters::{
network_upgrade::TESTNET_ACTIVATION_HEIGHTS, Network, NetworkUpgrade,
NETWORK_UPGRADES_IN_ORDER,
},
};
/// Reserved network names that should not be allowed for configured Testnets.
pub const RESERVED_NETWORK_NAMES: [&str; 6] = [
"Mainnet",
"Testnet",
"Regtest",
"MainnetKind",
"TestnetKind",
"RegtestKind",
];
/// Maximum length for a configured network name.
pub const MAX_NETWORK_NAME_LENGTH: usize = 30;
/// Maximum length for a configured human-readable prefix.
pub const MAX_HRP_LENGTH: usize = 30;
/// Configurable activation heights for Regtest and configured Testnets.
#[derive(Deserialize, Default)]
#[serde(rename_all = "PascalCase")]
pub struct ConfiguredActivationHeights {
/// Activation height for `BeforeOverwinter` network upgrade.
pub before_overwinter: Option<u32>,
/// Activation height for `Overwinter` network upgrade.
pub overwinter: Option<u32>,
/// Activation height for `Sapling` network upgrade.
pub sapling: Option<u32>,
/// Activation height for `Blossom` network upgrade.
pub blossom: Option<u32>,
/// Activation height for `Heartwood` network upgrade.
pub heartwood: Option<u32>,
/// Activation height for `Canopy` network upgrade.
pub canopy: Option<u32>,
/// Activation height for `NU5` network upgrade.
#[serde(rename = "NU5")]
pub nu5: Option<u32>,
}
/// Builder for the [`Parameters`] struct.
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct ParametersBuilder {
/// The name of this network to be used by the `Display` trait impl.
network_name: String,
/// The network upgrade activation heights for this network, see [`Parameters::activation_heights`] for more details.
activation_heights: BTreeMap<Height, NetworkUpgrade>,
/// Sapling extended spending key human-readable prefix for this network
hrp_sapling_extended_spending_key: String,
/// Sapling extended full viewing key human-readable prefix for this network
hrp_sapling_extended_full_viewing_key: String,
/// Sapling payment address human-readable prefix for this network
hrp_sapling_payment_address: String,
}
impl Default for ParametersBuilder {
fn default() -> Self {
Self {
network_name: "UnknownTestnet".to_string(),
// # Correctness
//
// `Genesis` network upgrade activation height must always be 0
activation_heights: TESTNET_ACTIVATION_HEIGHTS.iter().cloned().collect(),
hrp_sapling_extended_spending_key:
zp_constants::testnet::HRP_SAPLING_EXTENDED_SPENDING_KEY.to_string(),
hrp_sapling_extended_full_viewing_key:
zp_constants::testnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY.to_string(),
hrp_sapling_payment_address: zp_constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS
.to_string(),
}
}
}
impl ParametersBuilder {
/// Sets the network name to be used in the [`Parameters`] being built.
pub fn with_network_name(mut self, network_name: impl fmt::Display) -> Self {
self.network_name = network_name.to_string();
assert!(
!RESERVED_NETWORK_NAMES.contains(&self.network_name.as_str()),
"cannot use reserved network name '{network_name}' as configured Testnet name, reserved names: {RESERVED_NETWORK_NAMES:?}"
);
assert!(
self.network_name.len() <= MAX_NETWORK_NAME_LENGTH,
"network name {network_name} is too long, must be {MAX_NETWORK_NAME_LENGTH} characters or less"
);
assert!(
self.network_name
.chars()
.all(|x| x.is_alphanumeric() || x == '_'),
"network name must include only alphanumeric characters or '_'"
);
self
}
/// Checks that the provided Sapling human-readable prefixes (HRPs) are valid and unique, then
/// sets the Sapling HRPs to be used in the [`Parameters`] being built.
pub fn with_sapling_hrps(
mut self,
hrp_sapling_extended_spending_key: impl fmt::Display,
hrp_sapling_extended_full_viewing_key: impl fmt::Display,
hrp_sapling_payment_address: impl fmt::Display,
) -> Self {
self.hrp_sapling_extended_spending_key = hrp_sapling_extended_spending_key.to_string();
self.hrp_sapling_extended_full_viewing_key =
hrp_sapling_extended_full_viewing_key.to_string();
self.hrp_sapling_payment_address = hrp_sapling_payment_address.to_string();
let sapling_hrps = [
&self.hrp_sapling_extended_spending_key,
&self.hrp_sapling_extended_full_viewing_key,
&self.hrp_sapling_payment_address,
];
for sapling_hrp in sapling_hrps {
assert!(sapling_hrp.len() <= MAX_HRP_LENGTH, "Sapling human-readable prefix {sapling_hrp} is too long, must be {MAX_HRP_LENGTH} characters or less");
assert!(
sapling_hrp.chars().all(|c| c.is_ascii_lowercase() || c == '-'),
"human-readable prefixes should contain only lowercase ASCII characters and dashes, hrp: {sapling_hrp}"
);
assert_eq!(
sapling_hrps
.iter()
.filter(|&&hrp| hrp == sapling_hrp)
.count(),
1,
"Sapling human-readable prefixes must be unique, repeated Sapling HRP: {sapling_hrp}"
);
}
self
}
/// Checks that the provided network upgrade activation heights are in the correct order, then
/// sets them as the new network upgrade activation heights.
pub fn with_activation_heights(
mut self,
ConfiguredActivationHeights {
// TODO: Find out if `BeforeOverwinter` is required at Height(1), allow for
// configuring its activation height if it's not required to be at Height(1)
before_overwinter: _,
overwinter,
sapling,
blossom,
heartwood,
canopy,
nu5,
}: ConfiguredActivationHeights,
) -> Self {
use NetworkUpgrade::*;
// # Correctness
//
// These must be in order so that later network upgrades overwrite prior ones
// if multiple network upgrades are configured with the same activation height.
let activation_heights: BTreeMap<_, _> = overwinter
.into_iter()
.map(|h| (h, Overwinter))
.chain(sapling.into_iter().map(|h| (h, Sapling)))
.chain(blossom.into_iter().map(|h| (h, Blossom)))
.chain(heartwood.into_iter().map(|h| (h, Heartwood)))
.chain(canopy.into_iter().map(|h| (h, Canopy)))
.chain(nu5.into_iter().map(|h| (h, Nu5)))
.map(|(h, nu)| (h.try_into().expect("activation height must be valid"), nu))
.collect();
let network_upgrades: Vec<_> = activation_heights.iter().map(|(_h, &nu)| nu).collect();
// Check that the provided network upgrade activation heights are in the same order by height as the default testnet activation heights
let mut activation_heights_iter = activation_heights.iter();
for expected_network_upgrade in NETWORK_UPGRADES_IN_ORDER {
if !network_upgrades.contains(&expected_network_upgrade) {
continue;
} else if let Some((&height, &network_upgrade)) = activation_heights_iter.next() {
assert_ne!(
height,
Height(0),
"Height(0) is reserved for the `Genesis` upgrade"
);
assert!(
network_upgrade == expected_network_upgrade,
"network upgrades must be activated in order, the correct order is {NETWORK_UPGRADES_IN_ORDER:?}"
);
}
}
// # Correctness
//
// Height(0) must be reserved for the `NetworkUpgrade::Genesis`.
// TODO: Find out if `BeforeOverwinter` must always be active at Height(1), remove it here if it's not required.
self.activation_heights.split_off(&Height(2));
self.activation_heights.extend(activation_heights);
self
}
/// Converts the builder to a [`Parameters`] struct
pub fn finish(self) -> Parameters {
let Self {
network_name,
activation_heights,
hrp_sapling_extended_spending_key,
hrp_sapling_extended_full_viewing_key,
hrp_sapling_payment_address,
} = self;
Parameters {
network_name,
activation_heights,
hrp_sapling_extended_spending_key,
hrp_sapling_extended_full_viewing_key,
hrp_sapling_payment_address,
}
}
/// Converts the builder to a configured [`Network::Testnet`]
pub fn to_network(self) -> Network {
Network::new_configured_testnet(self.finish())
}
}
/// Network consensus parameters for test networks such as Regtest and the default Testnet.
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
pub struct Parameters {}
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct Parameters {
/// The name of this network to be used by the `Display` trait impl.
network_name: String,
/// The network upgrade activation heights for this network.
///
/// Note: This value is ignored by `Network::activation_list()` when `zebra-chain` is
/// compiled with the `zebra-test` feature flag AND the `TEST_FAKE_ACTIVATION_HEIGHTS`
/// environment variable is set.
activation_heights: BTreeMap<Height, NetworkUpgrade>,
/// Sapling extended spending key human-readable prefix for this network
hrp_sapling_extended_spending_key: String,
/// Sapling extended full viewing key human-readable prefix for this network
hrp_sapling_extended_full_viewing_key: String,
/// Sapling payment address human-readable prefix for this network
hrp_sapling_payment_address: String,
}
impl Default for Parameters {
/// Returns an instance of the default public testnet [`Parameters`].
fn default() -> Self {
Self {
network_name: "Testnet".to_string(),
..Self::build().finish()
}
}
}
impl Parameters {
/// Creates a new [`ParametersBuilder`].
pub fn build() -> ParametersBuilder {
ParametersBuilder::default()
}
/// Accepts a [`ConfiguredActivationHeights`].
///
/// Creates an instance of [`Parameters`] with `Regtest` values.
pub fn new_regtest(activation_heights: ConfiguredActivationHeights) -> Self {
Self {
network_name: "Regtest".to_string(),
..Self::build()
.with_sapling_hrps(
zp_constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY,
zp_constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
zp_constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS,
)
// Removes default Testnet activation heights if not configured,
// most network upgrades are disabled by default for Regtest in zcashd
.with_activation_heights(activation_heights)
.finish()
}
}
/// Returns true if the instance of [`Parameters`] represents the default public Testnet.
pub fn is_default_testnet(&self) -> bool {
self == &Self::default()
}
/// Returns true if the instance of [`Parameters`] represents Regtest.
pub fn is_regtest(&self) -> bool {
let Self {
network_name,
hrp_sapling_extended_spending_key,
hrp_sapling_extended_full_viewing_key,
hrp_sapling_payment_address,
..
} = Self::new_regtest(ConfiguredActivationHeights::default());
self.network_name == network_name
&& self.hrp_sapling_extended_spending_key == hrp_sapling_extended_spending_key
&& self.hrp_sapling_extended_full_viewing_key == hrp_sapling_extended_full_viewing_key
&& self.hrp_sapling_payment_address == hrp_sapling_payment_address
}
/// Returns the network name
pub fn network_name(&self) -> &str {
&self.network_name
}
/// Returns the network upgrade activation heights
pub fn activation_heights(&self) -> &BTreeMap<Height, NetworkUpgrade> {
&self.activation_heights
}
/// Returns the `hrp_sapling_extended_spending_key` field
pub fn hrp_sapling_extended_spending_key(&self) -> &str {
&self.hrp_sapling_extended_spending_key
}
/// Returns the `hrp_sapling_extended_full_viewing_key` field
pub fn hrp_sapling_extended_full_viewing_key(&self) -> &str {
&self.hrp_sapling_extended_full_viewing_key
}
/// Returns the `hrp_sapling_payment_address` field
pub fn hrp_sapling_payment_address(&self) -> &str {
&self.hrp_sapling_payment_address
}
}

View File

@ -1 +1,2 @@
mod prop;
mod vectors;

View File

@ -0,0 +1,350 @@
//! Fixed test vectors for the network consensus parameters.
use zcash_primitives::{
consensus::{self as zp_consensus, Parameters},
constants as zp_constants,
};
use crate::{
block::Height,
parameters::{
testnet::{
self, ConfiguredActivationHeights, MAX_HRP_LENGTH, MAX_NETWORK_NAME_LENGTH,
RESERVED_NETWORK_NAMES,
},
Network, NetworkUpgrade, MAINNET_ACTIVATION_HEIGHTS, NETWORK_UPGRADES_IN_ORDER,
TESTNET_ACTIVATION_HEIGHTS,
},
};
/// Checks that every method in the `Parameters` impl for `zebra_chain::Network` has the same output
/// as the Parameters impl for `zcash_primitives::consensus::Network` on Mainnet and the default Testnet.
#[test]
fn check_parameters_impl() {
let zp_network_upgrades = [
zp_consensus::NetworkUpgrade::Overwinter,
zp_consensus::NetworkUpgrade::Sapling,
zp_consensus::NetworkUpgrade::Blossom,
zp_consensus::NetworkUpgrade::Heartwood,
zp_consensus::NetworkUpgrade::Canopy,
zp_consensus::NetworkUpgrade::Nu5,
];
for (network, zp_network) in [
(Network::Mainnet, zp_consensus::Network::MainNetwork),
(
Network::new_default_testnet(),
zp_consensus::Network::TestNetwork,
),
] {
for nu in zp_network_upgrades {
let activation_height = network
.activation_height(nu)
.expect("must have activation height for past network upgrades");
assert_eq!(
activation_height,
zp_network
.activation_height(nu)
.expect("must have activation height for past network upgrades"),
"Parameters::activation_heights() outputs must match"
);
let activation_height: u32 = activation_height.into();
for height in (activation_height - 1)..=(activation_height + 1) {
for nu in zp_network_upgrades {
let height = zp_consensus::BlockHeight::from_u32(height);
assert_eq!(
network.is_nu_active(nu, height),
zp_network.is_nu_active(nu, height),
"Parameters::is_nu_active() outputs must match",
);
}
}
}
assert_eq!(
network.coin_type(),
zp_network.coin_type(),
"Parameters::coin_type() outputs must match"
);
assert_eq!(
network.hrp_sapling_extended_spending_key(),
zp_network.hrp_sapling_extended_spending_key(),
"Parameters::hrp_sapling_extended_spending_key() outputs must match"
);
assert_eq!(
network.hrp_sapling_extended_full_viewing_key(),
zp_network.hrp_sapling_extended_full_viewing_key(),
"Parameters::hrp_sapling_extended_full_viewing_key() outputs must match"
);
assert_eq!(
network.hrp_sapling_payment_address(),
zp_network.hrp_sapling_payment_address(),
"Parameters::hrp_sapling_payment_address() outputs must match"
);
assert_eq!(
network.b58_pubkey_address_prefix(),
zp_network.b58_pubkey_address_prefix(),
"Parameters::b58_pubkey_address_prefix() outputs must match"
);
assert_eq!(
network.b58_script_address_prefix(),
zp_network.b58_script_address_prefix(),
"Parameters::b58_script_address_prefix() outputs must match"
);
}
}
/// Checks that `NetworkUpgrade::activation_height()` returns the activation height of the next
/// network upgrade if it doesn't find an activation height for a prior network upgrade, that the
/// `Genesis` upgrade is always at `Height(0)`, and that the default Mainnet/Testnet/Regtest activation
/// heights are what's expected.
#[test]
fn activates_network_upgrades_correctly() {
let expected_activation_height = 1;
let network = testnet::Parameters::build()
.with_activation_heights(ConfiguredActivationHeights {
nu5: Some(expected_activation_height),
..Default::default()
})
.to_network();
let genesis_activation_height = NetworkUpgrade::Genesis
.activation_height(&network)
.expect("must return an activation height");
assert_eq!(
genesis_activation_height,
Height(0),
"activation height for all networks after Genesis and BeforeOverwinter should match NU5 activation height"
);
for nu in NETWORK_UPGRADES_IN_ORDER.into_iter().skip(1) {
let activation_height = nu
.activation_height(&network)
.expect("must return an activation height");
assert_eq!(
activation_height, Height(expected_activation_height),
"activation height for all networks after Genesis and BeforeOverwinter \
should match NU5 activation height, network_upgrade: {nu}, activation_height: {activation_height:?}"
);
}
let expected_default_regtest_activation_heights = &[
(Height(0), NetworkUpgrade::Genesis),
(Height(1), NetworkUpgrade::BeforeOverwinter),
];
for (network, expected_activation_heights) in [
(Network::Mainnet, MAINNET_ACTIVATION_HEIGHTS),
(Network::new_default_testnet(), TESTNET_ACTIVATION_HEIGHTS),
(
Network::new_regtest(Default::default()),
expected_default_regtest_activation_heights,
),
] {
assert_eq!(
network.activation_list(),
expected_activation_heights.iter().cloned().collect(),
"network activation list should match expected activation heights"
);
}
}
/// Checks that configured testnet names are validated and used correctly.
#[test]
fn check_configured_network_name() {
// Sets a no-op panic hook to avoid long output.
std::panic::set_hook(Box::new(|_| {}));
// Checks that reserved network names cannot be used for configured testnets.
for reserved_network_name in RESERVED_NETWORK_NAMES {
std::panic::catch_unwind(|| {
testnet::Parameters::build().with_network_name(reserved_network_name)
})
.expect_err("should panic when attempting to set network name as a reserved name");
}
// Check that max length is enforced, and that network names may only contain alphanumeric characters and '_'.
for invalid_network_name in [
"a".repeat(MAX_NETWORK_NAME_LENGTH + 1),
"!!!!non-alphanumeric-name".to_string(),
] {
std::panic::catch_unwind(|| {
testnet::Parameters::build().with_network_name(invalid_network_name)
})
.expect_err("should panic when setting network name that's too long or contains non-alphanumeric characters (except '_')");
}
drop(std::panic::take_hook());
// Checks that network names are displayed correctly
assert_eq!(
Network::new_default_testnet().to_string(),
"Testnet",
"default testnet should be displayed as 'Testnet'"
);
assert_eq!(
Network::Mainnet.to_string(),
"Mainnet",
"Mainnet should be displayed as 'Mainnet'"
);
assert_eq!(
Network::new_regtest(Default::default()).to_string(),
"Regtest",
"Regtest should be displayed as 'Regtest'"
);
// Check that network name can contain alphanumeric characters and '_'.
let expected_name = "ConfiguredTestnet_1";
let network = testnet::Parameters::build()
// Check that network name can contain `MAX_NETWORK_NAME_LENGTH` characters
.with_network_name("a".repeat(MAX_NETWORK_NAME_LENGTH))
.with_network_name(expected_name)
.to_network();
// Check that configured network name is displayed
assert_eq!(
network.to_string(),
expected_name,
"network must be displayed as configured network name"
);
}
/// Checks that configured Sapling human-readable prefixes (HRPs) are validated and used correctly.
#[test]
fn check_configured_sapling_hrps() {
// Sets a no-op panic hook to avoid long output.
std::panic::set_hook(Box::new(|_| {}));
// Check that configured Sapling HRPs must be unique.
std::panic::catch_unwind(|| {
testnet::Parameters::build().with_sapling_hrps("", "", "");
})
.expect_err("should panic when setting non-unique Sapling HRPs");
// Check that max length is enforced, and that network names may only contain lowecase ASCII characters and dashes.
for invalid_hrp in [
"a".repeat(MAX_NETWORK_NAME_LENGTH + 1),
"!!!!non-alphabetical-name".to_string(),
"A".to_string(),
] {
std::panic::catch_unwind(|| {
testnet::Parameters::build().with_sapling_hrps(invalid_hrp, "dummy-hrp-a", "dummy-hrp-b");
})
.expect_err("should panic when setting Sapling HRPs that are too long or contain non-alphanumeric characters (except '-')");
}
drop(std::panic::take_hook());
// Check that Sapling HRPs can contain lowercase ascii characters and dashes.
let expected_hrp_sapling_extended_spending_key = "sapling-hrp-a";
let expected_hrp_sapling_extended_full_viewing_key = "sapling-hrp-b";
let expected_hrp_sapling_payment_address = "sapling-hrp-c";
let network = testnet::Parameters::build()
// Check that Sapling HRPs can contain `MAX_HRP_LENGTH` characters
.with_sapling_hrps("a".repeat(MAX_HRP_LENGTH), "dummy-hrp-a", "dummy-hrp-b")
.with_sapling_hrps(
expected_hrp_sapling_extended_spending_key,
expected_hrp_sapling_extended_full_viewing_key,
expected_hrp_sapling_payment_address,
)
.to_network();
// Check that configured Sapling HRPs are returned by `Parameters` trait methods
assert_eq!(
network.hrp_sapling_extended_spending_key(),
expected_hrp_sapling_extended_spending_key,
"should return expected Sapling extended spending key HRP"
);
assert_eq!(
network.hrp_sapling_extended_full_viewing_key(),
expected_hrp_sapling_extended_full_viewing_key,
"should return expected Sapling EFVK HRP"
);
assert_eq!(
network.hrp_sapling_payment_address(),
expected_hrp_sapling_payment_address,
"should return expected Sapling payment address HRP"
);
// Check that default Mainnet, Testnet, and Regtest HRPs are valid, these calls will panic
// if any of the values fail validation.
testnet::Parameters::build()
.with_sapling_hrps(
zp_constants::mainnet::HRP_SAPLING_EXTENDED_SPENDING_KEY,
zp_constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
zp_constants::mainnet::HRP_SAPLING_PAYMENT_ADDRESS,
)
.with_sapling_hrps(
zp_constants::testnet::HRP_SAPLING_EXTENDED_SPENDING_KEY,
zp_constants::testnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
zp_constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS,
)
.with_sapling_hrps(
zp_constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY,
zp_constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
zp_constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS,
);
}
/// Checks that configured testnet names are validated and used correctly.
#[test]
fn check_network_name() {
// Sets a no-op panic hook to avoid long output.
std::panic::set_hook(Box::new(|_| {}));
// Checks that reserved network names cannot be used for configured testnets.
for reserved_network_name in RESERVED_NETWORK_NAMES {
std::panic::catch_unwind(|| {
testnet::Parameters::build().with_network_name(reserved_network_name)
})
.expect_err("should panic when attempting to set network name as a reserved name");
}
// Check that max length is enforced, and that network names may only contain alphanumeric characters and '_'.
for invalid_network_name in [
"a".repeat(MAX_NETWORK_NAME_LENGTH + 1),
"!!!!non-alphanumeric-name".to_string(),
] {
std::panic::catch_unwind(|| {
testnet::Parameters::build().with_network_name(invalid_network_name)
})
.expect_err("should panic when setting network name that's too long or contains non-alphanumeric characters (except '_')");
}
drop(std::panic::take_hook());
// Checks that network names are displayed correctly
assert_eq!(
Network::new_default_testnet().to_string(),
"Testnet",
"default testnet should be displayed as 'Testnet'"
);
assert_eq!(
Network::Mainnet.to_string(),
"Mainnet",
"Mainnet should be displayed as 'Mainnet'"
);
// TODO: Check Regtest
// Check that network name can contain alphanumeric characters and '_'.
let expected_name = "ConfiguredTestnet_1";
let network = testnet::Parameters::build()
// Check that network name can contain `MAX_NETWORK_NAME_LENGTH` characters
.with_network_name("a".repeat(MAX_NETWORK_NAME_LENGTH))
.with_network_name(expected_name)
.to_network();
// Check that configured network name is displayed
assert_eq!(
network.to_string(),
expected_name,
"network must be displayed as configured network name"
);
}

View File

@ -7,7 +7,6 @@ use crate::parameters::{Network, Network::*};
use std::collections::{BTreeMap, HashMap};
use std::fmt;
use std::ops::Bound::*;
use chrono::{DateTime, Duration, Utc};
use hex::{FromHex, ToHex};
@ -15,6 +14,18 @@ use hex::{FromHex, ToHex};
#[cfg(any(test, feature = "proptest-impl"))]
use proptest_derive::Arbitrary;
/// A list of network upgrades in the order that they must be activated.
pub const NETWORK_UPGRADES_IN_ORDER: [NetworkUpgrade; 8] = [
Genesis,
BeforeOverwinter,
Overwinter,
Sapling,
Blossom,
Heartwood,
Canopy,
Nu5,
];
/// A Zcash network upgrade.
///
/// Network upgrades can change the Zcash network protocol or consensus rules in
@ -242,12 +253,7 @@ impl Network {
/// and it's a test build, this returns a list of fake activation heights
/// used by some tests.
pub fn activation_list(&self) -> BTreeMap<block::Height, NetworkUpgrade> {
let (mainnet_heights, testnet_heights) = {
#[cfg(not(feature = "zebra-test"))]
{
(MAINNET_ACTIVATION_HEIGHTS, TESTNET_ACTIVATION_HEIGHTS)
}
match self {
// To prevent accidentally setting this somehow, only check the env var
// when being compiled for tests. We can't use cfg(test) since the
// test that uses this is in zebra-state, and cfg(test) is not
@ -260,25 +266,19 @@ impl Network {
// feature should only be enabled for tests:
// https://doc.rust-lang.org/cargo/reference/features.html#resolver-version-2-command-line-flags
#[cfg(feature = "zebra-test")]
if std::env::var_os("TEST_FAKE_ACTIVATION_HEIGHTS").is_some() {
(
FAKE_MAINNET_ACTIVATION_HEIGHTS,
FAKE_TESTNET_ACTIVATION_HEIGHTS,
)
} else {
(MAINNET_ACTIVATION_HEIGHTS, TESTNET_ACTIVATION_HEIGHTS)
Mainnet if std::env::var_os("TEST_FAKE_ACTIVATION_HEIGHTS").is_some() => {
FAKE_MAINNET_ACTIVATION_HEIGHTS.iter().cloned().collect()
}
};
match self {
Mainnet => mainnet_heights,
// TODO: Add an `activation_heights` field to `testnet::Parameters` to return here. (#7970)
Testnet(_params) => testnet_heights,
#[cfg(feature = "zebra-test")]
Testnet(_) if std::env::var_os("TEST_FAKE_ACTIVATION_HEIGHTS").is_some() => {
FAKE_TESTNET_ACTIVATION_HEIGHTS.iter().cloned().collect()
}
Mainnet => MAINNET_ACTIVATION_HEIGHTS.iter().cloned().collect(),
Testnet(params) => params.activation_heights().clone(),
}
.iter()
.cloned()
.collect()
}
}
impl NetworkUpgrade {
/// Returns the current network upgrade for `network` and `height`.
pub fn current(network: &Network, height: block::Height) -> NetworkUpgrade {
@ -290,11 +290,28 @@ impl NetworkUpgrade {
.expect("every height has a current network upgrade")
}
/// Returns the next expected network upgrade after this network upgrade
pub fn next_upgrade(self) -> Option<Self> {
match self {
Genesis => Some(BeforeOverwinter),
BeforeOverwinter => Some(Overwinter),
Overwinter => Some(Sapling),
Sapling => Some(Blossom),
Blossom => Some(Heartwood),
Heartwood => Some(Canopy),
Canopy => Some(Nu5),
Nu5 => None,
}
}
/// Returns the next network upgrade for `network` and `height`.
///
/// Returns None if the next upgrade has not been implemented in Zebra
/// yet.
#[cfg(test)]
pub fn next(network: &Network, height: block::Height) -> Option<NetworkUpgrade> {
use std::ops::Bound::*;
network
.activation_list()
.range((Excluded(height), Unbounded))
@ -302,17 +319,27 @@ impl NetworkUpgrade {
.next()
}
/// Returns the activation height for this network upgrade on `network`.
/// Returns the activation height for this network upgrade on `network`, or
///
/// Returns the activation height of the first network upgrade that follows
/// this network upgrade if there is no activation height for this network upgrade
/// such as on Regtest or a configured Testnet where multiple network upgrades have the
/// same activation height, or if one is omitted when others that follow it are included.
///
/// Returns None if this network upgrade is a future upgrade, and its
/// activation height has not been set yet.
///
/// Returns None if this network upgrade has not been configured on a Testnet or Regtest.
pub fn activation_height(&self, network: &Network) -> Option<block::Height> {
network
.activation_list()
.iter()
.filter(|(_, nu)| nu == &self)
.find(|(_, nu)| nu == &self)
.map(|(height, _)| *height)
.next()
.or_else(|| {
self.next_upgrade()
.and_then(|next_nu| next_nu.activation_height(network))
})
}
/// Returns `true` if `height` is the activation height of any network upgrade

View File

@ -53,7 +53,7 @@ impl ZcashDeserialize for Bctv14Proof {
}
#[cfg(any(test, feature = "proptest-impl"))]
use proptest::{arbitrary::Arbitrary, collection::vec, prelude::*};
use proptest::{collection::vec, prelude::*};
#[cfg(any(test, feature = "proptest-impl"))]
impl Arbitrary for Bctv14Proof {

View File

@ -65,7 +65,7 @@ impl ZcashDeserialize for Groth16Proof {
}
#[cfg(any(test, feature = "proptest-impl"))]
use proptest::{arbitrary::Arbitrary, collection::vec, prelude::*};
use proptest::{collection::vec, prelude::*};
#[cfg(any(test, feature = "proptest-impl"))]
impl Arbitrary for Groth16Proof {

View File

@ -36,7 +36,7 @@ impl ZcashDeserialize for Halo2Proof {
}
}
#[cfg(any(test, feature = "proptest-impl"))]
use proptest::{arbitrary::Arbitrary, prelude::*};
use proptest::prelude::*;
#[cfg(any(test, feature = "proptest-impl"))]
impl Arbitrary for Halo2Proof {

View File

@ -6,7 +6,7 @@
mod tests;
use std::{collections::BTreeMap, convert::TryInto, io, sync::Arc};
use std::{collections::BTreeMap, io, sync::Arc};
use serde_big_array::BigArray;
pub use zcash_history::{V1, V2};

View File

@ -22,29 +22,11 @@ pub fn decrypts_successfully(transaction: &Transaction, network: &Network, heigh
let alt_height = height.0.into();
let null_sapling_ovk = zcash_primitives::keys::OutgoingViewingKey([0u8; 32]);
let network = match network {
Network::Mainnet => zcash_primitives::consensus::Network::MainNetwork,
Network::Testnet(params) => {
// # Correctness:
//
// There are differences between the `TestNetwork` parameters and those returned by
// `CRegTestParams()` in zcashd, so this function can't return `TestNetwork` unless
// Zebra is using the default public Testnet.
//
// TODO: Remove this conversion by implementing `zcash_primitives::consensus::Parameters`
// for `Network` (#8365).
assert!(
params.is_default_testnet(),
"could not convert configured testnet to zcash_primitives::consensus::Network"
);
zcash_primitives::consensus::Network::TestNetwork
}
};
if let Some(bundle) = alt_tx.sapling_bundle() {
for output in bundle.shielded_outputs().iter() {
let recovery = zcash_primitives::sapling::note_encryption::try_sapling_output_recovery(
&network,
network,
alt_height,
&null_sapling_ovk,
output,

View File

@ -5,7 +5,7 @@ use jubjub::{AffinePoint, ExtendedPoint};
use rand::SeedableRng;
use rand_chacha::ChaChaRng;
use proptest::{arbitrary::any, collection::vec, prelude::*};
use proptest::{collection::vec, prelude::*};
use crate::primitives::Groth16Proof;

View File

@ -1,9 +1,6 @@
//! Note and value commitments.
use std::{
convert::{TryFrom, TryInto},
fmt, io,
};
use std::{fmt, io};
use bitvec::prelude::*;
use jubjub::ExtendedPoint;

View File

@ -16,7 +16,7 @@ use rand_core::{CryptoRng, RngCore};
use crate::{
error::{AddressError, RandError},
primitives::redjubjub::{self, SpendAuth},
primitives::redjubjub::SpendAuth,
serialization::{
serde_helpers, ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize,
},

View File

@ -1,4 +1,4 @@
use proptest::{arbitrary::any, collection::vec, prelude::*};
use proptest::{collection::vec, prelude::*};
use super::*;

View File

@ -3,14 +3,11 @@
//! Zebra uses a generic spend type for `V4` and `V5` transactions.
//! The anchor change is handled using the `AnchorVariant` type trait.
use std::{convert::TryInto, fmt, io};
use std::{fmt, io};
use crate::{
block::MAX_BLOCK_BYTES,
primitives::{
redjubjub::{self, SpendAuth},
Groth16Proof,
},
primitives::{redjubjub::SpendAuth, Groth16Proof},
serialization::{
ReadZcashExt, SerializationError, TrustedPreallocate, WriteZcashExt, ZcashDeserialize,
ZcashDeserializeInto, ZcashSerialize,

View File

@ -8,7 +8,6 @@ use crate::{
serialization::{ZcashDeserializeInto, ZcashSerialize},
transaction::{LockTime, Transaction},
};
use std::convert::TryInto;
proptest! {
/// Serialize and deserialize `Spend<PerSpendAnchor>`

View File

@ -19,7 +19,7 @@ use std::{
};
use bitvec::prelude::*;
use bridgetree::{self, NonEmptyFrontier};
use bridgetree::NonEmptyFrontier;
use hex::ToHex;
use incrementalmerkletree::{frontier::Frontier, Hashable};

View File

@ -1,9 +1,7 @@
//! Arbitrary data generation for serialization proptests
use std::convert::TryInto;
use chrono::{DateTime, TimeZone, Utc};
use proptest::{arbitrary::any, prelude::*};
use proptest::prelude::*;
use super::{
CompactSizeMessage, DateTime32, TrustedPreallocate, ZcashSerialize, MAX_PROTOCOL_MESSAGE_LEN,

View File

@ -5,8 +5,6 @@
//! - [`CompactSizeMessage`] for sizes that must be less than the network message limit, and
//! - [`CompactSize64`] for flags, arbitrary counts, and sizes that span multiple blocks.
use std::convert::{TryFrom, TryInto};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use crate::serialization::{

View File

@ -1,9 +1,6 @@
//! Serialization constraint helpers.
use std::{
convert::{TryFrom, TryInto},
ops::Deref,
};
use std::ops::Deref;
use crate::serialization::SerializationError;

View File

@ -2,7 +2,7 @@
use proptest::{collection::size_range, prelude::*};
use std::{convert::TryInto, matches};
use std::matches;
use crate::serialization::{
arbitrary::max_allocation_is_big_enough, zcash_deserialize::MAX_U8_ALLOCATION,

View File

@ -1,4 +1,4 @@
use proptest::{arbitrary::any, array, prelude::*};
use proptest::{array, prelude::*};
use crate::{
amount::{Amount, NonNegative},

View File

@ -1,4 +1,4 @@
use proptest::{arbitrary::any, collection::vec, prelude::*};
use proptest::{collection::vec, prelude::*};
impl Arbitrary for super::EncryptedNote {
type Parameters = ();

View File

@ -30,7 +30,9 @@ impl Network {
}
}
/// Returns blocks indexed by height in a [`BTreeMap`].
///
/// Returns Mainnet blocks if `self` is set to Mainnet, and Testnet blocks otherwise.
pub fn block_map(&self) -> BTreeMap<u32, &'static [u8]> {
if self.is_mainnet() {
zebra_test::vectors::MAINNET_BLOCKS.clone()

View File

@ -1,17 +1,9 @@
//! Arbitrary data generation for transaction proptests
use std::{
cmp::max,
collections::HashMap,
convert::{TryFrom, TryInto},
ops::Neg,
sync::Arc,
};
use std::{cmp::max, collections::HashMap, ops::Neg, sync::Arc};
use chrono::{TimeZone, Utc};
use proptest::{
arbitrary::any, array, collection::vec, option, prelude::*, test_runner::TestRunner,
};
use proptest::{array, collection::vec, option, prelude::*, test_runner::TestRunner};
use reddsa::{orchard::Binding, Signature};
use crate::{

View File

@ -28,11 +28,7 @@
//!
//! [1]: crate::transaction::UnminedTx
use std::{
convert::{TryFrom, TryInto},
fmt,
sync::Arc,
};
use std::{fmt, sync::Arc};
#[cfg(any(test, feature = "proptest-impl"))]
use proptest_derive::Arbitrary;

View File

@ -1,4 +1,4 @@
use std::{cmp, convert::TryFrom, fmt};
use std::{cmp, fmt};
/// A 512-byte (plaintext) memo associated with a note, as described in
/// [protocol specification §5.5][ps].

View File

@ -1,10 +1,10 @@
//! Contains impls of `ZcashSerialize`, `ZcashDeserialize` for all of the
//! transaction types, so that all of the serialization logic is in one place.
use std::{borrow::Borrow, convert::TryInto, io, sync::Arc};
use std::{borrow::Borrow, io, sync::Arc};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use halo2::pasta::{group::ff::PrimeField, pallas};
use halo2::pasta::group::ff::PrimeField;
use hex::FromHex;
use reddsa::{orchard::Binding, orchard::SpendAuth, Signature};
@ -12,13 +12,12 @@ use crate::{
amount,
block::MAX_BLOCK_BYTES,
parameters::{OVERWINTER_VERSION_GROUP_ID, SAPLING_VERSION_GROUP_ID, TX_V5_VERSION_GROUP_ID},
primitives::{Groth16Proof, Halo2Proof, ZkSnarkProof},
primitives::{Halo2Proof, ZkSnarkProof},
serialization::{
zcash_deserialize_external_count, zcash_serialize_empty_list,
zcash_serialize_external_count, AtLeastOne, ReadZcashExt, SerializationError,
TrustedPreallocate, ZcashDeserialize, ZcashDeserializeInto, ZcashSerialize,
},
sprout,
};
use super::*;

View File

@ -1,15 +1,14 @@
//! Fixed test vectors for transactions.
use chrono::{DateTime, NaiveDateTime, Utc};
use chrono::DateTime;
use color_eyre::eyre::Result;
use lazy_static::lazy_static;
use crate::{
amount::Amount,
block::{Block, Height, MAX_BLOCK_BYTES},
parameters::{Network, NetworkUpgrade},
parameters::Network,
serialization::{SerializationError, ZcashDeserialize, ZcashDeserializeInto, ZcashSerialize},
transaction::{hash::WtxId, sighash::SigHasher, txid::TxIdBuilder, Transaction},
transaction::{sighash::SigHasher, txid::TxIdBuilder},
transparent::Script,
};
@ -221,13 +220,6 @@ fn deserialize_large_transaction() {
let output =
transparent::Output::zcash_deserialize(&zebra_test::vectors::DUMMY_OUTPUT1[..]).unwrap();
// Create a lock time.
let lock_time = LockTime::Time(DateTime::<Utc>::from_naive_utc_and_offset(
NaiveDateTime::from_timestamp_opt(61, 0)
.expect("in-range number of seconds and valid nanosecond"),
Utc,
));
// Serialize the input so that we can determine its serialized size.
let mut input_data = Vec::new();
input
@ -242,14 +234,12 @@ fn deserialize_large_transaction() {
.take(tx_inputs_num)
.collect::<Vec<_>>();
let outputs = vec![output];
// Create an oversized transaction. Adding the output and lock time causes
// the transaction to overflow the threshold.
let oversized_tx = Transaction::V1 {
inputs,
outputs,
lock_time,
outputs: vec![output],
lock_time: LockTime::Time(DateTime::from_timestamp(61, 0).unwrap()),
};
// Serialize the transaction.

View File

@ -1,6 +1,6 @@
//! Transaction ID computation. Contains code for generating the Transaction ID
//! from the transaction.
use std::{convert::TryInto, io};
use std::io;
use super::{Hash, Transaction};
use crate::serialization::{sha256d, ZcashSerialize};

View File

@ -2,10 +2,6 @@
use std::{fmt, io};
use ripemd::{Digest, Ripemd160};
use secp256k1::PublicKey;
use sha2::Sha256;
use crate::{
parameters::NetworkKind,
serialization::{SerializationError, ZcashDeserialize, ZcashSerialize},
@ -154,29 +150,6 @@ impl ZcashDeserialize for Address {
}
}
trait ToAddressWithNetwork {
/// Convert `self` to an `Address`, given the current `network`.
fn to_address(&self, network: NetworkKind) -> Address;
}
impl ToAddressWithNetwork for Script {
fn to_address(&self, network_kind: NetworkKind) -> Address {
Address::PayToScriptHash {
network_kind,
script_hash: Address::hash_payload(self.as_raw_bytes()),
}
}
}
impl ToAddressWithNetwork for PublicKey {
fn to_address(&self, network_kind: NetworkKind) -> Address {
Address::PayToPublicKeyHash {
network_kind,
pub_key_hash: Address::hash_payload(&self.serialize()[..]),
}
}
}
impl Address {
/// Create an address for the given public key hash and network.
pub fn from_pub_key_hash(network_kind: NetworkKind, pub_key_hash: [u8; 20]) -> Self {
@ -219,21 +192,6 @@ impl Address {
}
}
/// A hash of a transparent address payload, as used in
/// transparent pay-to-script-hash and pay-to-publickey-hash
/// addresses.
///
/// The resulting hash in both of these cases is always exactly 20
/// bytes.
/// <https://en.bitcoin.it/Base58Check_encoding#Encoding_a_Bitcoin_address>
fn hash_payload(bytes: &[u8]) -> [u8; 20] {
let sha_hash = Sha256::digest(bytes);
let ripe_hash = Ripemd160::digest(sha_hash);
let mut payload = [0u8; 20];
payload[..].copy_from_slice(&ripe_hash[..]);
payload
}
/// Given a transparent address (P2SH or a P2PKH), create a script that can be used in a coinbase
/// transaction output.
pub fn create_script_from_address(&self) -> Script {
@ -264,11 +222,53 @@ impl Address {
#[cfg(test)]
mod tests {
use ripemd::{Digest, Ripemd160};
use secp256k1::PublicKey;
use sha2::Sha256;
use super::*;
trait ToAddressWithNetwork {
/// Convert `self` to an `Address`, given the current `network`.
fn to_address(&self, network: NetworkKind) -> Address;
}
impl ToAddressWithNetwork for Script {
fn to_address(&self, network_kind: NetworkKind) -> Address {
Address::PayToScriptHash {
network_kind,
script_hash: Address::hash_payload(self.as_raw_bytes()),
}
}
}
impl ToAddressWithNetwork for PublicKey {
fn to_address(&self, network_kind: NetworkKind) -> Address {
Address::PayToPublicKeyHash {
network_kind,
pub_key_hash: Address::hash_payload(&self.serialize()[..]),
}
}
}
impl Address {
/// A hash of a transparent address payload, as used in
/// transparent pay-to-script-hash and pay-to-publickey-hash
/// addresses.
///
/// The resulting hash in both of these cases is always exactly 20
/// bytes.
/// <https://en.bitcoin.it/Base58Check_encoding#Encoding_a_Bitcoin_address>
#[allow(dead_code)]
fn hash_payload(bytes: &[u8]) -> [u8; 20] {
let sha_hash = Sha256::digest(bytes);
let ripe_hash = Ripemd160::digest(sha_hash);
let mut payload = [0u8; 20];
payload[..].copy_from_slice(&ripe_hash[..]);
payload
}
}
#[test]
fn pubkey_mainnet() {
let _init_guard = zebra_test::init();

View File

@ -1,4 +1,4 @@
use proptest::{arbitrary::any, collection::vec, prelude::*};
use proptest::{collection::vec, prelude::*};
use crate::{block, parameters::NetworkKind, LedgerState};

View File

@ -95,7 +95,6 @@ mod proptests {
use proptest::prelude::*;
use super::*;
use crate::serialization::{ZcashDeserialize, ZcashSerialize};
proptest! {
#[test]

View File

@ -1,6 +1,6 @@
//! Unspent transparent output data structures and functions.
use std::{collections::HashMap, convert::TryInto};
use std::collections::HashMap;
use crate::{
block::{self, Block, Height},

View File

@ -6,7 +6,7 @@ use crate::{
transparent,
};
use std::{borrow::Borrow, collections::HashMap, convert::TryInto};
use std::{borrow::Borrow, collections::HashMap};
#[cfg(any(test, feature = "proptest-impl"))]
use crate::{amount::MAX_MONEY, transaction::Transaction};

View File

@ -1,6 +1,6 @@
use super::*;
use proptest::{arbitrary::Arbitrary, collection::vec, prelude::*};
use proptest::{collection::vec, prelude::*};
impl Arbitrary for equihash::Solution {
type Parameters = ();

View File

@ -1,8 +1,6 @@
use super::*;
use crate::block;
use proptest::{arbitrary::Arbitrary, collection::vec, prelude::*};
use proptest::{collection::vec, prelude::*};
impl Arbitrary for CompactDifficulty {
type Parameters = ();

View File

@ -1,8 +1,4 @@
use proptest::{arbitrary::any, prelude::*};
use std::cmp::Ordering;
use crate::block;
use proptest::prelude::*;
use super::super::*;

View File

@ -2,7 +2,7 @@
use std::{env, sync::Arc};
use proptest::{arbitrary::any, prelude::*, test_runner::Config};
use proptest::{prelude::*, test_runner::Config};
use crate::{
block::{self, Block},

View File

@ -1,5 +1,3 @@
use std::convert::TryInto;
use crate::{
block::{Block, MAX_BLOCK_BYTES},
serialization::{CompactSizeMessage, ZcashDeserialize, ZcashDeserializeInto, ZcashSerialize},

View File

@ -43,16 +43,16 @@ jubjub = "0.10.0"
rand = "0.8.5"
rayon = "1.10.0"
chrono = { version = "0.4.34", default-features = false, features = ["clock", "std"] }
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] }
displaydoc = "0.2.4"
lazy_static = "1.4.0"
once_cell = "1.18.0"
serde = { version = "1.0.196", features = ["serde_derive"] }
serde = { version = "1.0.198", features = ["serde_derive"] }
futures = "0.3.30"
futures-util = "0.3.28"
metrics = "0.22.3"
thiserror = "1.0.58"
thiserror = "1.0.59"
tokio = { version = "1.37.0", features = ["time", "sync", "tracing", "rt-multi-thread"] }
tower = { version = "0.4.13", features = ["timeout", "util", "buffer"] }
tracing = "0.1.39"

View File

@ -2,7 +2,7 @@
//!
//! [7.8]: https://zips.z.cash/protocol/protocol.pdf#subsidies
use std::{collections::HashSet, convert::TryFrom};
use std::collections::HashSet;
use zebra_chain::{
amount::{Amount, Error, NonNegative},

View File

@ -1,22 +1,18 @@
//! Tests for block verification
use std::sync::Arc;
use chrono::Utc;
use color_eyre::eyre::{eyre, Report};
use once_cell::sync::Lazy;
use tower::{buffer::Buffer, util::BoxService};
use zebra_chain::{
amount::{Amount, MAX_MONEY},
amount::MAX_MONEY,
block::{
self,
tests::generate::{
large_multi_transaction_block, large_single_transaction_block_many_inputs,
},
Block, Height,
},
parameters::{Network, NetworkUpgrade},
parameters::NetworkUpgrade,
serialization::{ZcashDeserialize, ZcashDeserializeInto},
transaction::{arbitrary::transaction_to_fake_v5, LockTime, Transaction},
work::difficulty::{ParameterDifficulty as _, INVALID_COMPACT_DIFFICULTY},

View File

@ -5,8 +5,8 @@ use std::sync::Arc;
use num_integer::div_ceil;
use zebra_chain::{
block::{self, Block, HeightDiff, MAX_BLOCK_BYTES},
parameters::{Network, Network::*},
block::{Block, HeightDiff, MAX_BLOCK_BYTES},
parameters::Network::*,
serialization::ZcashDeserialize,
};
use zebra_node_services::constants::{MAX_CHECKPOINT_BYTE_COUNT, MAX_CHECKPOINT_HEIGHT_GAP};

View File

@ -1,14 +1,10 @@
//! Tests for checkpoint-based block verification
use std::{cmp::min, mem::drop, time::Duration};
use std::{cmp::min, time::Duration};
use color_eyre::eyre::{eyre, Report};
use futures::{
future::TryFutureExt,
stream::{FuturesUnordered, StreamExt},
};
use futures::stream::{FuturesUnordered, StreamExt};
use tokio::time::timeout;
use tower::{Service, ServiceExt};
use tracing_futures::Instrument;
use zebra_chain::{parameters::Network::*, serialization::ZcashDeserialize};

View File

@ -15,7 +15,7 @@ use tokio::sync::watch;
use tower::{util::ServiceFn, Service};
use tower_batch_control::{Batch, BatchControl};
use tower_fallback::Fallback;
use zebra_chain::primitives::ed25519::{batch, *};
use zebra_chain::primitives::ed25519::*;
use crate::BoxError;

View File

@ -5,7 +5,6 @@ use std::time::Duration;
use color_eyre::eyre::{eyre, Report, Result};
use futures::stream::{FuturesOrdered, StreamExt};
use tower::ServiceExt;
use tower_batch_control::Batch;
use crate::primitives::ed25519::*;

View File

@ -1,5 +1,3 @@
use std::convert::TryFrom;
use crate::groth16::h_sig;
#[test]

View File

@ -16,7 +16,7 @@ use tower::{util::ServiceFn, Service};
use tower_batch_control::{Batch, BatchControl};
use tower_fallback::Fallback;
use zebra_chain::primitives::redjubjub::{batch, *};
use zebra_chain::primitives::redjubjub::*;
use crate::BoxError;

View File

@ -7,7 +7,6 @@ use std::time::Duration;
use color_eyre::eyre::{eyre, Result};
use futures::stream::{FuturesUnordered, StreamExt};
use tower::ServiceExt;
use tower_batch_control::Batch;
async fn sign_and_verify<V>(mut verifier: V, n: usize) -> Result<(), V::Error>
where

View File

@ -7,7 +7,6 @@ use std::time::Duration;
use color_eyre::eyre::{eyre, Result};
use futures::stream::{FuturesUnordered, StreamExt};
use tower::ServiceExt;
use tower_batch_control::Batch;
use zebra_chain::primitives::reddsa::{
orchard::{Binding, SpendAuth},

View File

@ -4,18 +4,15 @@ use std::{sync::Arc, time::Duration};
use color_eyre::eyre::Report;
use once_cell::sync::Lazy;
use tower::{layer::Layer, timeout::TimeoutLayer, Service};
use tower::{layer::Layer, timeout::TimeoutLayer};
use zebra_chain::{
block::{self, Block},
parameters::Network,
block::Block,
serialization::{ZcashDeserialize, ZcashDeserializeInto},
};
use zebra_state as zs;
use zebra_test::transcript::{ExpectedTranscriptError, Transcript};
use crate::Config;
use super::*;
/// The timeout we apply to each verify future during testing.

View File

@ -3,7 +3,6 @@
use std::{
collections::HashMap,
future::Future,
iter::FromIterator,
pin::Pin,
sync::Arc,
task::{Context, Poll},

View File

@ -20,13 +20,13 @@ futures-util = "0.3.28"
tonic = "0.11.0"
tonic-reflection = "0.11.0"
prost = "0.12.4"
serde = { version = "1.0.196", features = ["serde_derive"] }
serde = { version = "1.0.198", features = ["serde_derive"] }
tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread"] }
tokio-stream = "0.1.15"
tower = { version = "0.4.13", features = ["util", "buffer"] }
color-eyre = "0.6.3"
zcash_primitives = { version = "0.13.0-rc.1" }
zcash_primitives = { version = "0.13.0" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.36", features = ["shielded-scan"] }
zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.36" }

View File

@ -43,7 +43,7 @@ proptest-impl = ["proptest", "proptest-derive", "zebra-chain/proptest-impl"]
bitflags = "2.5.0"
byteorder = "1.5.0"
bytes = "1.6.0"
chrono = { version = "0.4.34", default-features = false, features = ["clock", "std"] }
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] }
dirs = "5.0.1"
hex = "0.4.3"
humantime-serde = "1.1.1"
@ -56,9 +56,9 @@ pin-project = "1.1.5"
rand = "0.8.5"
rayon = "1.10.0"
regex = "1.10.4"
serde = { version = "1.0.196", features = ["serde_derive"] }
serde = { version = "1.0.198", features = ["serde_derive"] }
tempfile = "3.10.1"
thiserror = "1.0.58"
thiserror = "1.0.59"
futures = "0.3.30"
tokio = { version = "1.37.0", features = ["fs", "io-util", "net", "time", "tracing", "macros", "rt-multi-thread"] }

View File

@ -4,7 +4,6 @@
use std::{
cmp::Reverse,
collections::HashMap,
iter::Extend,
net::{IpAddr, SocketAddr},
sync::{Arc, Mutex},
time::Instant,

View File

@ -5,7 +5,6 @@ use std::{
ffi::OsString,
io::{self, ErrorKind},
net::{IpAddr, SocketAddr},
string::String,
time::Duration,
};
@ -15,7 +14,10 @@ use tempfile::NamedTempFile;
use tokio::{fs, io::AsyncWriteExt};
use tracing::Span;
use zebra_chain::parameters::{testnet, Network, NetworkKind};
use zebra_chain::parameters::{
testnet::{self, ConfiguredActivationHeights},
Network, NetworkKind,
};
use crate::{
constants::{
@ -625,12 +627,19 @@ impl<'de> Deserialize<'de> for Config {
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct DTestnetParameters {
network_name: Option<String>,
activation_heights: Option<ConfiguredActivationHeights>,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields, default)]
struct DConfig {
listen_addr: String,
network: NetworkKind,
testnet_parameters: Option<testnet::Parameters>,
testnet_parameters: Option<DTestnetParameters>,
regtest_activation_heights: ConfiguredActivationHeights,
initial_mainnet_peers: IndexSet<String>,
initial_testnet_peers: IndexSet<String>,
cache_dir: CacheDir,
@ -647,6 +656,7 @@ impl<'de> Deserialize<'de> for Config {
listen_addr: "0.0.0.0".to_string(),
network: Default::default(),
testnet_parameters: None,
regtest_activation_heights: ConfiguredActivationHeights::default(),
initial_mainnet_peers: config.initial_mainnet_peers,
initial_testnet_peers: config.initial_testnet_peers,
cache_dir: config.cache_dir,
@ -661,6 +671,7 @@ impl<'de> Deserialize<'de> for Config {
listen_addr,
network: network_kind,
testnet_parameters,
regtest_activation_heights,
initial_mainnet_peers,
initial_testnet_peers,
cache_dir,
@ -669,21 +680,55 @@ impl<'de> Deserialize<'de> for Config {
max_connections_per_ip,
} = DConfig::deserialize(deserializer)?;
let network = if let Some(network_params) = testnet_parameters {
// TODO: Panic here if the initial testnet peers are the default initial testnet peers.
assert_eq!(
network_kind,
NetworkKind::Testnet,
"set network to 'Testnet' to use configured testnet parameters"
);
/// Accepts an [`IndexSet`] of initial peers,
///
/// Returns true if any of them are the default Testnet or Mainnet initial peers.
fn contains_default_initial_peers(initial_peers: &IndexSet<String>) -> bool {
let Config {
initial_mainnet_peers: mut default_initial_peers,
initial_testnet_peers: default_initial_testnet_peers,
..
} = Config::default();
default_initial_peers.extend(default_initial_testnet_peers);
Network::new_configured_testnet(network_params)
} else {
// Convert to default `Network` for a `NetworkKind` if there are no testnet parameters.
match network_kind {
NetworkKind::Mainnet => Network::Mainnet,
NetworkKind::Testnet => Network::new_default_testnet(),
NetworkKind::Regtest => unimplemented!("Regtest is not yet implemented in Zebra"),
initial_peers
.intersection(&default_initial_peers)
.next()
.is_some()
}
let network = match (network_kind, testnet_parameters) {
(NetworkKind::Mainnet, _) => Network::Mainnet,
(NetworkKind::Testnet, None) => Network::new_default_testnet(),
(NetworkKind::Regtest, _) => Network::new_regtest(regtest_activation_heights),
(
NetworkKind::Testnet,
Some(DTestnetParameters {
network_name,
activation_heights,
}),
) => {
let mut params_builder = testnet::Parameters::build();
if let Some(network_name) = network_name {
params_builder = params_builder.with_network_name(network_name)
}
// Retain default Testnet activation heights unless there's an empty [testnet_parameters.activation_heights] section.
if let Some(activation_heights) = activation_heights {
// Return an error if the initial testnet peers includes any of the default initial Mainnet or Testnet
// peers while activation heights are configured.
// TODO: Check that the network magic is different from the default Mainnet/Testnet network magic too?
if contains_default_initial_peers(&initial_testnet_peers) {
return Err(de::Error::custom(
"cannot use default initial testnet peers with configured activation heights",
));
}
params_builder = params_builder.with_activation_heights(activation_heights)
}
params_builder.to_network()
}
};

View File

@ -1,7 +1,7 @@
//! An address-with-metadata type used in Bitcoin networking.
use std::{
cmp::{max, Ord, Ordering},
cmp::{max, Ordering},
time::Instant,
};

View File

@ -2,7 +2,7 @@
use std::net::IpAddr;
use proptest::{arbitrary::any, collection::vec, prelude::*};
use proptest::{collection::vec, prelude::*};
use zebra_chain::{parameters::Network::*, serialization::DateTime32};

View File

@ -9,11 +9,7 @@
use std::{borrow::Cow, collections::HashSet, fmt, pin::Pin, sync::Arc, time::Instant};
use futures::{
future::{self, Either},
prelude::*,
stream::Stream,
};
use futures::{future::Either, prelude::*};
use rand::{seq::SliceRandom, thread_rng, Rng};
use tokio::time::{sleep, Sleep};
use tower::{Service, ServiceExt};

View File

@ -1,7 +1,6 @@
//! Wrapper around handshake logic that also opens a TCP connection.
use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};

View File

@ -106,7 +106,7 @@ use std::{
use futures::{
channel::{mpsc, oneshot},
future::{Future, FutureExt, TryFutureExt},
future::{FutureExt, TryFutureExt},
prelude::*,
stream::FuturesUnordered,
task::noop_waker,

View File

@ -2,7 +2,7 @@
use std::net::SocketAddr;
use proptest::{arbitrary::any, arbitrary::Arbitrary, collection::vec, prelude::*};
use proptest::{collection::vec, prelude::*};
use zebra_chain::{block, transaction};

View File

@ -1,7 +1,5 @@
//! Randomised property tests for Zebra's Zcash network protocol types.
use std::convert::TryInto;
use bytes::BytesMut;
use proptest::{collection::vec, prelude::*};
use tokio_util::codec::{Decoder, Encoder};

View File

@ -1,6 +1,6 @@
//! Fixed test vectors for external protocol messages.
use std::{convert::TryInto, io::Write};
use std::io::Write;
use byteorder::{LittleEndian, WriteBytesExt};

View File

@ -46,8 +46,8 @@ color-eyre = { version = "0.6.3", optional = true }
jsonrpc-core = { version = "18.0.0", optional = true }
# Security: avoid default dependency on openssl
reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"], optional = true }
serde = { version = "1.0.196", optional = true }
serde_json = { version = "1.0.115", optional = true }
serde = { version = "1.0.198", optional = true }
serde_json = { version = "1.0.116", optional = true }
tokio = { version = "1.37.0", features = ["time"], optional = true }
[dev-dependencies]
@ -55,5 +55,5 @@ tokio = { version = "1.37.0", features = ["time"], optional = true }
color-eyre = "0.6.3"
jsonrpc-core = "18.0.0"
reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"] }
serde = "1.0.196"
serde_json = "1.0.115"
serde = "1.0.198"
serde_json = "1.0.116"

View File

@ -42,7 +42,7 @@ proptest-impl = [
]
[dependencies]
chrono = { version = "0.4.34", default-features = false, features = ["clock", "std"] }
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] }
futures = "0.3.30"
# lightwalletd sends JSON-RPC requests over HTTP 1.1
@ -53,7 +53,7 @@ jsonrpc-derive = "18.0.0"
jsonrpc-http-server = "18.0.0"
# zebra-rpc needs the preserve_order feature in serde_json, which is a dependency of jsonrpc-core
serde_json = { version = "1.0.115", features = ["preserve_order"] }
serde_json = { version = "1.0.116", features = ["preserve_order"] }
indexmap = { version = "2.2.6", features = ["serde"] }
tokio = { version = "1.37.0", features = ["time", "rt-multi-thread", "macros", "tracing"] }
@ -62,7 +62,7 @@ tower = "0.4.13"
tracing = "0.1.39"
hex = { version = "0.4.3", features = ["serde"] }
serde = { version = "1.0.196", features = ["serde_derive"] }
serde = { version = "1.0.198", features = ["serde_derive"] }
# Experimental feature getblocktemplate-rpcs
rand = { version = "0.8.5", optional = true }
@ -84,7 +84,7 @@ insta = { version = "1.38.0", features = ["redactions", "json", "ron"] }
proptest = "1.4.0"
thiserror = "1.0.58"
thiserror = "1.0.59"
tokio = { version = "1.37.0", features = ["full", "tracing", "test-util"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.36", features = ["proptest-impl"] }

View File

@ -6,7 +6,7 @@
//! Some parts of the `zcashd` RPC documentation are outdated.
//! So this implementation follows the `zcashd` server and `lightwalletd` client implementations.
use std::{collections::HashSet, default::Default, fmt::Debug, sync::Arc};
use std::{collections::HashSet, fmt::Debug, sync::Arc};
use chrono::Utc;
use futures::{stream::FuturesOrdered, FutureExt, StreamExt, TryFutureExt};
@ -1098,6 +1098,11 @@ where
data: None,
})?;
// # Concurrency
//
// For consistency, this lookup must be performed first, then all the other
// lookups must be based on the hash.
// Fetch the block referenced by [`hash_or_height`] from the state.
// TODO: If this RPC is called a lot, just get the block header,
// rather than the whole block.
@ -1128,6 +1133,9 @@ where
_ => unreachable!("unmatched response to a block request"),
};
let hash = hash_or_height.hash().unwrap_or_else(|| block.hash());
let hash_or_height = hash.into();
// Fetch the Sapling & Orchard treestates referenced by
// [`hash_or_height`] from the state.
@ -1156,8 +1164,6 @@ where
// We've got all the data we need for the RPC response, so we
// assemble the response.
let hash = block.hash();
let height = block
.coinbase_height()
.expect("verified blocks have a valid height");

View File

@ -7,14 +7,14 @@ use jsonrpc_core::{self, BoxFuture, Error, ErrorCode, Result};
use jsonrpc_derive::rpc;
use tower::{Service, ServiceExt};
use zcash_address::{self, unified::Encoding, TryFromAddress};
use zcash_address::{unified::Encoding, TryFromAddress};
use zebra_chain::{
amount::Amount,
block::{self, Block, Height, TryIntoHeight},
chain_sync_status::ChainSyncStatus,
chain_tip::ChainTip,
parameters::{Network, POW_AVERAGING_WINDOW},
parameters::{Network, NetworkKind, POW_AVERAGING_WINDOW},
primitives,
serialization::ZcashDeserializeInto,
transparent::{
@ -449,13 +449,25 @@ where
) -> Self {
// Prevent loss of miner funds due to an unsupported or incorrect address type.
if let Some(miner_address) = mining_config.miner_address.clone() {
assert_eq!(
miner_address.network_kind(),
network.kind(),
"incorrect miner address config: {miner_address} \
network.network {network} and miner address network {} must match",
miner_address.network_kind(),
);
match network.kind() {
NetworkKind::Mainnet => assert_eq!(
miner_address.network_kind(),
NetworkKind::Mainnet,
"Incorrect config: Zebra is configured to run on a Mainnet network, \
which implies the configured mining address needs to be for Mainnet, \
but the provided address is for {}.",
miner_address.network_kind(),
),
// `Regtest` uses `Testnet` transparent addresses.
network_kind @ (NetworkKind::Testnet | NetworkKind::Regtest) => assert_eq!(
miner_address.network_kind(),
NetworkKind::Testnet,
"Incorrect config: Zebra is configured to run on a {network_kind} network, \
which implies the configured mining address needs to be for Testnet, \
but the provided address is for {}.",
miner_address.network_kind(),
),
}
}
// A limit on the configured extra coinbase data, regardless of the current block height.

View File

@ -227,9 +227,8 @@ fn update_checksum(checksum: &mut u32, item: [u8; 32]) {
}
}
impl ToString for LongPollId {
/// Exact conversion from LongPollId to a string.
fn to_string(&self) -> String {
impl std::fmt::Display for LongPollId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let LongPollId {
tip_height,
tip_hash_checksum,
@ -240,7 +239,8 @@ impl ToString for LongPollId {
// We can't do this using `serde`, because it names each field,
// but we want a single string containing all the fields.
format!(
write!(
f,
// Height as decimal, padded with zeroes to the width of Height::MAX
// Checksums as hex, padded with zeroes to the width of u32::MAX
// Timestamp as decimal, padded with zeroes to the width of u32::MAX

View File

@ -5,7 +5,7 @@
//! cargo insta test --review -p zebra-rpc --lib -- test_rpc_response_data
//! ```
use std::{collections::BTreeMap, sync::Arc};
use std::collections::BTreeMap;
use insta::dynamic_redaction;
use tower::buffer::Buffer;

View File

@ -1,8 +1,7 @@
//! Fixed test vectors for RPC methods.
use std::{ops::RangeInclusive, sync::Arc};
use std::ops::RangeInclusive;
use jsonrpc_core::ErrorCode;
use tower::buffer::Buffer;
use zebra_chain::{
@ -11,8 +10,7 @@ use zebra_chain::{
chain_tip::{mock::MockChainTip, NoChainTip},
parameters::Network::*,
serialization::{ZcashDeserializeInto, ZcashSerialize},
transaction::{UnminedTx, UnminedTxId},
transparent,
transaction::UnminedTxId,
};
use zebra_node_services::BoxError;

View File

@ -13,7 +13,7 @@ use jsonrpc_core::{Compatibility, MetaIoHandler};
use jsonrpc_http_server::{CloseHandle, ServerBuilder};
use tokio::task::JoinHandle;
use tower::Service;
use tracing::{Instrument, *};
use tracing::*;
use zebra_chain::{
block, chain_sync_status::ChainSyncStatus, chain_tip::ChainTip, parameters::Network,

View File

@ -23,13 +23,14 @@ use super::super::*;
/// Test that the JSON-RPC server spawns when configured with a single thread.
#[test]
#[cfg(not(target_os = "windows"))]
fn rpc_server_spawn_single_thread() {
rpc_server_spawn(false)
}
/// Test that the JSON-RPC server spawns when configured with multiple threads.
#[test]
fn rpc_sever_spawn_parallel_threads() {
fn rpc_server_spawn_parallel_threads() {
rpc_server_spawn(true)
}

View File

@ -45,21 +45,21 @@ color-eyre = "0.6.3"
indexmap = { version = "2.2.6", features = ["serde"] }
itertools = "0.12.1"
semver = "1.0.22"
serde = { version = "1.0.196", features = ["serde_derive"] }
serde = { version = "1.0.198", features = ["serde_derive"] }
tokio = { version = "1.37.0", features = ["time"] }
tower = "0.4.13"
tracing = "0.1.39"
futures = "0.3.30"
zcash_client_backend = "0.10.0-rc.1"
zcash_primitives = "0.13.0-rc.1"
zcash_primitives = "0.13.0"
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.36", features = ["shielded-scan"] }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.36", features = ["shielded-scan"] }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.36", features = ["shielded-scan"] }
zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.3" }
chrono = { version = "0.4.34", default-features = false, features = ["clock", "std", "serde"] }
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std", "serde"] }
# test feature proptest-impl
proptest = { version = "1.4.0", optional = true }

View File

@ -384,25 +384,6 @@ pub fn scan_block<K: ScanningKey>(
// TODO: Implement a check that returns early when the block height is below the Sapling
// activation height.
let network = match network {
Network::Mainnet => zcash_primitives::consensus::Network::MainNetwork,
Network::Testnet(params) => {
// # Correctness:
//
// There are differences between the `TestNetwork` parameters and those returned by
// `CRegTestParams()` in zcashd, so this function can't return `TestNetwork` unless
// Zebra is using the default public Testnet.
//
// TODO: Remove this conversion by implementing `zcash_primitives::consensus::Parameters`
// for `Network` (#8365).
assert!(
params.is_default_testnet(),
"could not convert configured testnet to zcash_primitives::consensus::Network"
);
zcash_primitives::consensus::Network::TestNetwork
}
};
let chain_metadata = ChainMetadata {
sapling_commitment_tree_size: sapling_tree_size,
// Orchard is not supported at the moment so the tree size can be 0.
@ -417,7 +398,7 @@ pub fn scan_block<K: ScanningKey>(
.collect();
zcash_client_backend::scanning::scan_block(
&network,
network,
block_to_compact(block, chain_metadata),
scanning_keys.as_slice(),
// Ignore whether notes are change from a viewer's own spends for now.

View File

@ -15,11 +15,11 @@ keywords = ["zebra", "zcash"]
categories = ["api-bindings", "cryptography::cryptocurrencies"]
[dependencies]
zcash_script = "0.1.14"
zcash_script = "0.1.15"
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.36" }
thiserror = "1.0.58"
thiserror = "1.0.59"
displaydoc = "0.2.4"
[dev-dependencies]

View File

@ -277,7 +277,6 @@ impl Drop for CachedFfiTransaction {
#[cfg(test)]
mod tests {
use hex::FromHex;
use std::convert::TryInto;
use std::sync::Arc;
use zebra_chain::{
parameters::{ConsensusBranchId, NetworkUpgrade::*},

View File

@ -47,7 +47,7 @@ elasticsearch = [
[dependencies]
bincode = "1.3.3"
chrono = { version = "0.4.34", default-features = false, features = ["clock", "std"] }
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] }
dirs = "5.0.1"
futures = "0.3.30"
hex = "0.4.3"
@ -63,9 +63,9 @@ regex = "1.10.4"
rlimit = "0.10.1"
rocksdb = { version = "0.22.0", default-features = false, features = ["lz4"] }
semver = "1.0.22"
serde = { version = "1.0.196", features = ["serde_derive"] }
serde = { version = "1.0.198", features = ["serde_derive"] }
tempfile = "3.10.1"
thiserror = "1.0.58"
thiserror = "1.0.59"
rayon = "1.10.0"
tokio = { version = "1.37.0", features = ["rt-multi-thread", "sync", "tracing"] }
@ -75,7 +75,7 @@ tracing = "0.1.39"
# elasticsearch specific dependencies.
# Security: avoid default dependency on openssl
elasticsearch = { version = "8.5.0-alpha.1", default-features = false, features = ["rustls-tls"], optional = true }
serde_json = { version = "1.0.115", package = "serde_json", optional = true }
serde_json = { version = "1.0.116", package = "serde_json", optional = true }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.36", features = ["async-error"] }

View File

@ -5,7 +5,7 @@
//! * the Testnet minimum difficulty adjustment from ZIPs 205 and 208, and
//! * `median-time-past`.
use std::{cmp::max, cmp::min, convert::TryInto};
use std::{cmp::max, cmp::min};
use chrono::{DateTime, Duration, Utc};

View File

@ -1,6 +1,6 @@
//! Randomised property tests for nullifier contextual validation
use std::{convert::TryInto, env, sync::Arc};
use std::{env, sync::Arc};
use itertools::Itertools;
use proptest::prelude::*;

View File

@ -1,7 +1,5 @@
//! Fixed test vectors for state contextual validation checks.
use std::sync::Arc;
use zebra_chain::serialization::ZcashDeserializeInto;
use super::super::*;

View File

@ -502,6 +502,12 @@ impl FinalizedState {
let network = self.network();
rt.block_on(async move {
// Send a ping to the server to check if it is available before inserting.
if client.ping().send().await.is_err() {
tracing::error!("Elasticsearch is not available, skipping block indexing");
return;
}
let response = client
.bulk(elasticsearch::BulkParts::Index(
format!("zcash_{}", network.to_string().to_lowercase()).as_str(),

Some files were not shown because too many files have changed in this diff Show More