Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factor out protocol constants and value types into a zcash_protocol crate. #1142

Merged
merged 18 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
66c6bba
Add stub for a `zcash_protocol` crate.
nuttycom Jan 27, 2024
bacfe3c
Move `zcash_primitives::{consensus, constants}` to the `zcash_protoco…
nuttycom Jan 27, 2024
5e4d9ab
Move `Amount` and `NonNegativeAmount` types to the `zcash_protocol` c…
nuttycom Jan 27, 2024
7188482
zcash_protocol: Rename value amounts to `Zatoshis` and `ZatBalance`
nuttycom Jan 27, 2024
eb3c7b4
zcash_protocol: Modify `Zatoshis` to directly wrap a u64
nuttycom Jan 27, 2024
85d1ca2
zcash_primitives: Move the `local-consensus` module to the `zcash_pro…
nuttycom Jan 29, 2024
a35ccfc
Fix broken intra-doc links after `zcash_protocol` crate extraction.
nuttycom Feb 2, 2024
6445410
zcash_client_backend: Move the `ShieldedProtocol` and `PoolType` type…
nuttycom Feb 2, 2024
4b18426
zcash_address: Use `zcash_protocol::consensus::NetworkType`
nuttycom Feb 3, 2024
a823ed7
Expose address generation errors when constructing default addresses
nuttycom Feb 6, 2024
04fdac7
zcash_primitives: Move the `memo` module to the `zcash_protocol` crate.
nuttycom Feb 7, 2024
b8aa513
Apply suggestions from code review
nuttycom Mar 5, 2024
51d4464
Remove `network_type` calls that are obviated by the blanket impl.
nuttycom Mar 5, 2024
5675a76
zcash_protocol: Use `BalanceError` instead of `()` for monetary range…
nuttycom Mar 5, 2024
8955cfc
Add missing CHANGELOG entries.
nuttycom Mar 5, 2024
eaabc0f
Apply suggestions from code review
nuttycom Mar 6, 2024
6b4942f
Add failing test for incorrect zip321 amount parsing.
nuttycom Mar 6, 2024
376db46
Fix incorrect zip321 amount parsing.
nuttycom Mar 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"components/f4jumble",
"components/zcash_address",
"components/zcash_encoding",
"components/zcash_protocol",
"zcash_client_backend",
"zcash_client_sqlite",
"zcash_extensions",
Expand Down Expand Up @@ -32,6 +33,8 @@ zcash_address = { version = "0.3", path = "components/zcash_address" }
zcash_client_backend = { version = "0.11", path = "zcash_client_backend" }
zcash_encoding = { version = "0.2", path = "components/zcash_encoding" }
zcash_keys = { version = "0.1", path = "zcash_keys" }
zcash_protocol = { version = "0.0", path = "components/zcash_protocol" }

zcash_note_encryption = "0.4"
zcash_primitives = { version = "0.14", path = "zcash_primitives", default-features = false }
zcash_proofs = { version = "0.14", path = "zcash_proofs", default-features = false }
Expand Down
3 changes: 2 additions & 1 deletion components/zcash_address/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ rustdoc-args = ["--cfg", "docsrs"]
bech32 = "0.9"
bs58 = { version = "0.5", features = ["check"] }
f4jumble = { version = "0.1", path = "../f4jumble" }
zcash_encoding = { version = "0.2", path = "../zcash_encoding" }
zcash_protocol.workspace = true
zcash_encoding.workspace = true

[dev-dependencies]
assert_matches = "1.3.0"
Expand Down
85 changes: 37 additions & 48 deletions components/zcash_address/src/encoding.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::{convert::TryInto, error::Error, fmt, str::FromStr};

use bech32::{self, FromBase32, ToBase32, Variant};
use zcash_protocol::consensus::{NetworkConstants, NetworkType};
use zcash_protocol::constants::{mainnet, regtest, testnet};

use crate::kind::unified::Encoding;
use crate::{kind::*, AddressKind, Network, ZcashAddress};
use crate::{kind::*, AddressKind, ZcashAddress};

/// An error while attempting to parse a string as a Zcash address.
#[derive(Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -68,9 +70,9 @@
let data = Vec::<u8>::from_base32(&data).map_err(|_| ParseError::InvalidEncoding)?;

