Skip to content

Commit

Permalink
feat!: fix difficulty overflow (#5935)
Browse files Browse the repository at this point in the history
Description
---
Increases the accumulated algo difficulty from u64 ti u128. 
Increases the total accumulated difficulty from u128 to u256. 

Motivation and Context
---
Having block difficulty as u64 and accumulated difficulty as u64 will
overflow.
See:  #5851

How Has This Been Tested?
---
unit tests

Fixes: #5851

---------

Co-authored-by: Aaron Feickert <[email protected]>
  • Loading branch information
SWvheerden and AaronFeickert authored Nov 13, 2023
1 parent 18c3d0b commit 55bbdf2
Show file tree
Hide file tree
Showing 33 changed files with 513 additions and 145 deletions.
115 changes: 114 additions & 1 deletion Cargo.lock

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

Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ use crate::tari_rpc as grpc;

impl From<ChainMetadata> for grpc::MetaData {
fn from(meta: ChainMetadata) -> Self {
let diff = meta.accumulated_difficulty();
let mut diff = [0u8; 32];
meta.accumulated_difficulty().to_big_endian(&mut diff);
Self {
height_of_longest_chain: meta.height_of_longest_chain(),
best_block: meta.best_block().to_vec(),
pruned_height: meta.pruned_height(),
accumulated_difficulty: diff.to_be_bytes().to_vec(),
accumulated_difficulty: diff.to_vec(),
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ impl CommandContext {
Utc
),
target_diff.get(pow_algo).len(),
acc_monero.as_u64(),
acc_sha3.as_u64(),
acc_monero,
acc_sha3,
)?;
output.write_all(&buff).await?;

Expand Down
1 change: 1 addition & 0 deletions base_layer/common_types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ thiserror = "1.0.29"
tokio = { version = "1.23", features = ["time", "sync"] }
base64 = "0.21.0"
blake2 = "0.10"
primitive-types = { version = "0.12", features = ["serde"] }
9 changes: 5 additions & 4 deletions base_layer/common_types/src/chain_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

use std::fmt::{Display, Error, Formatter};

use primitive_types::U256;
use serde::{Deserialize, Serialize};
use tari_utilities::hex::Hex;

Expand All @@ -43,7 +44,7 @@ pub struct ChainMetadata {
/// provided. Archival nodes wil always have an `pruned_height` of zero.
pruned_height: u64,
/// The total accumulated proof of work of the longest chain
accumulated_difficulty: u128,
accumulated_difficulty: U256,
/// Timestamp of the tip block in the longest valid chain
timestamp: u64,
}
Expand All @@ -54,7 +55,7 @@ impl ChainMetadata {
hash: BlockHash,
pruning_horizon: u64,
pruned_height: u64,
accumulated_difficulty: u128,
accumulated_difficulty: U256,
timestamp: u64,
) -> ChainMetadata {
ChainMetadata {
Expand All @@ -73,7 +74,7 @@ impl ChainMetadata {
best_block: FixedHash::zero(),
pruning_horizon: 0,
pruned_height: 0,
accumulated_difficulty: 0,
accumulated_difficulty: 0.into(),
timestamp: 0,
}
}
Expand Down Expand Up @@ -128,7 +129,7 @@ impl ChainMetadata {
self.pruned_height
}

pub fn accumulated_difficulty(&self) -> u128 {
pub fn accumulated_difficulty(&self) -> U256 {
self.accumulated_difficulty
}

Expand Down
2 changes: 1 addition & 1 deletion base_layer/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ strum_macros = "0.22"
thiserror = "1.0.26"
tokio = { version = "1.23", features = ["time", "sync", "macros"] }
tracing = "0.1.26"
uint = { version = "0.9", default-features = false }
zeroize = "1"
primitive-types = { version = "0.12", features = ["serde"] }

[dev-dependencies]
criterion = { version = "0.4.0" }
Expand Down
11 changes: 6 additions & 5 deletions base_layer/core/src/base_node/chain_metadata_service/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
use std::{convert::TryFrom, sync::Arc};

use log::*;
use num_format::{Locale, ToFormattedString};
use prost::Message;
use tari_common::log_if_error;
use tari_common_types::chain_metadata::ChainMetadata;
Expand Down Expand Up @@ -204,7 +203,7 @@ impl ChainMetadataService {
"Received chain metadata from NodeId '{}' #{}, Acc_diff {}",
event.node_id,
chain_metadata.height_of_longest_chain(),
chain_metadata.accumulated_difficulty().to_formatted_string(&Locale::en),
chain_metadata.accumulated_difficulty(),
);

let peer_chain_metadata = PeerChainMetadata::new(event.node_id.clone(), chain_metadata, event.latency);
Expand All @@ -225,6 +224,7 @@ mod test {
use std::convert::TryInto;

use futures::StreamExt;
use primitive_types::U256;
use tari_comms::{peer_manager::NodeId, test_utils::mocks::create_connectivity_mock};
use tari_p2p::services::liveness::{
mock::{create_p2p_liveness_mock, LivenessMockState},
Expand Down Expand Up @@ -253,15 +253,17 @@ mod test {
}

fn create_sample_proto_chain_metadata() -> proto::ChainMetadata {
let diff: u128 = 1;
let diff: U256 = 1.into();
let mut bytes = [0u8; 32];
diff.to_big_endian(&mut bytes);
proto::ChainMetadata {
height_of_longest_chain: 1,
best_block: vec![
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31,
],
pruned_height: 0,
accumulated_difficulty: diff.to_be_bytes().to_vec(),
accumulated_difficulty: bytes.to_vec(),
timestamp: EpochTime::now().as_u64(),
}
}
Expand Down Expand Up @@ -303,7 +305,6 @@ mod test {
});

service.update_liveness_chain_metadata().await.unwrap();

assert_eq!(liveness_mock_state.call_count(), 1);

let last_call = liveness_mock_state.take_calls().remove(0);
Expand Down
23 changes: 11 additions & 12 deletions base_layer/core/src/base_node/proto/chain_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,27 @@
// 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::{
convert::{TryFrom, TryInto},
mem,
};
use std::convert::{TryFrom, TryInto};

use primitive_types::U256;
use tari_common_types::{chain_metadata::ChainMetadata, types::FixedHash};

use crate::proto::base_node as proto;

const ACCUMULATED_DIFFICULTY_BYTE_SIZE: usize = 32;
impl TryFrom<proto::ChainMetadata> for ChainMetadata {
type Error = String;

fn try_from(metadata: proto::ChainMetadata) -> Result<Self, Self::Error> {
const ACC_DIFFICULTY_ARRAY_LEN: usize = mem::size_of::<u128>();
if metadata.accumulated_difficulty.len() != ACC_DIFFICULTY_ARRAY_LEN {
if metadata.accumulated_difficulty.len() != ACCUMULATED_DIFFICULTY_BYTE_SIZE {
return Err(format!(
"Invalid accumulated difficulty byte length. {} was expected but the actual length was {}",
ACC_DIFFICULTY_ARRAY_LEN,
ACCUMULATED_DIFFICULTY_BYTE_SIZE,
metadata.accumulated_difficulty.len()
));
}

let mut acc_diff = [0; ACC_DIFFICULTY_ARRAY_LEN];
acc_diff.copy_from_slice(&metadata.accumulated_difficulty[0..ACC_DIFFICULTY_ARRAY_LEN]);
let accumulated_difficulty = u128::from_be_bytes(acc_diff);
let accumulated_difficulty = U256::from_big_endian(&metadata.accumulated_difficulty);
let height_of_longest_chain = metadata.height_of_longest_chain;

let pruning_horizon = if metadata.pruned_height == 0 {
Expand Down Expand Up @@ -73,12 +69,15 @@ impl TryFrom<proto::ChainMetadata> for ChainMetadata {

impl From<ChainMetadata> for proto::ChainMetadata {
fn from(metadata: ChainMetadata) -> Self {
let accumulated_difficulty = metadata.accumulated_difficulty().to_be_bytes().to_vec();
let mut accumulated_difficulty = [0u8; ACCUMULATED_DIFFICULTY_BYTE_SIZE];
metadata
.accumulated_difficulty()
.to_big_endian(&mut accumulated_difficulty);
Self {
height_of_longest_chain: metadata.height_of_longest_chain(),
best_block: metadata.best_block().to_vec(),
pruned_height: metadata.pruned_height(),
accumulated_difficulty,
accumulated_difficulty: accumulated_difficulty.to_vec(),
timestamp: metadata.timestamp(),
}
}
Expand Down
Loading

0 comments on commit 55bbdf2

Please sign in to comment.