mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-11-16 15:58:17 +00:00
database: split cumulative_difficulty
into low/high bits (#114)
* types: split `cumulative_difficulty` into low/high bits * helper: add `map` module * database: use `helper`'s cumulative_diff functions * helper: rename functions splitting bits isn't necessarily `cumulative_difficulty` specific * database: fix tests * helper: docs * helper: test output is low-endian bits * helper: docs * Update helper/src/map.rs Co-authored-by: Boog900 <boog900@tutanota.com> * Update helper/src/map.rs Co-authored-by: Boog900 <boog900@tutanota.com> --------- Co-authored-by: Boog900 <boog900@tutanota.com>
This commit is contained in:
parent
c65eb0a3ca
commit
bf6c21c71e
7 changed files with 84 additions and 8 deletions
|
@ -25,7 +25,7 @@ cfg-if = { workspace = true }
|
||||||
# FIXME:
|
# FIXME:
|
||||||
# We only need the `thread` feature if `service` is enabled.
|
# We only need the `thread` feature if `service` is enabled.
|
||||||
# Figure out how to enable features of an already pulled in dependency conditionally.
|
# Figure out how to enable features of an already pulled in dependency conditionally.
|
||||||
cuprate-helper = { path = "../helper", features = ["fs", "thread"] }
|
cuprate-helper = { path = "../helper", features = ["fs", "thread", "map"] }
|
||||||
cuprate-types = { path = "../types", features = ["service"] }
|
cuprate-types = { path = "../types", features = ["service"] }
|
||||||
curve25519-dalek = { workspace = true }
|
curve25519-dalek = { workspace = true }
|
||||||
monero-pruning = { path = "../pruning" }
|
monero-pruning = { path = "../pruning" }
|
||||||
|
|
|
@ -434,7 +434,8 @@ test_tables! {
|
||||||
timestamp: 1,
|
timestamp: 1,
|
||||||
cumulative_generated_coins: 123,
|
cumulative_generated_coins: 123,
|
||||||
weight: 321,
|
weight: 321,
|
||||||
cumulative_difficulty: 111,
|
cumulative_difficulty_low: 111,
|
||||||
|
cumulative_difficulty_high: 111,
|
||||||
block_hash: [54; 32],
|
block_hash: [54; 32],
|
||||||
cumulative_rct_outs: 2389,
|
cumulative_rct_outs: 2389,
|
||||||
long_term_weight: 2389,
|
long_term_weight: 2389,
|
||||||
|
|
|
@ -10,6 +10,7 @@ use monero_serai::{
|
||||||
transaction::{Input, Timelock, Transaction},
|
transaction::{Input, Timelock, Transaction},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use cuprate_helper::map::{combine_low_high_bits_to_u128, split_u128_into_low_high_bits};
|
||||||
use cuprate_types::{ExtendedBlockHeader, TransactionVerificationData, VerifiedBlockInformation};
|
use cuprate_types::{ExtendedBlockHeader, TransactionVerificationData, VerifiedBlockInformation};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -102,14 +103,18 @@ pub fn add_block(
|
||||||
cumulative_generated_coins(&block.height.saturating_sub(1), tables.block_infos())?
|
cumulative_generated_coins(&block.height.saturating_sub(1), tables.block_infos())?
|
||||||
+ block.generated_coins;
|
+ block.generated_coins;
|
||||||
|
|
||||||
|
let (cumulative_difficulty_low, cumulative_difficulty_high) =
|
||||||
|
split_u128_into_low_high_bits(block.cumulative_difficulty);
|
||||||
|
|
||||||
// Block Info.
|
// Block Info.
|
||||||
tables.block_infos_mut().put(
|
tables.block_infos_mut().put(
|
||||||
&block.height,
|
&block.height,
|
||||||
&BlockInfo {
|
&BlockInfo {
|
||||||
|
cumulative_difficulty_low,
|
||||||
|
cumulative_difficulty_high,
|
||||||
cumulative_generated_coins,
|
cumulative_generated_coins,
|
||||||
cumulative_rct_outs,
|
cumulative_rct_outs,
|
||||||
timestamp: block.block.header.timestamp,
|
timestamp: block.block.header.timestamp,
|
||||||
cumulative_difficulty: block.cumulative_difficulty,
|
|
||||||
block_hash: block.block_hash,
|
block_hash: block.block_hash,
|
||||||
// INVARIANT: #[cfg] @ lib.rs asserts `usize == u64`
|
// INVARIANT: #[cfg] @ lib.rs asserts `usize == u64`
|
||||||
weight: block.weight as u64,
|
weight: block.weight as u64,
|
||||||
|
@ -192,13 +197,18 @@ pub fn get_block_extended_header_from_height(
|
||||||
let block_blob = tables.block_blobs().get(block_height)?.0;
|
let block_blob = tables.block_blobs().get(block_height)?.0;
|
||||||
let block = Block::read(&mut block_blob.as_slice())?;
|
let block = Block::read(&mut block_blob.as_slice())?;
|
||||||
|
|
||||||
|
let cumulative_difficulty = combine_low_high_bits_to_u128(
|
||||||
|
block_info.cumulative_difficulty_low,
|
||||||
|
block_info.cumulative_difficulty_high,
|
||||||
|
);
|
||||||
|
|
||||||
// INVARIANT: #[cfg] @ lib.rs asserts `usize == u64`
|
// INVARIANT: #[cfg] @ lib.rs asserts `usize == u64`
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
Ok(ExtendedBlockHeader {
|
Ok(ExtendedBlockHeader {
|
||||||
|
cumulative_difficulty,
|
||||||
version: block.header.major_version,
|
version: block.header.major_version,
|
||||||
vote: block.header.minor_version,
|
vote: block.header.minor_version,
|
||||||
timestamp: block.header.timestamp,
|
timestamp: block.header.timestamp,
|
||||||
cumulative_difficulty: block_info.cumulative_difficulty,
|
|
||||||
block_weight: block_info.weight as usize,
|
block_weight: block_info.weight as usize,
|
||||||
long_term_weight: block_info.long_term_weight as usize,
|
long_term_weight: block_info.long_term_weight as usize,
|
||||||
})
|
})
|
||||||
|
|
|
@ -138,7 +138,8 @@ pub struct PreRctOutputId {
|
||||||
/// timestamp: 1,
|
/// timestamp: 1,
|
||||||
/// cumulative_generated_coins: 123,
|
/// cumulative_generated_coins: 123,
|
||||||
/// weight: 321,
|
/// weight: 321,
|
||||||
/// cumulative_difficulty: 112,
|
/// cumulative_difficulty_low: 112,
|
||||||
|
/// cumulative_difficulty_high: 112,
|
||||||
/// block_hash: [54; 32],
|
/// block_hash: [54; 32],
|
||||||
/// cumulative_rct_outs: 2389,
|
/// cumulative_rct_outs: 2389,
|
||||||
/// long_term_weight: 2389,
|
/// long_term_weight: 2389,
|
||||||
|
@ -165,8 +166,10 @@ pub struct BlockInfo {
|
||||||
pub cumulative_generated_coins: u64,
|
pub cumulative_generated_coins: u64,
|
||||||
/// TODO
|
/// TODO
|
||||||
pub weight: u64,
|
pub weight: u64,
|
||||||
/// TODO
|
/// Least-significant 64 bits of the 128-bit cumulative difficulty.
|
||||||
pub cumulative_difficulty: u128,
|
pub cumulative_difficulty_low: u64,
|
||||||
|
/// Most-significant 64 bits of the 128-bit cumulative difficulty.
|
||||||
|
pub cumulative_difficulty_high: u64,
|
||||||
/// TODO
|
/// TODO
|
||||||
pub block_hash: [u8; 32],
|
pub block_hash: [u8; 32],
|
||||||
/// TODO
|
/// TODO
|
||||||
|
|
|
@ -10,13 +10,14 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/consensus"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# All features on by default.
|
# All features on by default.
|
||||||
default = ["std", "atomic", "asynch", "fs", "num", "time", "thread", "constants"]
|
default = ["std", "atomic", "asynch", "fs", "num", "map", "time", "thread", "constants"]
|
||||||
std = []
|
std = []
|
||||||
atomic = ["dep:crossbeam"]
|
atomic = ["dep:crossbeam"]
|
||||||
asynch = ["dep:futures", "dep:rayon"]
|
asynch = ["dep:futures", "dep:rayon"]
|
||||||
constants = []
|
constants = []
|
||||||
fs = ["dep:dirs"]
|
fs = ["dep:dirs"]
|
||||||
num = []
|
num = []
|
||||||
|
map = []
|
||||||
time = ["dep:chrono", "std"]
|
time = ["dep:chrono", "std"]
|
||||||
thread = ["std", "dep:target_os_lib"]
|
thread = ["std", "dep:target_os_lib"]
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,9 @@ pub mod network;
|
||||||
#[cfg(feature = "num")]
|
#[cfg(feature = "num")]
|
||||||
pub mod num;
|
pub mod num;
|
||||||
|
|
||||||
|
#[cfg(feature = "map")]
|
||||||
|
pub mod map;
|
||||||
|
|
||||||
#[cfg(feature = "thread")]
|
#[cfg(feature = "thread")]
|
||||||
pub mod thread;
|
pub mod thread;
|
||||||
|
|
||||||
|
|
58
helper/src/map.rs
Normal file
58
helper/src/map.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
//! Mapping of data types.
|
||||||
|
//!
|
||||||
|
//! This module provides functions solely for mapping data types into others, mostly similar ones.
|
||||||
|
//!
|
||||||
|
//! `#[no_std]` compatible.
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- Use
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- `(u64, u64) <-> u128`
|
||||||
|
/// Split a [`u128`] value into 2 64-bit values.
|
||||||
|
///
|
||||||
|
/// The tuple returned is `(low, high)` where `low` is the least significant
|
||||||
|
/// 64-bits of `number`, and `high` is the most significant.
|
||||||
|
///
|
||||||
|
/// Note that the output of this function are `u64` representations of _bits_, not numerical values.
|
||||||
|
///
|
||||||
|
/// See [`combine_low_high_bits_to_u128`] for the inverse function.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use cuprate_helper::map::*;
|
||||||
|
/// let value = u128::MAX - 1;
|
||||||
|
/// let low = u64::MAX - 1;
|
||||||
|
/// let high = u64::MAX;
|
||||||
|
///
|
||||||
|
/// assert_eq!(split_u128_into_low_high_bits(value), (low, high));
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub const fn split_u128_into_low_high_bits(value: u128) -> (u64, u64) {
|
||||||
|
(value as u64, (value >> 64) as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Combine 2 64-bit values into a single [`u128`] value.
|
||||||
|
///
|
||||||
|
/// The inputs:
|
||||||
|
/// - `low_bits` are the _least_ significant 64-bits of `cumulative_difficulty`
|
||||||
|
/// - `high_bits` are the _most_ significant 64-bits of `cumulative_difficulty`
|
||||||
|
///
|
||||||
|
/// Note that `low_bits` & `high_bits` should be `u64` representation of _bits_, not numerical values.
|
||||||
|
///
|
||||||
|
/// See [`split_u128_into_low_high_bits`] for the inverse function.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use cuprate_helper::map::*;
|
||||||
|
/// let value = u128::MAX - 1;
|
||||||
|
/// let low = u64::MAX - 1;
|
||||||
|
/// let high = u64::MAX;
|
||||||
|
///
|
||||||
|
/// assert_eq!(combine_low_high_bits_to_u128(low, high), value);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub const fn combine_low_high_bits_to_u128(low_bits: u64, high_bits: u64) -> u128 {
|
||||||
|
let res = (high_bits as u128) << 64;
|
||||||
|
res | (low_bits as u128)
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- Tests
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {}
|
Loading…
Reference in a new issue