mirror of
https://github.com/Cuprate/cuprate.git
synced 2025-01-05 10:29:28 +00:00
9c27ba5791
* write: impl write_block()
* ops: add `get_block_info()`
* read: impl block fn's
* read: fix signatures
* service: wrap `ConcreteEnv` in `RwLock` and doc why
* heed: use `read-txn-no-tls` for `Send` read transactions
* service: remove RwLock, impl some read functions
* read: impl `outputs()`
* read: flatten indentation, add `thread_local()`
* read: impl `number_outputs_with_amount()`
* tests: add `AssertTableLen`
* ops: replace all table len asserts with `AssertTableLen`
* service: initial tests
* service: finish most tests
* service: fix bad block data in test
* tables: fix incorrect doc
* service: add `ReadRequest::Outputs` test
* read: use macros for set/getting `ThreadLocal`'s based on backend
* small fixes
* fix review
* small fixes
* read: fix ThreadLocal macros for `redb`
* read: move `Output` mapping to `crate::free`
it's needed in tests too
* service: check output value correctness in tests
* helper: add timelock <-> u64 mapping functions
* free: use `u64_to_timelock()`
* read: rct outputs
* read: fix variable name
* read: use ThreadLocal for both backends
* heed: use Mutex for `HeedTableRo`'s read tx
* block: add miner_tx
* heed: remove Table bound
oops
* Revert "heed: use Mutex for `HeedTableRo`'s read tx"
This reverts commit 7e8aae016c
.
* add `UnsafeSendable`
* read: use `UnsafeSendable` for `heed`, branch on backend
* read: safety docs
* cargo.toml: re-add `read-txn-no-tls` for heed
* ops: fix tests, remove miner_tx
* fix tx_idx calculation, account for RCT outputs in tests
* read: docs, fix `get_tables!()` for both backends
* fix clippy
* database: `unsafe trait DatabaseRo`
* tx: use correct tx_id
* free: remove miner_tx comment
* free: remove `amount` input for rct outputs
* ops: split `add_tx` inputs
* read: use `UnsafeSendable` for all backends
* heed: update safety comment
* move output functions `free` -> `ops`
* read: fix `chain_height()` handling
* remove serde on `UnsafeSendable`
* de-dup docs on `trait DatabaseRo`, `get_tables!()`
* Update database/src/unsafe_sendable.rs
Co-authored-by: Boog900 <boog900@tutanota.com>
---------
Co-authored-by: Boog900 <boog900@tutanota.com>
107 lines
3.7 KiB
Rust
107 lines
3.7 KiB
Rust
//! Mapping of data types.
|
|
//!
|
|
//! This module provides functions solely for mapping data types into others, mostly similar ones.
|
|
//!
|
|
//! `#[no_std]` compatible.
|
|
|
|
//---------------------------------------------------------------------------------------------------- Use
|
|
use monero_serai::transaction::Timelock;
|
|
|
|
//---------------------------------------------------------------------------------------------------- `(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)
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------------- Timelock
|
|
/// Map a [`u64`] to a [`Timelock`].
|
|
///
|
|
/// Height/time is not differentiated via type, but rather:
|
|
/// "height is any value less than 500_000_000 and timestamp is any value above"
|
|
/// so the `u64/usize` is stored without any tag.
|
|
///
|
|
/// See [`timelock_to_u64`] for the inverse function.
|
|
///
|
|
/// - <https://github.com/Cuprate/cuprate/pull/102#discussion_r1558504285>
|
|
/// - <https://github.com/serai-dex/serai/blob/bc1dec79917d37d326ac3d9bc571a64131b0424a/coins/monero/src/transaction.rs#L139>
|
|
///
|
|
/// ```rust
|
|
/// # use cuprate_helper::map::*;
|
|
/// # use monero_serai::transaction::*;
|
|
/// assert_eq!(u64_to_timelock(0), Timelock::None);
|
|
/// assert_eq!(u64_to_timelock(499_999_999), Timelock::Block(499_999_999));
|
|
/// assert_eq!(u64_to_timelock(500_000_000), Timelock::Time(500_000_000));
|
|
/// ```
|
|
pub fn u64_to_timelock(u: u64) -> Timelock {
|
|
if u == 0 {
|
|
Timelock::None
|
|
} else if u < 500_000_000 {
|
|
Timelock::Block(usize::try_from(u).unwrap())
|
|
} else {
|
|
Timelock::Time(u)
|
|
}
|
|
}
|
|
|
|
/// Map [`Timelock`] to a [`u64`].
|
|
///
|
|
/// See [`u64_to_timelock`] for the inverse function and more documentation.
|
|
///
|
|
/// ```rust
|
|
/// # use cuprate_helper::map::*;
|
|
/// # use monero_serai::transaction::*;
|
|
/// assert_eq!(timelock_to_u64(Timelock::None), 0);
|
|
/// assert_eq!(timelock_to_u64(Timelock::Block(499_999_999)), 499_999_999);
|
|
/// assert_eq!(timelock_to_u64(Timelock::Time(500_000_000)), 500_000_000);
|
|
/// ```
|
|
pub fn timelock_to_u64(timelock: Timelock) -> u64 {
|
|
match timelock {
|
|
Timelock::None => 0,
|
|
Timelock::Block(u) => u64::try_from(u).unwrap(),
|
|
Timelock::Time(u) => u,
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------------- Tests
|
|
#[cfg(test)]
|
|
mod test {}
|