Skip to content
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
7 changes: 7 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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ chrono = "0.4.10"
clap = "2.33.0"
config = { version = "0.10.1", features = ["toml"] }
crevice = "0.16.0"
debug-ignore = "1.0.5"
futures = "0.3"
futures-util = "0.3.15"
gl = "0.14.0"
Expand Down
2 changes: 1 addition & 1 deletion src/api/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ async fn get_db_with_block_no_mutex() -> SimpleDb {
block.set_txs_merkle_root_and_hash().await;
block.header = apply_mining_tx(block.header, nonce, "test".to_string());

if !validate_pow_block(&block.header) {
if validate_pow_block(&block.header).is_err() {
block.header.nonce_and_mining_tx_hash.0 = generate_pow_for_block(&block.header)
.expect("error occurred while mining block")
.expect("couldn't find a valid nonce");
Expand Down
60 changes: 48 additions & 12 deletions src/asert.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::convert::TryInto;
use {
crate::constants::{ASERT_HALF_LIFE, ASERT_TARGET_HASHES_PER_BLOCK},
rug::{integer::ParseIntegerError, Integer},
Expand Down Expand Up @@ -278,6 +279,28 @@ impl Sub for Timestamp {
}
}

/// An error which can occur when working with `CompactTarget`.
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum CompactTargetError {
/// Indicates that an attempt was made to construct a `CompactTarget` from a byte slice with
/// an invalid length.
SliceLength {
/// The length of the slice
length: usize,
},
}

impl std::error::Error for CompactTargetError {}

impl fmt::Display for CompactTargetError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::SliceLength { length } =>
write!(f, "Cannot construct CompactTarget from slice of length {}", length),
}
}
}

/// A 32-bit approximation of a 256-bit number that represents the target
/// a block hash must be lower than in order to meet PoW requirements.
///
Expand Down Expand Up @@ -321,14 +344,11 @@ impl CompactTarget {
Self(u32::from_be_bytes(array))
}

pub fn try_from_slice(slice: &[u8]) -> Option<Self> {
if slice.len() < 4 {
return None;
}

let mut array = [0u8; 4];
array.copy_from_slice(&slice[slice.len() - 4..]);
Some(Self::from_array(array))
pub fn try_from_slice(slice: &[u8]) -> Result<Self, CompactTargetError> {
// This requires that the slice's length is exactly 4
slice.try_into()
.map(Self::from_array)
.map_err(|_| CompactTargetError::SliceLength { length: slice.len() })
}
}

Expand Down Expand Up @@ -379,13 +399,13 @@ impl CompactTarget {
}
}

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct HeaderHash(sha3_256::Output<sha3::Sha3_256>);

impl HeaderHash {
pub fn try_calculate(header: &BlockHeader) -> Option<Self> {
let serialized = bincode::serialize(header).ok()?;
let hashed = sha3_256::digest(&serialized);
Some(Self(hashed))
pub fn calculate(header: &BlockHeader) -> Self {
let serialized = bincode::serialize(header).unwrap();
Self(sha3_256::digest(&serialized))
}

pub fn is_below_target(&self, target: &Target) -> bool {
Expand All @@ -402,6 +422,10 @@ impl HeaderHash {
self.is_below_target(&target)
}

pub fn as_bytes(&self) -> &[u8] {
&self.0
}

pub fn into_vec(self) -> Vec<u8> {
self.0.to_vec()
}
Expand All @@ -413,6 +437,18 @@ impl From<sha3_256::Output<sha3::Sha3_256>> for HeaderHash {
}
}

impl From<HeaderHash> for sha3_256::Output<sha3::Sha3_256> {
fn from(value: HeaderHash) -> Self {
value.0
}
}

impl AsRef<[u8]> for HeaderHash {
fn as_ref(&self) -> &[u8] {
&self.0
}
}

/// The expanded integer from of a `CompactTarget` that represents the target
/// a block hash must be lower than in order to meet PoW requirements.
///
Expand Down
4 changes: 2 additions & 2 deletions src/mempool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2079,10 +2079,10 @@ impl MempoolNode {
// Perform validation
let coinbase_hash = construct_tx_hash(&coinbase);
let block_to_check = apply_mining_tx(block_to_check, nonce, coinbase_hash);
if !validate_pow_block(&block_to_check) {
if let Err(err) = validate_pow_block(&block_to_check) {
return Some(Response {
success: false,
reason: "Invalid PoW for block".to_owned(),
reason: format!("Invalid PoW for block: {}", err),
});
}

Expand Down
4 changes: 2 additions & 2 deletions src/miner_pow/cpu.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use tw_chain::crypto::sha3_256;
use crate::constants::MINING_DIFFICULTY;
use crate::miner_pow::{MinerStatistics, SHA3_256PoWMiner, PoWDifficulty, MineError};
use crate::miner_pow::{MinerStatistics, Sha3_256PoWMiner, PoWDifficulty, MineError};

/// A miner which runs on the CPU.
#[derive(Copy, Clone, Debug)]
Expand All @@ -13,7 +13,7 @@ impl CpuMiner {
}
}

impl SHA3_256PoWMiner for CpuMiner {
impl Sha3_256PoWMiner for CpuMiner {
fn is_hw_accelerated(&self) -> bool {
false
}
Expand Down
Loading