From 92d6913b14ab0812b2cf0b8e69f2a7d3a4b48e87 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Tue, 14 May 2024 14:25:46 +0200 Subject: [PATCH] fix monero merkle tree params --- .../src/grpc/base_node_grpc_server.rs | 27 +- .../core/src/proof_of_work/monero_rx/error.rs | 12 +- .../src/proof_of_work/monero_rx/helpers.rs | 11 +- .../monero_rx/merkle_tree_parameters.rs | 339 +++++++++++++----- 4 files changed, 273 insertions(+), 116 deletions(-) diff --git a/applications/minotari_node/src/grpc/base_node_grpc_server.rs b/applications/minotari_node/src/grpc/base_node_grpc_server.rs index 4ad1e1a1b3..01a0e6c978 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -235,10 +235,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { let (start_height, end_height) = get_heights(&request, handler.clone()) .await .map_err(|e| obscure_error_if_true(report_error_flag, e))?; - let num_requested = end_height.checked_sub(start_height).ok_or(obscure_error_if_true( - report_error_flag, - Status::invalid_argument("Start height is more than end height"), - ))?; + let num_requested = end_height.checked_sub(start_height).ok_or_else(|| { + obscure_error_if_true( + report_error_flag, + Status::invalid_argument("Start height is more than end height"), + ) + })?; if num_requested > GET_DIFFICULTY_MAX_HEIGHTS { return Err(obscure_error_if_true( report_error_flag, @@ -810,10 +812,9 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { coinbase.value = u64::try_from( (cur_share_sum.saturating_mul(reward)) .checked_div(total_shares) - .ok_or(obscure_error_if_true( - report_error_flag, - Status::internal("total shares are zero".to_string()), - ))? - + .ok_or_else(|| { + obscure_error_if_true(report_error_flag, Status::internal("total shares are zero".to_string())) + })? - prev_coinbase_value, ) .map_err(|_| { @@ -981,10 +982,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { debug!(target: LOG_TARGET, "Incoming GRPC request for get new block with coinbases"); let mut block_template: NewBlockTemplate = request .new_template - .ok_or(obscure_error_if_true( - report_error_flag, - Status::invalid_argument("Malformed block template provided".to_string()), - ))? + .ok_or_else(|| { + obscure_error_if_true( + report_error_flag, + Status::invalid_argument("Malformed block template provided".to_string()), + ) + })? .try_into() .map_err(|s| { obscure_error_if_true( diff --git a/base_layer/core/src/proof_of_work/monero_rx/error.rs b/base_layer/core/src/proof_of_work/monero_rx/error.rs index 1517ff9f0f..18e8fd242e 100644 --- a/base_layer/core/src/proof_of_work/monero_rx/error.rs +++ b/base_layer/core/src/proof_of_work/monero_rx/error.rs @@ -24,7 +24,11 @@ use tari_utilities::hex::HexError; use crate::{ common::{BanPeriod, BanReason}, - proof_of_work::{randomx_factory::RandomXVMFactoryError, DifficultyError}, + proof_of_work::{ + monero_rx::merkle_tree_parameters::MerkleTreeParametersError, + randomx_factory::RandomXVMFactoryError, + DifficultyError, + }, }; /// Errors that can occur when merging Monero PoW data with Tari PoW data @@ -50,6 +54,8 @@ pub enum MergeMineError { DifficultyError(#[from] DifficultyError), #[error("Cannot mine with 0 aux chains")] ZeroAuxChains, + #[error("Merkle Tree Parameters error: {0}")] + MerkleTreeParamsError(#[from] MerkleTreeParametersError), } impl MergeMineError { @@ -66,7 +72,9 @@ impl MergeMineError { reason: err.to_string(), ban_duration: BanPeriod::Long, }), - MergeMineError::RandomXVMFactoryError(_) | MergeMineError::ZeroAuxChains => None, + MergeMineError::RandomXVMFactoryError(_) | + MergeMineError::ZeroAuxChains | + MergeMineError::MerkleTreeParamsError(_) => None, } } } diff --git a/base_layer/core/src/proof_of_work/monero_rx/helpers.rs b/base_layer/core/src/proof_of_work/monero_rx/helpers.rs index 0a6407542b..17c1f46d40 100644 --- a/base_layer/core/src/proof_of_work/monero_rx/helpers.rs +++ b/base_layer/core/src/proof_of_work/monero_rx/helpers.rs @@ -162,18 +162,18 @@ fn check_aux_chains( } } let merkle_tree_params = MerkleTreeParameters::from_varint(merge_mining_params); - if merkle_tree_params.number_of_chains == 0 { + if merkle_tree_params.number_of_chains() == 0 { return false; } let hash_position = U256::from_little_endian( &Sha256::new() .chain_update(tari_genesis_block_hash) - .chain_update(merkle_tree_params.aux_nonce.to_le_bytes()) + .chain_update(merkle_tree_params.aux_nonce().to_le_bytes()) .chain_update((109_u8).to_le_bytes()) .finalize(), ) .low_u32() % - u32::from(merkle_tree_params.number_of_chains); + u32::from(merkle_tree_params.number_of_chains()); let (merkle_root, pos) = monero_data.aux_chain_merkle_proof.calculate_root_with_pos(&t_hash); if hash_position != pos { return false; @@ -342,10 +342,7 @@ pub fn insert_aux_chain_mr_and_info_into_block>( let encoded = if aux_chain_count == 1 { VarInt(0) } else { - let mt_params = MerkleTreeParameters { - number_of_chains: aux_chain_count, - aux_nonce, - }; + let mt_params = MerkleTreeParameters::new(aux_chain_count, aux_nonce)?; mt_params.to_varint() }; extra_field.0.insert(0, SubField::MergeMining(encoded, hash)); diff --git a/base_layer/core/src/proof_of_work/monero_rx/merkle_tree_parameters.rs b/base_layer/core/src/proof_of_work/monero_rx/merkle_tree_parameters.rs index fc785315d1..575ad117e3 100644 --- a/base_layer/core/src/proof_of_work/monero_rx/merkle_tree_parameters.rs +++ b/base_layer/core/src/proof_of_work/monero_rx/merkle_tree_parameters.rs @@ -20,20 +20,39 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use std::{cmp::min, convert::TryFrom}; +use std::convert::TryFrom; use monero::VarInt; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +#[derive(Clone, Debug, PartialEq, Error, Deserialize, Serialize, Eq)] +pub enum MerkleTreeParametersError { + #[error("Cannot have zero chains")] + NumberOfChainZero, +} // This is based on https://github.com/SChernykh/p2pool/blob/merge-mining/docs/MERGE_MINING.MD#merge-mining-tx_extra-tag-format #[derive(Debug, Clone, PartialEq)] pub struct MerkleTreeParameters { - pub number_of_chains: u8, - pub aux_nonce: u32, + number_of_chains: u8, + aux_nonce: u32, } impl MerkleTreeParameters { + pub fn new(number_of_chains: u8, aux_nonce: u32) -> Result { + if number_of_chains == 0u8 { + return Err(MerkleTreeParametersError::NumberOfChainZero); + } + Ok(MerkleTreeParameters { + number_of_chains, + aux_nonce, + }) + } + pub fn from_varint(merkle_tree_varint: VarInt) -> MerkleTreeParameters { - let bits = get_decode_bits(merkle_tree_varint.0) + 1; + let bits = get_decode_bits(merkle_tree_varint.0); + let number_of_chains = get_aux_chain_count(merkle_tree_varint.0, bits); let aux_nonce = get_aux_nonce(merkle_tree_varint.0, bits); MerkleTreeParameters { @@ -43,23 +62,35 @@ impl MerkleTreeParameters { } pub fn to_varint(&self) -> VarInt { - let size = u8::try_from(self.number_of_chains.leading_zeros()) + // 1 is encoded as 0 + let num = self.number_of_chains.saturating_sub(1); + let size = u8::try_from(num.leading_zeros()) .expect("This cant fail, u8 can only have 8 leading 0's which will fit in 255"); - let mut size_bits = encode_bits(7 - size); - let mut n_bits = encode_aux_chain_count(self.number_of_chains, 8 - size); + // size must be greater than 0, so saturating sub should be safe. + let mut size_bits = encode_bits(7u8.saturating_sub(size)); + let mut n_bits = encode_aux_chain_count(self.number_of_chains); let mut nonce_bits = encode_aux_nonce(self.aux_nonce); // this wont underflow as max size will be size_bits(3) + n_bits(8) + nonce_bits(32) = 43 let mut zero_bits = vec![0; 64 - size_bits.len() - n_bits.len() - nonce_bits.len()]; - size_bits.append(&mut n_bits); - size_bits.append(&mut nonce_bits); - size_bits.append(&mut zero_bits); - let num: u64 = size_bits.iter().fold(0, |result, &bit| (result << 1) ^ u64::from(bit)); + zero_bits.append(&mut nonce_bits); + zero_bits.append(&mut n_bits); + zero_bits.append(&mut size_bits); + + let num: u64 = zero_bits.iter().fold(0, |result, &bit| (result << 1) ^ u64::from(bit)); VarInt(num) } + + pub fn number_of_chains(&self) -> u8 { + self.number_of_chains + } + + pub fn aux_nonce(&self) -> u32 { + self.aux_nonce + } } fn get_decode_bits(num: u64) -> u8 { - let bits_num: Vec = (61..=63).rev().map(|n| ((num >> n) & 1) as u8).collect(); + let bits_num: Vec = (0..=2).rev().map(|n| ((num >> n) & 1) as u8).collect(); bits_num.iter().fold(0, |result, &bit| (result << 1) ^ bit) } @@ -68,18 +99,27 @@ fn encode_bits(num: u8) -> Vec { } fn get_aux_chain_count(num: u64, bits: u8) -> u8 { - let start = 60 - min(8, bits) + 1; - let bits_num: Vec = (start..=60).rev().map(|n| ((num >> n) & 1) as u8).collect(); - bits_num.iter().fold(0, |result, &bit| (result << 1) ^ bit) + let end = 3 + bits; + let bits_num: Vec = (3..=end).rev().map(|n| ((num >> n) & 1) as u8).collect(); + (bits_num.iter().fold(0, |result, &bit| (result << 1) ^ bit)).saturating_add(1) } -fn encode_aux_chain_count(num: u8, bit_length: u8) -> Vec { +fn encode_aux_chain_count(num: u8) -> Vec { + // 1 is encoded as 0 + let num = num.saturating_sub(1); + if num == 0 { + return vec![0]; + } + let size = u8::try_from(num.leading_zeros()) + .expect("This cant fail, u8 can only have 8 leading 0's which will fit in 255"); + let bit_length = 8 - size; (0..bit_length).rev().map(|n| (num >> n) & 1).collect() } fn get_aux_nonce(num: u64, bits: u8) -> u32 { - let start = 60 - min(8, u32::from(bits)) + 1 - 32; - let end = 60 - min(8, u32::from(bits)); + // 0,1,2 is storing bits, then amount of bits, then start at next bit to read + let start = 3 + bits + 1; + let end = start + 32; let bits_num: Vec = (start..=end).rev().map(|n| ((num >> n) & 1) as u32).collect(); bits_num.iter().fold(0, |result, &bit| (result << 1) ^ bit) } @@ -90,39 +130,51 @@ fn encode_aux_nonce(num: u32) -> Vec { #[cfg(test)] mod test { - use crate::proof_of_work::monero_rx::merkle_tree_parameters::{ - encode_aux_chain_count, - encode_aux_nonce, - encode_bits, - get_aux_chain_count, - get_aux_nonce, - get_decode_bits, + use monero::VarInt; + + use crate::proof_of_work::monero_rx::{ + merkle_tree_parameters::{ + encode_aux_chain_count, + encode_aux_nonce, + encode_bits, + get_aux_chain_count, + get_aux_nonce, + get_decode_bits, + }, + MerkleTreeParameters, }; #[test] fn en_decode_bits_test() { + let num = 24u64; // 11000 + let bit = get_decode_bits(num); + assert_eq!(bit, 0); + let bits = encode_bits(0); + let array = vec![0, 0, 0]; + assert_eq!(bits, array); + let num = 0b1100000000000000000000000000000000000000000000000000000000000101; let bit = get_decode_bits(num); - assert_eq!(bit, 6); - let bits = encode_bits(6); - let array = vec![1, 1, 0]; + assert_eq!(bit, 5); + let bits = encode_bits(5); + let array = vec![1, 0, 1]; assert_eq!(bits, array); - let num = 0b0100000000000000000000000000000000000000000000000000000000000101; + let num = 0b0100000000000000000000000000000000000000000000000000000000000110; let bit = get_decode_bits(num); - assert_eq!(bit, 2); - let bits = encode_bits(2); - let array = vec![0, 1, 0]; + assert_eq!(bit, 6); + let bits = encode_bits(6); + let array = vec![1, 1, 0]; assert_eq!(bits, array); - let num = 0b1110000000000000000000000000000000000000000000000000000000000101; + let num = 0b1010000000000000000000000000000000000000000000000000000000000111; let bit = get_decode_bits(num); assert_eq!(bit, 7); let bits = encode_bits(7); let array = vec![1, 1, 1]; assert_eq!(bits, array); - let num = 0b0011000000000000000000000000000000000000000000000000000000000101; + let num = 0b0011000000000000000000000000000000000000000000000000000000000001; let bit = get_decode_bits(num); assert_eq!(bit, 1); let bits = encode_bits(1); @@ -132,104 +184,154 @@ mod test { #[test] fn get_decode_aux_chain_test() { - let num = 0b1101111111100000000000000000000000000000000000000000000000000101; - let aux_number = get_aux_chain_count(num, 8); + let num = 24u64; // 11000 + let aux_number = get_aux_chain_count(num, 0); + assert_eq!(aux_number, 2); + let bits = encode_aux_chain_count(2); + let array: Vec = vec![1]; + assert_eq!(bits, array); + + let num = 0b1101111111100000000000000000000000000000000000000000011111110000; + let aux_number = get_aux_chain_count(num, 7); assert_eq!(aux_number, 255); - let bits = encode_aux_chain_count(255, 8); - let array = vec![1, 1, 1, 1, 1, 1, 1, 1]; + let bits = encode_aux_chain_count(255); + let array = vec![1, 1, 1, 1, 1, 1, 1, 0]; assert_eq!(bits, array); - let num = 0b1100000000100000000000000000000000000000000000000000000000000101; - let aux_number = get_aux_chain_count(num, 8); - assert_eq!(aux_number, 1); - let bits = encode_aux_chain_count(1, 8); - let array = vec![0, 0, 0, 0, 0, 0, 0, 1]; + let num = 0b1100000000100000000000000000000000000000000000000000000000101101; + let aux_number = get_aux_chain_count(num, 3); + assert_eq!(aux_number, 6); + let bits = encode_aux_chain_count(6); + let array = vec![1, 0, 1]; assert_eq!(bits, array); - let num = 0b1100000000000000000000000000000000000000000000000000000000000101; - let aux_number = get_aux_chain_count(num, 8); - assert_eq!(aux_number, 0); - let bits = encode_aux_chain_count(0, 8); - let array = vec![0, 0, 0, 0, 0, 0, 0, 0]; + let num = 0b1100000000000000000000000000000000000000000000000000000000011101; + let aux_number = get_aux_chain_count(num, 2); + assert_eq!(aux_number, 4); + let bits = encode_aux_chain_count(4); + let array = vec![1, 1]; assert_eq!(bits, array); let num = 0b1100111000000000000000000000000000000000000000000000000000000101; - let aux_number = get_aux_chain_count(num, 8); - assert_eq!(aux_number, 112); - let bits = encode_aux_chain_count(112, 8); - let array = vec![0, 1, 1, 1, 0, 0, 0, 0]; + let aux_number = get_aux_chain_count(num, 1); + assert_eq!(aux_number, 1); + let bits = encode_aux_chain_count(1); + let array = vec![0]; assert_eq!(bits, array); - let num = 0b1100000100000000000000000000000000000000000000000000000000000101; - let aux_number = get_aux_chain_count(num, 8); + let num = 0b1100000100000000000000000000000000000000000000000000000000111101; + let aux_number = get_aux_chain_count(num, 3); assert_eq!(aux_number, 8); - let bits = encode_aux_chain_count(8, 8); - let array = vec![0, 0, 0, 0, 1, 0, 0, 0]; + let bits = encode_aux_chain_count(8); + let array = vec![1, 1, 1]; + assert_eq!(bits, array); + + let num = 0b1100000001000000000000000000000000000000000000000000000001111101; + let aux_number = get_aux_chain_count(num, 4); + assert_eq!(aux_number, 16); + let bits = encode_aux_chain_count(16); + let array = vec![1, 1, 1, 1]; assert_eq!(bits, array); - let num = 0b1100000001000000000000000000000000000000000000000000000000000101; + let num = 0b1100000010000000000000000000000000000000000000000000001111000101; let aux_number = get_aux_chain_count(num, 7); - assert_eq!(aux_number, 1); - let bits = encode_aux_chain_count(1, 7); - let array = vec![0, 0, 0, 0, 0, 0, 1]; + assert_eq!(aux_number, 121); + let bits = encode_aux_chain_count(121); + let array = vec![1, 1, 1, 1, 0, 0, 0]; assert_eq!(bits, array); - let num = 0b1100000010000000000000000000000000000000000000000000000000000101; + let num = 0b1100000100000000000000000000000000000000000000000000001100000101; + let aux_number = get_aux_chain_count(num, 7); + assert_eq!(aux_number, 97); + let bits = encode_aux_chain_count(97); + let array = vec![1, 1, 0, 0, 0, 0, 0]; + assert_eq!(bits, array); + + let num = 0b1111000110000000000000000000000000000000000000000000000111000101; let aux_number = get_aux_chain_count(num, 6); + assert_eq!(aux_number, 57); + let bits = encode_aux_chain_count(57); + let array = vec![1, 1, 1, 0, 0, 0]; + assert_eq!(bits, array); + } + + #[test] + #[allow(clippy::too_many_lines)] + fn get_decode_aux_nonce_test() { + let num = 24u64; // 11000 + let aux_number = get_aux_nonce(num, 0); assert_eq!(aux_number, 1); - let bits = encode_aux_chain_count(1, 6); - let array = vec![0, 0, 0, 0, 0, 1]; + let bits = encode_aux_nonce(1); + let array = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + ]; assert_eq!(bits, array); - let num = 0b1100000100000000000000000000000000000000000000000000000000000101; - let aux_number = get_aux_chain_count(num, 5); + let num = 0b1100000000110000000000000000000000000000000000000000100000000101; + let aux_number = get_aux_nonce(num, 7); assert_eq!(aux_number, 1); - let bits = encode_aux_chain_count(1, 5); - let array = vec![0, 0, 0, 0, 1]; + let bits = encode_aux_nonce(1); + let array = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + ]; assert_eq!(bits, array); - let num = 0b1100000110000000000000000000000000000000000000000000000000000101; - let aux_number = get_aux_chain_count(num, 5); + let num = 0b1100000000110000000000000000000000000000000000000000010000000101; + let aux_number = get_aux_nonce(num, 6); assert_eq!(aux_number, 1); + let bits = encode_aux_nonce(1); + let array = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + ]; + assert_eq!(bits, array); - let num = 0b1111000110000000000000000000000000000000000000000000000000000101; - let aux_number = get_aux_chain_count(num, 1); + let num = 0b1100000000110000000000000000000000000000000000000000001000000101; + let aux_number = get_aux_nonce(num, 5); assert_eq!(aux_number, 1); - let bits = encode_aux_chain_count(1, 1); - let array = vec![1]; + let bits = encode_aux_nonce(1); + let array = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + ]; assert_eq!(bits, array); - } - #[test] - fn get_decode_aux_nonce_test() { - let num = 0b1100000000110000000000000000000000000000000000000000000000000101; - let aux_number = get_aux_nonce(num, 8); - assert_eq!(aux_number, 2147483648); - let bits = encode_aux_nonce(2147483648); + let num = 0b1100000000110000000000000000000000000000000000000000000100000101; + let aux_number = get_aux_nonce(num, 4); + assert_eq!(aux_number, 1); + let bits = encode_aux_nonce(1); let array = vec![ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ]; assert_eq!(bits, array); - let num = 0b1100000000011111111111111111111111111111111000000000000000000101; - let aux_number = get_aux_nonce(num, 8); - assert_eq!(aux_number, u32::MAX); - let bits = encode_aux_nonce(u32::MAX); + let num = 0b1100000000110000000000000000000000000000000000000000000010000101; + let aux_number = get_aux_nonce(num, 3); + assert_eq!(aux_number, 1); + let bits = encode_aux_nonce(1); let array = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ]; assert_eq!(bits, array); - let num = 0b1100000000111111111111111111111111111111110000000000000000000101; - let aux_number = get_aux_nonce(num, 7); - assert_eq!(aux_number, u32::MAX); + let num = 0b1100000000110000000000000000000000000000000000000000000001000101; + let aux_number = get_aux_nonce(num, 2); + assert_eq!(aux_number, 1); + let bits = encode_aux_nonce(1); + let array = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + ]; + assert_eq!(bits, array); - let num = 0b1100111111111111111111111111111111110000000000000000000000000101; + let num = 0b1100000000110000000000000000000000000000000000000000000000100101; let aux_number = get_aux_nonce(num, 1); - assert_eq!(aux_number, u32::MAX); + assert_eq!(aux_number, 1); + let bits = encode_aux_nonce(1); + let array = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + ]; + assert_eq!(bits, array); - let num = 0b1100000000100000000000000000000000000000001000000000000000000101; - let aux_number = get_aux_nonce(num, 8); + let num = 0b1100000000110000000000000000000000000000000000000000000000010101; + let aux_number = get_aux_nonce(num, 0); assert_eq!(aux_number, 1); let bits = encode_aux_nonce(1); let array = vec![ @@ -237,14 +339,61 @@ mod test { ]; assert_eq!(bits, array); - let num = 0b1100000000100000000000000000000000000000000000000000000000000101; - let aux_number = get_aux_nonce(num, 8); + let num = 0b1100000000110000000000000000000000000000000000000000010000000101; + let aux_number = get_aux_nonce(num, 7); assert_eq!(aux_number, 0); let bits = encode_aux_nonce(0); let array = vec![ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; assert_eq!(bits, array); + + let num = 0b1100000000110000000001111111111111111111111111111111110000000101; + let aux_number = get_aux_nonce(num, 7); + assert_eq!(aux_number, u32::MAX); + let bits = encode_aux_nonce(u32::MAX); + let array = vec![ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + ]; + assert_eq!(bits, array); + + let num = 0b1100000000110000000001111111111100011111111111111111110000000101; + let aux_number = get_aux_nonce(num, 7); + assert_eq!(aux_number, 4293132287); + let bits = encode_aux_nonce(4293132287); + let array = vec![ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + ]; + assert_eq!(bits, array); + + let num = 0b1100000000110000000001010101010101010101010101010101010000000101; + let aux_number = get_aux_nonce(num, 7); + assert_eq!(aux_number, 2863311530); + let bits = encode_aux_nonce(2863311530); + let array = vec![ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + ]; + assert_eq!(bits, array); + + let num = 0b110000000011000000000000000000000000011110011110111010000000101; + let aux_number = get_aux_nonce(num, 7); + assert_eq!(aux_number, 31214); + let bits = encode_aux_nonce(31214); + let array = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, + ]; + assert_eq!(bits, array); + } + + #[test] + fn merkle_complete() { + let num = VarInt(24); + let merkle_tree_params = MerkleTreeParameters::from_varint(num); + assert_eq!(merkle_tree_params.aux_nonce, 1); + assert_eq!(merkle_tree_params.number_of_chains, 2); + + let ser_num = merkle_tree_params.to_varint(); + assert_eq!(ser_num, VarInt(24)); } mod quicktest {