let net = match hrp.as_str() {
sapling::MAINNET => Network::Main,
sapling::TESTNET => Network::Test,
sapling::REGTEST => Network::Regtest,
mainnet::HRP_SAPLING_PAYMENT_ADDRESS => NetworkType::Main,
testnet::HRP_SAPLING_PAYMENT_ADDRESS => NetworkType::Test,
regtest::HRP_SAPLING_PAYMENT_ADDRESS => NetworkType::Regtest,
// We will not define new Bech32 address encodings.
_ => {
return Err(ParseError::NotZcash);
Expand All @@ -86,23 +88,33 @@

// The rest use Base58Check.
if let Ok(decoded) = bs58::decode(s).with_check(None).into_vec() {
let net = match decoded[..2].try_into().unwrap() {
sprout::MAINNET | p2pkh::MAINNET | p2sh::MAINNET => Network::Main,
sprout::TESTNET | p2pkh::TESTNET | p2sh::TESTNET => Network::Test,
// We will not define new Base58Check address encodings.
_ => return Err(ParseError::NotZcash),
};
if decoded.len() >= 2 {
let (prefix, net) = match decoded[..2].try_into().unwrap() {
prefix @ (mainnet::B58_PUBKEY_ADDRESS_PREFIX
| mainnet::B58_SCRIPT_ADDRESS_PREFIX
| mainnet::B58_SPROUT_ADDRESS_PREFIX) => (prefix, NetworkType::Main),
prefix @ (testnet::B58_PUBKEY_ADDRESS_PREFIX
| testnet::B58_SCRIPT_ADDRESS_PREFIX
| testnet::B58_SPROUT_ADDRESS_PREFIX) => (prefix, NetworkType::Test),
// We will not define new Base58Check address encodings.
_ => return Err(ParseError::NotZcash),

Check warning on line 100 in components/zcash_address/src/encoding.rs

View check run for this annotation

Codecov / codecov/patch

components/zcash_address/src/encoding.rs#L100

Added line #L100 was not covered by tests
};

return match decoded[..2].try_into().unwrap() {
sprout::MAINNET | sprout::TESTNET => {
decoded[2..].try_into().map(AddressKind::Sprout)
return match prefix {
mainnet::B58_SPROUT_ADDRESS_PREFIX | testnet::B58_SPROUT_ADDRESS_PREFIX => {
decoded[2..].try_into().map(AddressKind::Sprout)
}
mainnet::B58_PUBKEY_ADDRESS_PREFIX | testnet::B58_PUBKEY_ADDRESS_PREFIX => {
decoded[2..].try_into().map(AddressKind::P2pkh)
}
mainnet::B58_SCRIPT_ADDRESS_PREFIX | testnet::B58_SCRIPT_ADDRESS_PREFIX => {
decoded[2..].try_into().map(AddressKind::P2sh)
}
_ => unreachable!(),

Check warning on line 113 in components/zcash_address/src/encoding.rs

View check run for this annotation

Codecov / codecov/patch

components/zcash_address/src/encoding.rs#L113

Added line #L113 was not covered by tests
}
p2pkh::MAINNET | p2pkh::TESTNET => decoded[2..].try_into().map(AddressKind::P2pkh),
p2sh::MAINNET | p2sh::TESTNET => decoded[2..].try_into().map(AddressKind::P2sh),
_ => unreachable!(),
.map_err(|_| ParseError::InvalidEncoding)
.map(|kind| ZcashAddress { kind, net });
}
.map_err(|_| ParseError::InvalidEncoding)
.map(|kind| ZcashAddress { kind, net });
};

// If it's not valid Bech32, Bech32m, or Base58Check, it's not a Zcash address.
Expand All @@ -124,36 +136,13 @@
impl fmt::Display for ZcashAddress {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let encoded = match &self.kind {
AddressKind::Sprout(data) => encode_b58(
match self.net {
Network::Main => sprout::MAINNET,
Network::Test | Network::Regtest => sprout::TESTNET,
},
data,
),
AddressKind::Sapling(data) => encode_bech32(
match self.net {
Network::Main => sapling::MAINNET,
Network::Test => sapling::TESTNET,
Network::Regtest => sapling::REGTEST,
},
data,
),
AddressKind::Sprout(data) => encode_b58(self.net.b58_sprout_address_prefix(), data),
AddressKind::Sapling(data) => {
encode_bech32(self.net.hrp_sapling_payment_address(), data)
}
AddressKind::Unified(addr) => addr.encode(&self.net),
AddressKind::P2pkh(data) => encode_b58(
match self.net {
Network::Main => p2pkh::MAINNET,
Network::Test | Network::Regtest => p2pkh::TESTNET,
},
data,
),
AddressKind::P2sh(data) => encode_b58(
match self.net {
Network::Main => p2sh::MAINNET,
Network::Test | Network::Regtest => p2sh::TESTNET,
},
data,
),
AddressKind::P2pkh(data) => encode_b58(self.net.b58_pubkey_address_prefix(), data),
AddressKind::P2sh(data) => encode_b58(self.net.b58_script_address_prefix(), data),
};
write!(f, "{}", encoded)
}
Expand All @@ -162,7 +151,7 @@
#[cfg(test)]
mod tests {
use super::*;
use crate::kind::unified;
use crate::{kind::unified, Network};

fn encoding(encoded: &str, decoded: ZcashAddress) {
assert_eq!(decoded.to_string(), encoded);
Expand Down
6 changes: 0 additions & 6 deletions components/zcash_address/src/kind.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1 @@
pub mod unified;

pub(crate) mod sapling;
pub(crate) mod sprout;

pub(crate) mod p2pkh;
pub(crate) mod p2sh;
5 changes: 0 additions & 5 deletions components/zcash_address/src/kind/p2pkh.rs

This file was deleted.

5 changes: 0 additions & 5 deletions components/zcash_address/src/kind/p2sh.rs

This file was deleted.

20 changes: 0 additions & 20 deletions components/zcash_address/src/kind/sapling.rs

This file was deleted.

13 changes: 0 additions & 13 deletions components/zcash_address/src/kind/sprout.rs

This file was deleted.

15 changes: 1 addition & 14 deletions components/zcash_address/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ pub use convert::{
};
pub use encoding::ParseError;
pub use kind::unified;
pub use zcash_protocol::consensus::NetworkType as Network;

/// A Zcash address.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
Expand All @@ -149,20 +150,6 @@ pub struct ZcashAddress {
kind: AddressKind,
}

/// The Zcash network for which an address is encoded.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Network {
/// Zcash Mainnet.
Main,
/// Zcash Testnet.
Test,
/// Private integration / regression testing, used in `zcashd`.
///
/// For some address types there is no distinction between test and regtest encodings;
/// those will always be parsed as `Network::Test`.
Regtest,
}

/// Known kinds of Zcash addresses.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
enum AddressKind {
Expand Down
55 changes: 55 additions & 0 deletions components/zcash_protocol/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Changelog
All notable changes to this library will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this library adheres to Rust's notion of
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
The entries below are relative to the `zcash_primitives` crate as of the tag
`zcash_primitives-0.14.0`.

### Added
- The following modules have been extracted from `zcash_primitives` and
moved to this crate:
- `consensus`
- `constants`
- `zcash_protocol::value` replaces `zcash_primitives::transaction::components::amount`
- `zcash_protocol::consensus`:
- `NetworkConstants` has been extracted from the `Parameters` trait. Relative to the
state prior to the extraction, the bech32 prefixes now return `&'static str` instead
of `&str`.
- `NetworkType`
- `Parameters::b58_sprout_address_prefix`
- `zcash_protocol::consensus`:
- `impl Hash for LocalNetwork`
- `zcash_protocol::constants::{mainnet, testnet}::B58_SPROUT_ADDRESS_PREFIX`
- Added in `zcash_protocol::value`:
- `Zatoshis`
- `ZatBalance`
- `MAX_BALANCE` has been added to replace previous instances where
`zcash_protocol::value::MAX_MONEY` was used as a signed value.

### Changed
- `zcash_protocol::value::COIN` has been changed from an `i64` to a `u64`
- `zcash_protocol::value::MAX_MONEY` has been changed from an `i64` to a `u64`
- `zcash_protocol::consensus::Parameters` has been split into two traits, with
the newly added `NetworkConstants` trait providing all network constant
accessors. Also, the `address_network` method has been replaced with a new
`network_type` method that serves the same purpose. A blanket impl of
`NetworkConstants` is provided for all types that implement `Parameters`,
so call sites for methods that have moved to `NetworkConstants` should
remain unchanged (though they may require an additional `use` statement.)

### Removed
- From `zcash_protocol::value`:
- `NonNegativeAmount` (use `Zatoshis` instead.)
- `Amount` (use `ZatBalance` instead.)
- The following conversions have been removed relative to `zcash_primitives-0.14.0`,
as `zcash_protocol` does not depend on the `orchard` or `sapling-crypto` crates.
- `From<NonNegativeAmount> for orchard::NoteValue>`
- `TryFrom<orchard::ValueSum> for Amount`
- `From<NonNegativeAmount> for sapling::value::NoteValue>`
- `TryFrom<sapling::value::NoteValue> for NonNegativeAmount`
- `impl AddAssign for NonNegativeAmount`
- `impl SubAssign for NonNegativeAmount`
Loading
Loading