Skip to content

Commit

Permalink
begin refactor suggested as "step 2": ZcashFoundation#7968 (comment)
Browse files Browse the repository at this point in the history
Squashed from multiple commits to enable partial rebase
  • Loading branch information
AloeareV committed Feb 29, 2024
1 parent 56fca2c commit cf70754
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 67 deletions.
94 changes: 94 additions & 0 deletions zebra-chain/src/parameters/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,100 @@ pub enum Network {
Testnet,
}

/// A magic number identifying the network.
#[derive(Copy, Clone, Eq, PartialEq)]
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
pub struct Magic(pub [u8; 4]);

impl fmt::Debug for Magic {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Magic").field(&hex::encode(self.0)).finish()
}
}

/// Magic numbers used to identify different Zcash networks.
pub mod magics {
use super::*;
/// The production mainnet.
pub const MAINNET: Magic = Magic([0x24, 0xe9, 0x27, 0x64]);
/// The testnet.
pub const TESTNET: Magic = Magic([0xfa, 0x1a, 0xf9, 0xbf]);
}
pub trait AllParameters: zcash_primitives::consensus::Parameters {
fn height_for_first_halving(&self) -> Height;
fn genesis_hash(&self) -> crate::block::Hash;
fn magic_value(&self) -> Magic;
}
impl AllParameters for Network {
fn height_for_first_halving(&self) -> Height {
match self {
Network::Mainnet => Canopy
.activation_height(*self)
.expect("canopy activation height should be available"),
Network::Testnet => constants::FIRST_HALVING_TESTNET,
}
}

fn genesis_hash(&self) -> crate::block::Hash {
match self {
// zcash-cli getblockhash 0
Network::Mainnet => "00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08",
// zcash-cli -testnet getblockhash 0
Network::Testnet => "05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38",
}
.parse()
.expect("hard-coded hash parses")
}

fn magic_value(&self) -> Magic {
match self {
Network::Mainnet => magics::MAINNET,
Network::Testnet => magics::TESTNET,
}
}
}
impl zcash_primitives::consensus::Parameters for Network {
fn activation_height(
&self,
nu: zcash_primitives::consensus::NetworkUpgrade,
) -> Option<zcash_primitives::consensus::BlockHeight> {
todo!()
}

fn coin_type(&self) -> u32 {
match self {
Network::Mainnet => zcash_primitives::constants::mainnet::COIN_TYPE,
Network::Testnet => zcash_primitives::constants::testnet::COIN_TYPE,
}
}

fn address_network(&self) -> Option<zcash_address::Network> {
todo!()
}

fn hrp_sapling_extended_spending_key(&self) -> &str {
todo!()
}

fn hrp_sapling_extended_full_viewing_key(&self) -> &str {
todo!()
}

fn hrp_sapling_payment_address(&self) -> &str {
todo!()
}

fn b58_pubkey_address_prefix(&self) -> [u8; 2] {
match self {
Network::Mainnet => zcash_primitives::constants::mainnet::B58_PUBKEY_ADDRESS_PREFIX,
Network::Testnet => zcash_primitives::constants::testnet::B58_PUBKEY_ADDRESS_PREFIX,
}
}

fn b58_script_address_prefix(&self) -> [u8; 2] {
todo!()
}
}
impl From<Network> for &'static str {
fn from(network: Network) -> &'static str {
match network {
Expand Down
24 changes: 6 additions & 18 deletions zebra-chain/src/primitives/zcash_note_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,12 @@ pub fn decrypts_successfully(transaction: &Transaction, network: Network, height

if let Some(bundle) = alt_tx.sapling_bundle() {
for output in bundle.shielded_outputs().iter() {
let recovery = match network {
Network::Mainnet => {
zcash_primitives::sapling::note_encryption::try_sapling_output_recovery(
&zcash_primitives::consensus::MAIN_NETWORK,
alt_height,
&null_sapling_ovk,
output,
)
}
Network::Testnet => {
zcash_primitives::sapling::note_encryption::try_sapling_output_recovery(
&zcash_primitives::consensus::TEST_NETWORK,
alt_height,
&null_sapling_ovk,
output,
)
}
};
let recovery = zcash_primitives::sapling::note_encryption::try_sapling_output_recovery(
&network,
alt_height,
&null_sapling_ovk,
output,
);
if recovery.is_none() {
return false;
}
Expand Down
55 changes: 27 additions & 28 deletions zebra-chain/src/transparent/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::{fmt, io};
use ripemd::{Digest, Ripemd160};
use secp256k1::PublicKey;
use sha2::Sha256;
use zcash_primitives::consensus::Parameters as _;

use crate::{
parameters::Network,
Expand Down Expand Up @@ -118,24 +119,14 @@ impl ZcashSerialize for Address {
network,
script_hash,
} => {
// Dev network doesn't have a recommendation so we
// default to testnet bytes if it's not mainnet.
match *network {
Network::Mainnet => writer.write_all(&magics::p2sh::MAINNET[..])?,
_ => writer.write_all(&magics::p2sh::TESTNET[..])?,
}
writer.write_all(&network.b58_script_address_prefix())?;
writer.write_all(script_hash)?
}
Address::PayToPublicKeyHash {
network,
pub_key_hash,
} => {
// Dev network doesn't have a recommendation so we
// default to testnet bytes if it's not mainnet.
match *network {
Network::Mainnet => writer.write_all(&magics::p2pkh::MAINNET[..])?,
_ => writer.write_all(&magics::p2pkh::TESTNET[..])?,
}
writer.write_all(&network.b58_pubkey_address_prefix())?;
writer.write_all(pub_key_hash)?
}
}
Expand All @@ -153,22 +144,30 @@ impl ZcashDeserialize for Address {
reader.read_exact(&mut hash_bytes)?;

match version_bytes {
magics::p2sh::MAINNET => Ok(Address::PayToScriptHash {
network: Network::Mainnet,
script_hash: hash_bytes,
}),
magics::p2sh::TESTNET => Ok(Address::PayToScriptHash {
network: Network::Testnet,
script_hash: hash_bytes,
}),
magics::p2pkh::MAINNET => Ok(Address::PayToPublicKeyHash {
network: Network::Mainnet,
pub_key_hash: hash_bytes,
}),
magics::p2pkh::TESTNET => Ok(Address::PayToPublicKeyHash {
network: Network::Testnet,
pub_key_hash: hash_bytes,
}),
zcash_primitives::constants::mainnet::B58_SCRIPT_ADDRESS_PREFIX => {
Ok(Address::PayToScriptHash {
network: Network::Mainnet,
script_hash: hash_bytes,
})
}
zcash_primitives::constants::testnet::B58_SCRIPT_ADDRESS_PREFIX => {
Ok(Address::PayToScriptHash {
network: Network::Testnet,
script_hash: hash_bytes,
})
}
zcash_primitives::constants::mainnet::B58_PUBKEY_ADDRESS_PREFIX => {
Ok(Address::PayToPublicKeyHash {
network: Network::Mainnet,
pub_key_hash: hash_bytes,
})
}
zcash_primitives::constants::testnet::B58_PUBKEY_ADDRESS_PREFIX => {
Ok(Address::PayToPublicKeyHash {
network: Network::Testnet,
pub_key_hash: hash_bytes,
})
}
_ => Err(SerializationError::Parse("bad t-addr version/type")),
}
}
Expand Down
12 changes: 2 additions & 10 deletions zebra-consensus/src/block/subsidy/funding_streams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,7 @@ pub fn height_for_first_halving(network: Network) -> Height {
// First halving on Mainnet is at Canopy
// while in Testnet is at block constant height of `1_116_000`
// https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams
match network {
Network::Mainnet => Canopy
.activation_height(network)
.expect("canopy activation height should be available"),
Network::Testnet => FIRST_HALVING_TESTNET,
}
network.height_for_first_halving()
}

/// Returns the address change period
Expand Down Expand Up @@ -93,10 +88,7 @@ fn funding_stream_address_period(height: Height, network: Network) -> u32 {
///
/// [7.10]: https://zips.z.cash/protocol/protocol.pdf#fundingstreams
fn funding_stream_address_index(height: Height, network: Network) -> usize {
let num_addresses = match network {
Network::Mainnet => FUNDING_STREAMS_NUM_ADDRESSES_MAINNET,
Network::Testnet => FUNDING_STREAMS_NUM_ADDRESSES_TESTNET,
};
let num_addresses = network.num_funding_streams();

let index = 1u32
.checked_add(funding_stream_address_period(height, network))
Expand Down
6 changes: 1 addition & 5 deletions zebra-consensus/src/block/subsidy/general.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,7 @@ mod test {

fn halving_for_network(network: Network) -> Result<(), Report> {
let blossom_height = Blossom.activation_height(network).unwrap();
let first_halving_height = match network {
Network::Mainnet => Canopy.activation_height(network).unwrap(),
// Based on "7.8 Calculation of Block Subsidy and Founders' Reward"
Network::Testnet => Height(1_116_000),
};
let first_halving_height = network.height_for_first_halving();

assert_eq!(
1,
Expand Down
6 changes: 3 additions & 3 deletions zebra-consensus/src/checkpoint/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ impl CheckpointList {
};

match checkpoint_list.hash(block::Height(0)) {
Some(hash) if hash == genesis_hash(network) => checkpoint_list,
Some(hash) if hash == network.genesis_hash() => checkpoint_list,
Some(_) => {
panic!("The hard-coded genesis checkpoint does not match the network genesis hash")
}
Expand Down Expand Up @@ -123,8 +123,8 @@ impl CheckpointList {
// Check that the list starts with the correct genesis block
match checkpoints.iter().next() {
Some((block::Height(0), hash))
if (hash == &genesis_hash(Network::Mainnet)
|| hash == &genesis_hash(Network::Testnet)) => {}
if (hash == &Network::Mainnet.genesis_hash()
|| hash == &Network::Testnet.genesis_hash()) => {}
Some((block::Height(0), _)) => {
Err("the genesis checkpoint does not match the Mainnet or Testnet genesis hash")?
}
Expand Down
12 changes: 12 additions & 0 deletions zebra-consensus/src/parameters/subsidy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,18 @@ pub const FUNDING_STREAM_ECC_ADDRESSES_MAINNET: [&str; FUNDING_STREAMS_NUM_ADDRE
"t3XHAGxRP2FNfhAjxGjxbrQPYtQQjc3RCQD",
];

pub trait ParameterSubsidy {
fn num_funding_streams(&self) -> usize;
}

impl ParameterSubsidy for Network {
fn num_funding_streams(&self) -> usize {
match self {
Network::Mainnet => FUNDING_STREAMS_NUM_ADDRESSES_MAINNET,
Network::Testnet => FUNDING_STREAMS_NUM_ADDRESSES_TESTNET,
}
}
}
/// List of addresses for the Zcash Foundation funding stream in the Mainnet.
pub const FUNDING_STREAM_ZF_ADDRESSES_MAINNET: [&str; FUNDING_STREAMS_NUM_ADDRESSES_MAINNET] =
["t3dvVE3SQEi7kqNzwrfNePxZ1d4hUyztBA1"; FUNDING_STREAMS_NUM_ADDRESSES_MAINNET];
Expand Down
9 changes: 6 additions & 3 deletions zebra-network/src/protocol/external/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ use tokio_util::codec::{Decoder, Encoder};

use zebra_chain::{
block::{self, Block},
parameters::Network,
parameters::{
network::{AllParameters as _, Magic},
Network,
},
serialization::{
sha256d, zcash_deserialize_bytes_external_count, zcash_deserialize_string_external_count,
CompactSizeMessage, FakeWriter, ReadZcashExt, SerializationError as Error,
Expand Down Expand Up @@ -163,7 +166,7 @@ impl Encoder<Message> for Codec {
let start_len = dst.len();
{
let dst = &mut dst.writer();
dst.write_all(&Magic::from(self.builder.network).0[..])?;
dst.write_all(&self.builder.network.magic_value().0[..])?;
dst.write_all(command)?;
dst.write_u32::<LittleEndian>(body_length as u32)?;

Expand Down Expand Up @@ -389,7 +392,7 @@ impl Decoder for Codec {
"read header from src buffer"
);

if magic != Magic::from(self.builder.network) {
if magic != self.builder.network.magic_value() {
return Err(Parse("supplied magic did not meet expectations"));
}
if body_len > self.builder.max_len {
Expand Down

0 comments on commit cf70754

Please sign in to comment.