Skip to content

Commit

Permalink
fix use of network domain separated hashes in genesis block tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hansieodendaal committed Aug 24, 2024
1 parent 99133f0 commit 66a0571
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 67 deletions.
23 changes: 23 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions base_layer/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ env_logger = "0.7.0"
tempfile = "3.1.0"
toml = { version = "0.5" }
quickcheck = "1.0"
serial_test = "0.5"

[build-dependencies]
tari_common = { path = "../../common", features = ["build"], version = "1.3.0-pre.0" }
Expand Down
144 changes: 117 additions & 27 deletions base_layer/core/src/blocks/genesis_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ pub fn get_genesis_block(network: Network) -> ChainBlock {
}
}

/// Returns the genesis block hash for the selected network.
pub fn get_genesis_block_hash(network: Network) -> FixedHash {
*get_genesis_block(network).hash()
}

fn add_pre_mine_utxos_to_genesis_block(file: &str, block: &mut Block) {
let mut utxos = Vec::new();
let mut counter = 1;
Expand Down Expand Up @@ -474,10 +469,12 @@ fn get_raw_block(genesis_timestamp: &DateTime<FixedOffset>, not_before_proof: &P
}
}

// Note: Tests in this module are serialized to prevent domain separated network hash conflicts
#[cfg(test)]
mod test {
use std::convert::TryFrom;

use serial_test::serial;
use tari_common::get_static_genesis_block_hash;
use tari_common_types::{epoch::VnEpoch, types::Commitment};

Expand All @@ -495,61 +492,103 @@ mod test {
};

#[test]
#[cfg(tari_target_network_testnet)]
// #[cfg(tari_target_network_testnet)]
#[serial]
fn esmeralda_genesis_sanity_check() {
let _ = Network::set_current(Network::Esmeralda);
let network = Network::Esmeralda;
set_network_by_env_var_or_force_set(network);
if !network_matches(network) {
panic!("Network could not be set ('esmeralda_genesis_sanity_check()')");
}
// Note: Generate new data for `pub fn get_esmeralda_genesis_block()` and `fn get_esmeralda_genesis_block_raw()`
// if consensus values change, e.g. new pre_mine or other
let block = get_esmeralda_genesis_block();
check_block(Network::Esmeralda, &block, 164, 1);
check_block(network, &block, 164, 1);
assert_genesis_block_hash(network);
remove_network_env_var()
}

#[test]
#[cfg(tari_target_network_nextnet)]
#[serial]
// #[cfg(tari_target_network_nextnet)]
fn nextnet_genesis_sanity_check() {
let _ = Network::set_current(Network::NextNet);
let network = Network::NextNet;
set_network_by_env_var_or_force_set(network);
if !network_matches(network) {
panic!("Network could not be set ('nextnet_genesis_sanity_check()')");
}
// Note: Generate new data for `pub fn get_nextnet_genesis_block()` and `fn get_stagenet_genesis_block_raw()`
// if consensus values change, e.g. new pre_mine or other
let block = get_nextnet_genesis_block();
check_block(Network::NextNet, &block, 0, 0);
check_block(network, &block, 0, 0);
assert_genesis_block_hash(network);
remove_network_env_var()
}

#[test]
#[cfg(tari_target_network_mainnet)]
#[serial]
// #[cfg(tari_target_network_mainnet)]
fn mainnet_genesis_sanity_check() {
let _ = Network::set_current(Network::MainNet);
let network = Network::MainNet;
set_network_by_env_var_or_force_set(network);
if !network_matches(network) {
panic!("Network could not be set ('mainnet_genesis_sanity_check()')");
}
// Note: Generate new data for `pub fn get_nextnet_genesis_block()` and `fn get_stagenet_genesis_block_raw()`
// if consensus values change, e.g. new pre_mine or other
let block = get_mainnet_genesis_block();
check_block(Network::MainNet, &block, 164, 1);
check_block(network, &block, 164, 1);
assert_genesis_block_hash(network);
remove_network_env_var()
}

#[test]
#[cfg(tari_target_network_mainnet)]
#[serial]
// #[cfg(tari_target_network_mainnet)]
fn stagenet_genesis_sanity_check() {
let _ = Network::set_current(Network::StageNet);
let network = Network::StageNet;
set_network_by_env_var_or_force_set(network);
if !network_matches(network) {
panic!("Network could not be set ('stagenet_genesis_sanity_check()')");
}
// Note: Generate new data for `pub fn get_stagenet_genesis_block()` and `fn get_stagenet_genesis_block_raw()`
// if consensus values change, e.g. new pre_mine or other
let block = get_stagenet_genesis_block();
check_block(Network::StageNet, &block, 0, 0);
check_block(network, &block, 0, 0);
assert_genesis_block_hash(network);
remove_network_env_var()
}

#[test]
#[cfg(tari_target_network_testnet)]
#[serial]
// #[cfg(tari_target_network_testnet)]
fn igor_genesis_sanity_check() {
let _ = Network::set_current(Network::Igor);
let network = Network::Igor;
set_network_by_env_var_or_force_set(network);
if !network_matches(network) {
panic!("Network could not be set ('igor_genesis_sanity_check()')");
}
// Note: If outputs and kernels are added, this test will fail unless you explicitly check that network == Igor
let block = get_igor_genesis_block();
check_block(Network::Igor, &block, 0, 0);
check_block(network, &block, 0, 0);
assert_genesis_block_hash(network);
remove_network_env_var()
}

#[test]
#[cfg(tari_target_network_testnet)]
#[serial]
// #[cfg(tari_target_network_testnet)]
fn localnet_genesis_sanity_check() {
let _ = Network::set_current(Network::LocalNet);
let network = Network::LocalNet;
set_network_by_env_var_or_force_set(network);
if !network_matches(network) {
panic!("Network could not be set ('localnet_genesis_sanity_check()')");
}
// Note: If outputs and kernels are added, this test will fail unless you explicitly check that network == Igor
let block = get_localnet_genesis_block();
check_block(Network::LocalNet, &block, 0, 0);
check_block(network, &block, 0, 0);
assert_genesis_block_hash(network);
remove_network_env_var()
}

fn check_block(network: Network, block: &ChainBlock, expected_outputs: usize, expected_kernels: usize) {
Expand Down Expand Up @@ -631,9 +670,21 @@ mod test {
.unwrap();
}

// Update `tari_common::get_static_genesis_block_hash` with the correct values if the genesis block change
// This is a convenience test to check all networks are covered and to be able to test all networks at once
// without the need to re-compile or be dependent on the global static network setting. Update
// `tari_common::get_static_genesis_block_hash` with the correct values if the genesis block change.
#[test]
#[serial]
fn test_get_static_genesis_block_hash() {
if Network::is_set() {
println!("\nNote!! Static network constant is set, cannot run `test_get_static_genesis_block_hash`\n");
return;
}
if std::env::var("TARI_NETWORK").is_ok() {
println!("\nNote!! env_var 'TARI_NETWORK' in use, cannot run `test_get_static_genesis_block_hash`\n");
return;
}

for network in [
Network::MainNet,
Network::StageNet,
Expand All @@ -642,6 +693,10 @@ mod test {
Network::Esmeralda,
Network::LocalNet,
] {
set_network_by_env_var(network);
if !network_matches(network) {
panic!("Network could not be set ('test_get_static_genesis_block_hash()')");
}
match network {
Network::MainNet => assert_genesis_block_hash(network),
Network::StageNet => assert_genesis_block_hash(network),
Expand All @@ -650,16 +705,51 @@ mod test {
Network::Esmeralda => assert_genesis_block_hash(network),
Network::LocalNet => assert_genesis_block_hash(network),
}
remove_network_env_var();
}
}

fn assert_genesis_block_hash(network: Network) {
let expected_hash = *get_genesis_block(network).hash();
assert_eq!(
get_genesis_block_hash(network),
FixedHash::from_hex(get_static_genesis_block_hash(network)).unwrap(),
expected_hash.to_hex(),
get_static_genesis_block_hash(network),
"network: {}, expected hash: {} (update `tari_common::get_static_genesis_block_hash`)",
network,
get_genesis_block_hash(network)
expected_hash
);
}

fn set_network_by_env_var_or_force_set(network: Network) {
set_network_by_env_var(network);
if Network::get_current_or_user_setting_or_default() != network {
let _ = Network::set_current(network);
}
}

// Targeted network compilations will override inferred network hashes; this has effect only if
// `Network::set_current(<NETWORK>)` has not been called.
fn set_network_by_env_var(network: Network) {
// Do not override the env_var if network is already set; another test may fail
if std::env::var("TARI_NETWORK").is_err() {
std::env::set_var("TARI_NETWORK", network.as_key_str());
}
}

fn remove_network_env_var() {
std::env::remove_var("TARI_NETWORK");
}

fn network_matches(network: Network) -> bool {
let current_network = Network::get_current_or_user_setting_or_default();
if current_network == network {
true
} else {
println!(
"\nNetwork mismatch!! Required: {:?}, current: {:?}.\n",
network, current_network
);
false
}
}
}
85 changes: 50 additions & 35 deletions base_layer/core/src/consensus/consensus_encoding/hashing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,44 +145,59 @@ mod tests {

#[test]
fn it_uses_the_network_environment_variable_if_set() {
// This test will not pass if `Network::set_current(<NETWORK>)` is called before the test
if !Network::is_set() {
let label = "test";
let input = [1u8; 32];

for network in [
Network::MainNet,
Network::StageNet,
Network::NextNet,
Network::LocalNet,
Network::Igor,
Network::Esmeralda,
] {
println!("Testing network: {:?}", network);
// Generate a specific network hash
let hash_specify_network =
DomainSeparatedConsensusHasher::<TestHashDomain, Blake2b<U32>>::new_with_network(label, network)
.chain(&input)
.finalize();

// Generate an inferred network hash
std::env::set_var("TARI_NETWORK", network.as_key_str());
println!(
"TARI_NETWORK: {:?}",
std::env::var("TARI_NETWORK").unwrap_or_default()
);
println!(
"Network: {:?}\n",
Network::get_current_or_user_setting_or_default()
);
let inferred_network_hash = DomainSeparatedConsensusHasher::<TestHashDomain, Blake2b<U32>>::new(label)
// Targeted network compilations will override inferred network hashes; this only has effect if
// `Network::set_current(<NETWORK>)` has not been called. The test may also not run if
// `std::env::var("TARI_NETWORK")` has been set by some other test.
if Network::is_set() {
println!(
"\nNote!! Static network constant is set, cannot run \
`it_uses_the_network_environment_variable_if_set`\n"
);
return;
}
if std::env::var("TARI_NETWORK").is_ok() {
println!(
"\nNote!! env_var 'TARI_NETWORK' in use, cannot run \
`it_uses_the_network_environment_variable_if_set`\n"
);
return;
}

let label = "test";
let input = [1u8; 32];

for network in [
Network::MainNet,
Network::StageNet,
Network::NextNet,
Network::LocalNet,
Network::Igor,
Network::Esmeralda,
] {
println!("Testing network: {:?}", network);
// Generate a specific network hash
let hash_specify_network =
DomainSeparatedConsensusHasher::<TestHashDomain, Blake2b<U32>>::new_with_network(label, network)
.chain(&input)
.finalize();
std::env::remove_var("TARI_NETWORK");

// They should be equal
assert_eq!(hash_specify_network, inferred_network_hash);
}
// Generate an inferred network hash
std::env::set_var("TARI_NETWORK", network.as_key_str());
println!(
"TARI_NETWORK: {:?}",
std::env::var("TARI_NETWORK").unwrap_or_default()
);
println!(
"Network: {:?}\n",
Network::get_current_or_user_setting_or_default()
);
let inferred_network_hash = DomainSeparatedConsensusHasher::<TestHashDomain, Blake2b<U32>>::new(label)
.chain(&input)
.finalize();
std::env::remove_var("TARI_NETWORK");

// They should be equal
assert_eq!(hash_specify_network, inferred_network_hash);
}
}
}
10 changes: 5 additions & 5 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ pub(crate) const LOG_TARGET: &str = "common::config";
/// are wrong.
pub fn get_static_genesis_block_hash<'a>(network: Network) -> &'a str {
match network {
Network::MainNet => "54537be28b5d91b58d27fc52b7dc0cc8cea1977f199eb509d8b4978b0d6630c9",
Network::StageNet => "40afb45c7f10a2dd7bcdd3802273518aba20ac468a75cdfd0c85342a82096557",
Network::NextNet => "fed55ccea50122f9bc7ca913e4bbc0fcbd6913c10cb77bf08f98486ec88d5f02",
Network::Igor => "6cf2950380c69c991612f4ba0afb80281a41bb016239adc642c78817c2e1dbd4",
Network::MainNet => "ba4379a1319a6315d5262f61761d3f609f5b8eb9fa30a05f0d18a80c25d6bae9",
Network::StageNet => "cd073787a0bd8803a2546919523c687ccd88c8f0b39d652783530502e101f351",
Network::NextNet => "5ae9384d705f8df49d7e5b5988297440a53bc8be48b8792f8bc0a2c3d17c3479",
Network::Igor => "50ed5847a5b4b88dfd86fd48597801b72565a0e1ba14701fddbeaca356e8b4c3",
Network::Esmeralda => "6598d13c5dcb398f5cad294473421bc2fed69071b56fada4387a6ad03a44df08",
Network::LocalNet => "7a32e20ebaf29f7cd67f59a7894050488c350f9d97fcea0765b7a4723e2d0bf7",
Network::LocalNet => "b693c14804ceaafaee77c2d01310a221960383128de6b0f36c581fb706332bb3",
}
}

0 comments on commit 66a0571

Please sign in to comment.