Skip to content

Commit

Permalink
Add Regtest variant of Network and Parameter
Browse files Browse the repository at this point in the history
closes #1051

Also:
Adds encoding tests + cargo fmt
Adds tests on ZIP-321
Adds coverage on new code
  • Loading branch information
pacu committed Nov 30, 2023
1 parent 79e499e commit 3b0af31
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 5 deletions.
33 changes: 30 additions & 3 deletions zcash_client_backend/src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ mod tests {

let encoded_main = "zxviews1qqqqqqqqqqqqqq8n3zjjmvhhr854uy3qhpda3ml34haf0x388z5r7h4st4kpsf6qy3zw4wc246aw9rlfyg5ndlwvne7mwdq0qe6vxl42pqmcf8pvmmd5slmjxduqa9evgej6wa3th2505xq4nggrxdm93rxk4rpdjt5nmq2vn44e2uhm7h0hsagfvkk4n7n6nfer6u57v9cac84t7nl2zth0xpyfeg0w2p2wv2yn6jn923aaz0vdaml07l60ahapk6efchyxwysrvjsxmansf";
let encoded_test = "zxviewtestsapling1qqqqqqqqqqqqqq8n3zjjmvhhr854uy3qhpda3ml34haf0x388z5r7h4st4kpsf6qy3zw4wc246aw9rlfyg5ndlwvne7mwdq0qe6vxl42pqmcf8pvmmd5slmjxduqa9evgej6wa3th2505xq4nggrxdm93rxk4rpdjt5nmq2vn44e2uhm7h0hsagfvkk4n7n6nfer6u57v9cac84t7nl2zth0xpyfeg0w2p2wv2yn6jn923aaz0vdaml07l60ahapk6efchyxwysrvjs8evfkz";

let encoded_regtest = "zxviewregtestsapling1qqqqqqqqqqqqqq8n3zjjmvhhr854uy3qhpda3ml34haf0x388z5r7h4st4kpsf6qy3zw4wc246aw9rlfyg5ndlwvne7mwdq0qe6vxl42pqmcf8pvmmd5slmjxduqa9evgej6wa3th2505xq4nggrxdm93rxk4rpdjt5nmq2vn44e2uhm7h0hsagfvkk4n7n6nfer6u57v9cac84t7nl2zth0xpyfeg0w2p2wv2yn6jn923aaz0vdaml07l60ahapk6efchyxwysrvjskjkzax";
assert_eq!(
encode_extended_full_viewing_key(
constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
Expand All @@ -533,10 +533,19 @@ mod tests {
),
encoded_test
);

assert_eq!(
encode_extended_full_viewing_key(
constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
&extfvk
),
encoded_regtest
);

assert_eq!(
decode_extended_full_viewing_key(
constants::testnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
encoded_test
constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
encoded_regtest
)
.unwrap(),
extfvk
Expand All @@ -557,11 +566,14 @@ mod tests {
"zs1qqqqqqqqqqqqqqqqqqcguyvaw2vjk4sdyeg0lc970u659lvhqq7t0np6hlup5lusxle75c8v35z";
let encoded_test =
"ztestsapling1qqqqqqqqqqqqqqqqqqcguyvaw2vjk4sdyeg0lc970u659lvhqq7t0np6hlup5lusxle75ss7jnk";
let encoded_regtest =
"zregtestsapling1qqqqqqqqqqqqqqqqqqcguyvaw2vjk4sdyeg0lc970u659lvhqq7t0np6hlup5lusxle7505hlz3";

assert_eq!(
encode_payment_address(constants::mainnet::HRP_SAPLING_PAYMENT_ADDRESS, &addr),
encoded_main
);

assert_eq!(
decode_payment_address(
constants::mainnet::HRP_SAPLING_PAYMENT_ADDRESS,
Expand All @@ -575,6 +587,12 @@ mod tests {
encode_payment_address(constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS, &addr),
encoded_test
);

assert_eq!(
encode_payment_address(constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS, &addr),
encoded_regtest
);

assert_eq!(
decode_payment_address(
constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS,
Expand All @@ -583,6 +601,15 @@ mod tests {
.unwrap(),
addr
);

assert_eq!(
decode_payment_address(
constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS,
encoded_regtest
)
.unwrap(),
addr
);
}

#[test]
Expand Down
20 changes: 19 additions & 1 deletion zcash_client_backend/src/zip321.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@ pub mod testing {
mod tests {
use std::str::FromStr;
use zcash_primitives::{
consensus::{Parameters, TEST_NETWORK},
consensus::{BlockHeight, Network::RegtestNetwork, Parameters, TEST_NETWORK},
memo::Memo,
transaction::components::{amount::NonNegativeAmount, Amount},
};
Expand Down Expand Up @@ -1010,6 +1010,24 @@ mod tests {
);
}

#[test]
fn test_zip321_spec_regtest_valid_examples() {
let params = RegtestNetwork {
overwinter: Some(BlockHeight::from_u32(1)),
sapling: Some(BlockHeight::from_u32(1)),
blossom: Some(BlockHeight::from_u32(1)),
heartwood: Some(BlockHeight::from_u32(1)),
canopy: Some(BlockHeight::from_u32(1)),
nu5: Some(BlockHeight::from_u32(1)),
};
let valid_1 = "zcash:zregtestsapling1qqqqqqqqqqqqqqqqqqcguyvaw2vjk4sdyeg0lc970u659lvhqq7t0np6hlup5lusxle7505hlz3?amount=1&memo=VGhpcyBpcyBhIHNpbXBsZSBtZW1vLg&message=Thank%20you%20for%20your%20purchase";
let v1r = TransactionRequest::from_uri(&params, valid_1).unwrap();
assert_eq!(
v1r.payments.get(0).map(|p| p.amount),
Some(NonNegativeAmount::const_from_u64(100000000))
);
}

#[test]
fn test_zip321_spec_invalid_examples() {
// invalid; missing `address=`
Expand Down
172 changes: 171 additions & 1 deletion zcash_primitives/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,14 @@ impl Parameters for TestNetwork {
pub enum Network {
MainNetwork,
TestNetwork,
RegtestNetwork {
overwinter: Option<BlockHeight>,
sapling: Option<BlockHeight>,
blossom: Option<BlockHeight>,
heartwood: Option<BlockHeight>,
canopy: Option<BlockHeight>,
nu5: Option<BlockHeight>,
},
}

memuse::impl_no_dynamic_usage!(Network);
Expand All @@ -310,57 +318,87 @@ impl Parameters for Network {
match self {
Network::MainNetwork => MAIN_NETWORK.activation_height(nu),
Network::TestNetwork => TEST_NETWORK.activation_height(nu),
Network::RegtestNetwork {
overwinter,
sapling,
blossom,
heartwood,
canopy,
nu5,
} => match nu {
NetworkUpgrade::Overwinter => *overwinter,
NetworkUpgrade::Sapling => *sapling,
NetworkUpgrade::Blossom => *blossom,
NetworkUpgrade::Heartwood => *heartwood,
NetworkUpgrade::Canopy => *canopy,
NetworkUpgrade::Nu5 => *nu5,
#[cfg(feature = "zfuture")]
NetworkUpgrade::ZFuture => None,
},
}
}

fn coin_type(&self) -> u32 {
match self {
Network::MainNetwork => MAIN_NETWORK.coin_type(),
Network::TestNetwork => TEST_NETWORK.coin_type(),
Network::RegtestNetwork { .. } => constants::regtest::COIN_TYPE,
}
}

fn address_network(&self) -> Option<zcash_address::Network> {
match self {
Network::MainNetwork => Some(zcash_address::Network::Main),
Network::TestNetwork => Some(zcash_address::Network::Test),
Network::RegtestNetwork { .. } => Some(zcash_address::Network::Regtest),
}
}

fn hrp_sapling_extended_spending_key(&self) -> &str {
match self {
Network::MainNetwork => MAIN_NETWORK.hrp_sapling_extended_spending_key(),
Network::TestNetwork => TEST_NETWORK.hrp_sapling_extended_spending_key(),
Network::RegtestNetwork { .. } => constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY,
}
}

fn hrp_sapling_extended_full_viewing_key(&self) -> &str {
match self {
Network::MainNetwork => MAIN_NETWORK.hrp_sapling_extended_full_viewing_key(),
Network::TestNetwork => TEST_NETWORK.hrp_sapling_extended_full_viewing_key(),
Network::RegtestNetwork { .. } => {
constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY
}
}
}

fn hrp_sapling_payment_address(&self) -> &str {
match self {
Network::MainNetwork => MAIN_NETWORK.hrp_sapling_payment_address(),
Network::TestNetwork => TEST_NETWORK.hrp_sapling_payment_address(),
Network::RegtestNetwork { .. } => constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS,
}
}

fn b58_pubkey_address_prefix(&self) -> [u8; 2] {
match self {
Network::MainNetwork => MAIN_NETWORK.b58_pubkey_address_prefix(),
Network::TestNetwork => TEST_NETWORK.b58_pubkey_address_prefix(),
Network::RegtestNetwork { .. } => constants::regtest::B58_PUBKEY_ADDRESS_PREFIX,
}
}

fn b58_script_address_prefix(&self) -> [u8; 2] {
match self {
Network::MainNetwork => MAIN_NETWORK.b58_script_address_prefix(),
Network::TestNetwork => TEST_NETWORK.b58_script_address_prefix(),
Network::RegtestNetwork { .. } => constants::regtest::B58_SCRIPT_ADDRESS_PREFIX,

Check warning on line 395 in zcash_primitives/src/consensus.rs

View check run for this annotation

Codecov / codecov/patch

zcash_primitives/src/consensus.rs#L395

Added line #L395 was not covered by tests
}
}

fn is_nu_active(&self, nu: NetworkUpgrade, height: BlockHeight) -> bool {
self.activation_height(nu).map_or(false, |h| h <= height)
}
}

/// An event that occurs at a specified height on the Zcash chain, at which point the
Expand Down Expand Up @@ -664,8 +702,11 @@ pub mod testing {
mod tests {
use std::convert::TryFrom;

use crate::constants;

use super::{
BlockHeight, BranchId, NetworkUpgrade, Parameters, MAIN_NETWORK, UPGRADES_IN_ORDER,
BlockHeight, BranchId, Network::RegtestNetwork, NetworkUpgrade, Parameters, MAIN_NETWORK,
UPGRADES_IN_ORDER,
};

#[test]
Expand Down Expand Up @@ -732,4 +773,133 @@ mod tests {
BranchId::Nu5,
);
}

#[test]
fn regtest_nu_activation() {
let expected_overwinter = BlockHeight::from_u32(1);
let expected_sapling = BlockHeight::from_u32(2);
let expected_blossom = BlockHeight::from_u32(3);
let expected_heartwood = BlockHeight::from_u32(4);
let expected_canopy = BlockHeight::from_u32(5);
let expected_nu5 = BlockHeight::from_u32(6);

let regtest = RegtestNetwork {
overwinter: Some(expected_overwinter),
sapling: Some(expected_sapling),
blossom: Some(expected_blossom),
heartwood: Some(expected_heartwood),
canopy: Some(expected_canopy),
nu5: Some(expected_nu5),
};

assert!(regtest.is_nu_active(NetworkUpgrade::Overwinter, expected_overwinter));
assert!(regtest.is_nu_active(NetworkUpgrade::Sapling, expected_sapling));
assert!(regtest.is_nu_active(NetworkUpgrade::Blossom, expected_blossom));
assert!(regtest.is_nu_active(NetworkUpgrade::Heartwood, expected_heartwood));
assert!(regtest.is_nu_active(NetworkUpgrade::Canopy, expected_canopy));
assert!(regtest.is_nu_active(NetworkUpgrade::Nu5, expected_nu5));
#[cfg(feature = "zfuture")]
assert!(!regtest.is_nu_active(NetworkUpgrade::ZFuture, expected_nu5));

assert_eq!(regtest.coin_type(), constants::regtest::COIN_TYPE);
assert_eq!(
regtest.hrp_sapling_extended_spending_key(),
constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY
);
assert_eq!(
regtest.hrp_sapling_extended_full_viewing_key(),
constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY
);
assert_eq!(
regtest.hrp_sapling_payment_address(),
constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS
);
assert_eq!(
regtest.b58_pubkey_address_prefix(),
constants::regtest::B58_PUBKEY_ADDRESS_PREFIX
);
}

#[test]
fn regtest_activation_heights() {
let expected_overwinter = BlockHeight::from_u32(1);
let expected_sapling = BlockHeight::from_u32(2);
let expected_blossom = BlockHeight::from_u32(3);
let expected_heartwood = BlockHeight::from_u32(4);
let expected_canopy = BlockHeight::from_u32(5);
let expected_nu5 = BlockHeight::from_u32(6);

let regtest = RegtestNetwork {
overwinter: Some(expected_overwinter),
sapling: Some(expected_sapling),
blossom: Some(expected_blossom),
heartwood: Some(expected_heartwood),
canopy: Some(expected_canopy),
nu5: Some(expected_nu5),
};

assert_eq!(
regtest.activation_height(NetworkUpgrade::Overwinter),
Some(expected_overwinter)
);
assert_eq!(
regtest.activation_height(NetworkUpgrade::Sapling),
Some(expected_sapling)
);
assert_eq!(
regtest.activation_height(NetworkUpgrade::Blossom),
Some(expected_blossom)
);
assert_eq!(
regtest.activation_height(NetworkUpgrade::Heartwood),
Some(expected_heartwood)
);
assert_eq!(
regtest.activation_height(NetworkUpgrade::Canopy),
Some(expected_canopy)
);
assert_eq!(
regtest.activation_height(NetworkUpgrade::Nu5),
Some(expected_nu5)
);
#[cfg(feature = "zfuture")]
assert_eq!(regtest.activation_height(NetworkUpgrade::ZFuture), None);
}

#[test]
fn regtests_constants() {
let expected_overwinter = BlockHeight::from_u32(1);
let expected_sapling = BlockHeight::from_u32(2);
let expected_blossom = BlockHeight::from_u32(3);
let expected_heartwood = BlockHeight::from_u32(4);
let expected_canopy = BlockHeight::from_u32(5);
let expected_nu5 = BlockHeight::from_u32(6);

let regtest = RegtestNetwork {
overwinter: Some(expected_overwinter),
sapling: Some(expected_sapling),
blossom: Some(expected_blossom),
heartwood: Some(expected_heartwood),
canopy: Some(expected_canopy),
nu5: Some(expected_nu5),
};

assert_eq!(regtest.coin_type(), constants::regtest::COIN_TYPE);
assert_eq!(
regtest.hrp_sapling_extended_spending_key(),
constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY
);
assert_eq!(
regtest.hrp_sapling_extended_full_viewing_key(),
constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY
);
assert_eq!(
regtest.hrp_sapling_payment_address(),
constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS
);
assert_eq!(
regtest.b58_pubkey_address_prefix(),
constants::regtest::B58_PUBKEY_ADDRESS_PREFIX
);
}
}

0 comments on commit 3b0af31

Please sign in to comment.