Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: impl final tari pow algorithm #4862

Merged
merged 3 commits into from
Nov 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions applications/tari_miner/src/difficulty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
use std::convert::TryInto;

use tari_app_grpc::tari_rpc::BlockHeader as grpc_header;
use tari_core::{blocks::BlockHeader, proof_of_work::sha3_difficulty};
use tari_core::{blocks::BlockHeader, proof_of_work::sha3x_difficulty};
use tari_utilities::epoch_time::EpochTime;

use crate::errors::MinerError;
Expand Down Expand Up @@ -67,7 +67,7 @@ impl BlockHeaderSha3 {
#[inline]
pub fn difficulty(&mut self) -> Difficulty {
self.hashes = self.hashes.saturating_add(1);
sha3_difficulty(&self.header).into()
sha3x_difficulty(&self.header).into()
}

#[allow(clippy::cast_possible_wrap)]
Expand All @@ -84,7 +84,7 @@ impl BlockHeaderSha3 {
#[cfg(test)]
pub mod test {
use chrono::{DateTime, NaiveDate, Utc};
use tari_core::proof_of_work::sha3_difficulty as core_sha3_difficulty;
use tari_core::proof_of_work::sha3x_difficulty as core_sha3_difficulty;

use super::*;

Expand Down
109 changes: 43 additions & 66 deletions base_layer/core/src/consensus/consensus_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,73 +512,50 @@ impl ConsensusConstants {
features: OutputFeaturesVersion::V0..=OutputFeaturesVersion::V0,
opcode: OpcodeVersion::V0..=OpcodeVersion::V1,
};
let consensus_constants_1 = ConsensusConstants {
effective_from_height: 0,
coinbase_lock_height: 6,
blockchain_version: 0,
valid_blockchain_version_range: 0..=0,
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: &ESMERALDA_DECAY_PARAMS,
emission_tail: 800 * T,
max_randomx_seed_height: 3000,
proof_of_work: algos,
faucet_value: (10 * 4000) * T,
transaction_weight: TransactionWeight::v1(),
max_script_byte_size: 2048,
input_version_range,
output_version_range,
kernel_version_range,
permitted_output_types: Self::current_permitted_output_types(),
};
let consensus_constants_2 = ConsensusConstants {
effective_from_height: 23000,
blockchain_version: 1,
valid_blockchain_version_range: 0..=1,
..consensus_constants_1.clone()
};
let consensus_constants_3 = ConsensusConstants {
effective_from_height: 25000,
output_version_range: output_version_2_range,
..consensus_constants_2.clone()
};
let consensus_constants_4 = ConsensusConstants {
effective_from_height: 33000,
blockchain_version: 2,
..consensus_constants_3.clone()
};

vec![
ConsensusConstants {
effective_from_height: 0,
coinbase_lock_height: 6,
blockchain_version: 0,
valid_blockchain_version_range: 0..=0,
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: &ESMERALDA_DECAY_PARAMS,
emission_tail: 800 * T,
max_randomx_seed_height: 3000,
proof_of_work: algos.clone(),
faucet_value: (10 * 4000) * T,
transaction_weight: TransactionWeight::v1(),
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(),
permitted_output_types: Self::current_permitted_output_types(),
},
ConsensusConstants {
effective_from_height: 23000,
coinbase_lock_height: 6,
blockchain_version: 1,
valid_blockchain_version_range: 0..=1,
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: &ESMERALDA_DECAY_PARAMS,
emission_tail: 800 * T,
max_randomx_seed_height: 3000,
proof_of_work: algos.clone(),
faucet_value: (10 * 4000) * T,
transaction_weight: TransactionWeight::v1(),
max_script_byte_size: 2048,
input_version_range: input_version_range.clone(),
output_version_range,
kernel_version_range: kernel_version_range.clone(),
permitted_output_types: Self::current_permitted_output_types(),
},
ConsensusConstants {
effective_from_height: 25000,
coinbase_lock_height: 6,
blockchain_version: 1,
valid_blockchain_version_range: 0..=1,
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: &ESMERALDA_DECAY_PARAMS,
emission_tail: 800 * T,
max_randomx_seed_height: 3000,
proof_of_work: algos,
faucet_value: (10 * 4000) * T,
transaction_weight: TransactionWeight::v1(),
max_script_byte_size: 2048,
input_version_range,
output_version_range: output_version_2_range,
kernel_version_range,
permitted_output_types: Self::current_permitted_output_types(),
},
consensus_constants_1,
consensus_constants_2,
consensus_constants_3,
consensus_constants_4,
]
}

Expand Down
2 changes: 1 addition & 1 deletion base_layer/core/src/proof_of_work/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub use proof_of_work_algorithm::PowAlgorithm;
#[cfg(feature = "base_node")]
mod sha3_pow;
#[cfg(feature = "base_node")]
pub use sha3_pow::sha3_difficulty;
pub use sha3_pow::sha3x_difficulty;
#[cfg(all(test, feature = "base_node"))]
pub use sha3_pow::test as sha3_test;

Expand Down
36 changes: 24 additions & 12 deletions base_layer/core/src/proof_of_work/sha3_pow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,17 @@ use crate::{
proof_of_work::{difficulty::util::big_endian_difficulty, Difficulty},
};

/// A simple sha3 proof of work. This is currently intended to be used for testing and perhaps Testnet until
/// Monero merge-mining is active.
/// The Tari Sha3X proof-of-work algorithm. This is the reference implementation of Tari's standalone mining
/// algorithm as described in [RFC-0131](https://rfc.tari.com/RFC-0131_Mining.html).
///
/// The proof of work difficulty is given by `H256(header )` where Hnnn is the sha3 digest of length
/// `nnn` bits.
pub fn sha3_difficulty(header: &BlockHeader) -> Difficulty {
sha3_difficulty_with_hash(header).0
/// In short Sha3X is a triple Keccak Sha3-256 hash of the nonce, mining hash and PoW mode byte.
/// Mining using this CPU version of the algorithm is unlikely to be profitable, but is included for reference and
/// can be used to mine tXTR on testnets.
pub fn sha3x_difficulty(header: &BlockHeader) -> Difficulty {
match header.version {
2 => sha3x_difficulty_with_hash(header).0,
_ => old_sha3_difficulty_with_hash(header).0,
}
}

pub fn sha3_hash(header: &BlockHeader) -> Vec<u8> {
Expand All @@ -52,7 +56,15 @@ pub fn sha3_hash(header: &BlockHeader) -> Vec<u8> {
.to_vec()
}

fn sha3_difficulty_with_hash(header: &BlockHeader) -> (Difficulty, Vec<u8>) {
fn sha3x_difficulty_with_hash(header: &BlockHeader) -> (Difficulty, Vec<u8>) {
let hash = sha3_hash(header);
let hash = Sha3_256::digest(&hash);
let hash = Sha3_256::digest(&hash);
let difficulty = big_endian_difficulty(&hash);
(difficulty, hash.to_vec())
}

fn old_sha3_difficulty_with_hash(header: &BlockHeader) -> (Difficulty, Vec<u8>) {
let hash = sha3_hash(header);
let hash = Sha3_256::digest(&hash);
let difficulty = big_endian_difficulty(&hash);
Expand All @@ -66,7 +78,7 @@ pub mod test {

use crate::{
blocks::BlockHeader,
proof_of_work::{sha3_pow::sha3_difficulty, Difficulty, PowAlgorithm},
proof_of_work::{sha3_pow::sha3x_difficulty, Difficulty, PowAlgorithm},
};

/// A simple example miner. It starts at nonce = 0 and iterates until it finds a header hash that meets the desired
Expand All @@ -75,14 +87,14 @@ pub mod test {
fn mine_sha3(target_difficulty: Difficulty, header: &mut BlockHeader) -> u64 {
header.nonce = 0;
// We're mining over here!
while sha3_difficulty(header) < target_difficulty {
while sha3x_difficulty(header) < target_difficulty {
header.nonce += 1;
}
header.nonce
}

pub fn get_header() -> BlockHeader {
let mut header = BlockHeader::new(0);
let mut header = BlockHeader::new(2);

#[allow(clippy::cast_sign_loss)]
let epoch_secs =
Expand All @@ -95,7 +107,7 @@ pub mod test {
#[test]
fn validate_max_target() {
let mut header = get_header();
header.nonce = 1;
assert_eq!(sha3_difficulty(&header), Difficulty::from(28));
header.nonce = 14;
assert_eq!(sha3x_difficulty(&header), Difficulty::from(25));
}
}
4 changes: 2 additions & 2 deletions base_layer/core/src/test_helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use tari_storage::{lmdb_store::LMDBBuilder, LMDBWrapper};
use crate::{
blocks::{Block, BlockHeader, BlockHeaderAccumulatedData, ChainHeader},
consensus::{ConsensusConstants, ConsensusManager},
proof_of_work::{sha3_difficulty, AchievedTargetDifficulty, Difficulty},
proof_of_work::{sha3x_difficulty, AchievedTargetDifficulty, Difficulty},
transactions::{
transaction_components::{Transaction, UnblindedOutput},
CoinbaseBuilder,
Expand Down Expand Up @@ -109,7 +109,7 @@ pub fn mine_to_difficulty(mut block: Block, difficulty: Difficulty) -> Result<Bl
// hash changing. This introduces the required entropy
block.header.nonce = rand::thread_rng().gen();
for _i in 0..20000 {
if sha3_difficulty(&block.header) == difficulty {
if sha3x_difficulty(&block.header) == difficulty {
return Ok(block);
}
block.header.nonce += 1;
Expand Down
4 changes: 2 additions & 2 deletions base_layer/core/src/validation/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use crate::{
monero_difficulty,
monero_rx::MoneroPowData,
randomx_factory::RandomXFactory,
sha3_difficulty,
sha3x_difficulty,
AchievedTargetDifficulty,
Difficulty,
PowAlgorithm,
Expand Down Expand Up @@ -178,7 +178,7 @@ pub fn check_target_difficulty(
) -> Result<AchievedTargetDifficulty, ValidationError> {
let achieved = match block_header.pow_algo() {
PowAlgorithm::Monero => monero_difficulty(block_header, randomx_factory)?,
PowAlgorithm::Sha3 => sha3_difficulty(block_header),
PowAlgorithm::Sha3 => sha3x_difficulty(block_header),
};

match AchievedTargetDifficulty::try_construct(block_header.pow_algo(), target, achieved) {
Expand Down
4 changes: 2 additions & 2 deletions base_layer/core/src/validation/mocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use tari_common_types::{chain_metadata::ChainMetadata, types::Commitment};
use crate::{
blocks::{Block, BlockHeader, ChainBlock},
chain_storage::BlockchainBackend,
proof_of_work::{sha3_difficulty, AchievedTargetDifficulty, Difficulty, PowAlgorithm},
proof_of_work::{sha3x_difficulty, AchievedTargetDifficulty, Difficulty, PowAlgorithm},
transactions::transaction_components::Transaction,
validation::{
error::ValidationError,
Expand Down Expand Up @@ -116,7 +116,7 @@ impl<B: BlockchainBackend> HeaderValidation<B> for MockValidator {
_: &DifficultyCalculator,
) -> Result<AchievedTargetDifficulty, ValidationError> {
if self.is_valid.load(Ordering::SeqCst) {
let achieved = sha3_difficulty(header);
let achieved = sha3x_difficulty(header);

let achieved_target =
AchievedTargetDifficulty::try_construct(PowAlgorithm::Sha3, achieved - Difficulty::from(1), achieved)
Expand Down
4 changes: 2 additions & 2 deletions base_layer/core/tests/helpers/block_builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use tari_core::{
chain_storage::{BlockAddResult, BlockchainBackend, BlockchainDatabase, ChainStorageError},
consensus::{emission::Emission, ConsensusConstants, ConsensusManager, ConsensusManagerBuilder},
covenants::Covenant,
proof_of_work::{sha3_difficulty, AchievedTargetDifficulty, Difficulty},
proof_of_work::{sha3x_difficulty, AchievedTargetDifficulty, Difficulty},
transactions::{
tari_amount::MicroTari,
test_helpers::{
Expand Down Expand Up @@ -540,7 +540,7 @@ pub fn generate_new_block_with_coinbase<B: BlockchainBackend>(
pub fn find_header_with_achieved_difficulty(header: &mut BlockHeader, achieved_difficulty: Difficulty) {
let mut num_tries = 0;

while sha3_difficulty(header) != achieved_difficulty {
while sha3x_difficulty(header) != achieved_difficulty {
header.nonce += 1;
num_tries += 1;
if num_tries > 10_000_000 {
Expand Down
14 changes: 7 additions & 7 deletions base_layer/tari_mining_helper_ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use libc::{c_char, c_int, c_uchar, c_uint, c_ulonglong};
use tari_core::{
blocks::BlockHeader,
consensus::{ConsensusDecoding, ToConsensusBytes},
proof_of_work::sha3_difficulty,
proof_of_work::sha3x_difficulty,
};
use tari_crypto::tari_utilities::hex::Hex;

Expand Down Expand Up @@ -263,7 +263,7 @@ pub unsafe extern "C" fn share_difficulty(header: *mut ByteVector, error_out: *m
return 2;
},
};
let difficulty = sha3_difficulty(&block_header);
let difficulty = sha3x_difficulty(&block_header);
difficulty.as_u64()
}

Expand Down Expand Up @@ -322,7 +322,7 @@ pub unsafe extern "C" fn share_validate(
ptr::swap(error_out, &mut error as *mut c_int);
return 2;
}
let difficulty = sha3_difficulty(&block_header).as_u64();
let difficulty = sha3x_difficulty(&block_header).as_u64();
if difficulty >= template_difficulty {
0
} else if difficulty >= share_difficulty {
Expand Down Expand Up @@ -357,8 +357,8 @@ mod tests {
let mut block = create_test_block();
block.header.nonce = rand::thread_rng().gen();
for _ in 0..20000 {
if sha3_difficulty(&block.header) >= difficulty {
return Ok((sha3_difficulty(&block.header), block.header.nonce));
if sha3x_difficulty(&block.header) >= difficulty {
return Ok((sha3x_difficulty(&block.header), block.header.nonce));
}
block.header.nonce += 1;
}
Expand All @@ -370,8 +370,8 @@ mod tests {

#[test]
fn detect_change_in_consensus_encoding() {
const NONCE: u64 = 15151693527177504675;
const DIFFICULTY: Difficulty = Difficulty::from_u64(8707);
const NONCE: u64 = 1368783905506569398;
const DIFFICULTY: Difficulty = Difficulty::from_u64(3549);
unsafe {
let mut error = -1;
let error_ptr = &mut error as *mut c_int;
Expand Down