Skip to content

Commit

Permalink
fix: support previous block header hashing for version <= 2
Browse files Browse the repository at this point in the history
  • Loading branch information
sdbondi committed Mar 14, 2022
1 parent 26a4841 commit 82441f8
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 49 deletions.
87 changes: 67 additions & 20 deletions base_layer/core/src/blocks/block_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ use serde::{
Serialize,
Serializer,
};
use tari_common_types::types::{BlindingFactor, BlockHash, HashDigest, BLOCK_HASH_LENGTH};
use tari_common_types::{
array::copy_into_fixed_array,
types::{BlindingFactor, BlockHash, HashDigest, BLOCK_HASH_LENGTH},
};
use tari_crypto::tari_utilities::{epoch_time::EpochTime, hex::Hex, ByteArray, Hashable};
use thiserror::Error;

Expand Down Expand Up @@ -194,20 +197,49 @@ impl BlockHeader {
/// Provides a hash of the header, used for the merge mining.
/// This differs from the normal hash by not hashing the nonce and kernel pow.
pub fn merged_mining_hash(&self) -> Vec<u8> {
let mut hasher = HashWriter::new(HashDigest::new());
self.version.consensus_encode(&mut hasher).unwrap();
self.height.consensus_encode(&mut hasher).unwrap();
self.prev_hash.consensus_encode(&mut hasher).unwrap();
self.timestamp.as_u64().consensus_encode(&mut hasher).unwrap();
self.input_mr.consensus_encode(&mut hasher).unwrap();
self.output_mr.consensus_encode(&mut hasher).unwrap();
self.output_mmr_size.consensus_encode(&mut hasher).unwrap();
self.witness_mr.consensus_encode(&mut hasher).unwrap();
self.kernel_mr.consensus_encode(&mut hasher).unwrap();
self.kernel_mmr_size.consensus_encode(&mut hasher).unwrap();
self.total_kernel_offset.consensus_encode(&mut hasher).unwrap();
self.total_script_offset.consensus_encode(&mut hasher).unwrap();
hasher.finalize().to_vec()
if self.version <= 2 {
// TODO: Remove deprecated header hashing #testnetreset
HashDigest::new()
.chain(self.version.to_le_bytes())
.chain(self.height.to_le_bytes())
.chain(self.prev_hash.as_bytes())
.chain(self.timestamp.as_u64().to_le_bytes())
.chain(self.input_mr.as_bytes())
.chain(self.output_mr.as_bytes())
.chain(self.output_mmr_size.to_le_bytes())
.chain(self.witness_mr.as_bytes())
.chain(self.kernel_mr.as_bytes())
.chain(self.kernel_mmr_size.to_le_bytes())
.chain(self.total_kernel_offset.as_bytes())
.chain(self.total_script_offset.as_bytes())
.finalize()
.to_vec()
} else {
let mut hasher = HashWriter::new(HashDigest::new());
self.version.consensus_encode(&mut hasher).unwrap();
self.height.consensus_encode(&mut hasher).unwrap();
self.prev_hash.consensus_encode(&mut hasher).unwrap();
self.timestamp.as_u64().consensus_encode(&mut hasher).unwrap();
self.input_mr.consensus_encode(&mut hasher).unwrap();
// TODO: Cleanup if/when we migrate to fixed 32-byte array type for hashes
copy_into_fixed_array::<_, 32>(&self.output_mr)
.unwrap()
.consensus_encode(&mut hasher)
.unwrap();
self.output_mmr_size.consensus_encode(&mut hasher).unwrap();
copy_into_fixed_array::<_, 32>(&self.witness_mr)
.unwrap()
.consensus_encode(&mut hasher)
.unwrap();
copy_into_fixed_array::<_, 32>(&self.kernel_mr)
.unwrap()
.consensus_encode(&mut hasher)
.unwrap();
self.kernel_mmr_size.consensus_encode(&mut hasher).unwrap();
self.total_kernel_offset.consensus_encode(&mut hasher).unwrap();
self.total_script_offset.consensus_encode(&mut hasher).unwrap();
hasher.finalize().to_vec()
}
}

#[inline]
Expand Down Expand Up @@ -246,11 +278,26 @@ impl From<NewBlockHeaderTemplate> for BlockHeader {

impl Hashable for BlockHeader {
fn hash(&self) -> Vec<u8> {
let mut hasher = HashWriter::new(HashDigest::new());
self.merged_mining_hash().consensus_encode(&mut hasher).unwrap();
self.pow.consensus_encode(&mut hasher).unwrap();
self.nonce.consensus_encode(&mut hasher).unwrap();
hasher.finalize().to_vec()
if self.version <= 2 {
HashDigest::new()
.chain(self.merged_mining_hash())
.chain(self.pow.to_bytes())
.chain(self.nonce.to_le_bytes())
.finalize()
.to_vec()
} else {
let mut hasher = HashWriter::new(HashDigest::new());
// TODO: this excludes extraneous length varint used for Vec<u8> since a hash is always 32-bytes. Clean this
// up if we decide to migrate to a fixed 32-byte type
copy_into_fixed_array::<_, 32>(&self.merged_mining_hash())
.unwrap()
.consensus_encode(&mut hasher)
.unwrap();

self.pow.consensus_encode(&mut hasher).unwrap();
self.nonce.consensus_encode(&mut hasher).unwrap();
hasher.finalize().to_vec()
}
}
}

Expand Down
6 changes: 2 additions & 4 deletions base_layer/core/src/blocks/genesis_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ use crate::{
},
};

const LATEST_BLOCK_VERSION: u16 = 2;

/// Returns the genesis block for the selected network.
pub fn get_genesis_block(network: Network) -> ChainBlock {
use Network::*;
Expand Down Expand Up @@ -137,7 +135,7 @@ fn get_igor_genesis_block_raw() -> Block {
let timestamp = genesis.timestamp() as u64;
Block {
header: BlockHeader {
version: LATEST_BLOCK_VERSION,
version: 3,
height: 0,
prev_hash: vec![0; BLOCK_HASH_LENGTH],
timestamp: timestamp.into(),
Expand Down Expand Up @@ -277,7 +275,7 @@ fn get_dibbler_genesis_block_raw() -> Block {
let timestamp = genesis.timestamp() as u64;
Block {
header: BlockHeader {
version: LATEST_BLOCK_VERSION,
version: 2,
height: 0,
prev_hash: vec![0; BLOCK_HASH_LENGTH],
timestamp: timestamp.into(),
Expand Down
71 changes: 46 additions & 25 deletions base_layer/core/src/consensus/consensus_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,31 +402,52 @@ impl ConsensusConstants {
target_time: 200,
});
let (input_version_range, output_version_range, kernel_version_range) = version_zero();
let constants = ConsensusConstants {
effective_from_height: 0,
coinbase_lock_height: 360,
blockchain_version: 2,
future_time_limit: 540,
difficulty_block_window: 90,
// 65536 = target_block_size / bytes_per_gram = (1024*1024) / 16
// adj. + 95% = 127,795 - this effectively targets ~2Mb blocks closely matching the previous 19500
// weightings
max_block_transaction_weight: 127_795,
median_timestamp_count: 11,
emission_initial: 18_462_816_327 * uT,
emission_decay: &DIBBLER_DECAY_PARAMS,
emission_tail: 800 * T,
max_randomx_seed_height: u64::MAX,
proof_of_work: algos,
faucet_value: (10 * 4000) * T,
transaction_weight: TransactionWeight::v2(),
max_script_byte_size: 2048,
input_version_range,
output_version_range,
kernel_version_range,
};

vec![constants]
vec![
ConsensusConstants {
effective_from_height: 0,
coinbase_lock_height: 360,
blockchain_version: 2,
future_time_limit: 540,
difficulty_block_window: 90,
// 65536 = target_block_size / bytes_per_gram = (1024*1024) / 16
// adj. + 95% = 127,795 - this effectively targets ~2Mb blocks closely matching the previous 19500
// weightings
max_block_transaction_weight: 127_795,
median_timestamp_count: 11,
emission_initial: 18_462_816_327 * uT,
emission_decay: &DIBBLER_DECAY_PARAMS,
emission_tail: 800 * T,
max_randomx_seed_height: u64::MAX,
proof_of_work: algos.clone(),
faucet_value: (10 * 4000) * T,
transaction_weight: TransactionWeight::v2(),
max_script_byte_size: 2048,
input_version_range: input_version_range.clone(),
output_version_range: output_version_range.clone(),
kernel_version_range: kernel_version_range.clone(),
},
ConsensusConstants {
effective_from_height: 19000,
coinbase_lock_height: 360,
// CHANGE: Use v3 blocks from effective height
blockchain_version: 3,
future_time_limit: 540,
difficulty_block_window: 90,
max_block_transaction_weight: 127_795,
median_timestamp_count: 11,
emission_initial: 18_462_816_327 * uT,
emission_decay: &DIBBLER_DECAY_PARAMS,
emission_tail: 800 * T,
max_randomx_seed_height: u64::MAX,
proof_of_work: algos,
faucet_value: (10 * 4000) * T,
transaction_weight: TransactionWeight::v2(),
max_script_byte_size: 2048,
input_version_range,
output_version_range,
kernel_version_range,
},
]
}

pub fn mainnet() -> Vec<Self> {
Expand Down

0 comments on commit 82441f8

Please sign in to comment.