mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-11-16 07:47:46 +00:00
Replace OnceLock
+ fn
with LazyLock
(#256)
* `consensus/` * `helper/` * `test-utils/` * `storage/` * fix docs + tests + lints * decomposed_amount: remove `LazyLock` * clippy
This commit is contained in:
parent
59adf6dcf8
commit
aeb070ae8d
14 changed files with 186 additions and 227 deletions
|
@ -1,36 +1,27 @@
|
|||
use std::sync::OnceLock;
|
||||
|
||||
/// Decomposed amount table.
|
||||
///
|
||||
static DECOMPOSED_AMOUNTS: OnceLock<[u64; 172]> = OnceLock::new();
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn decomposed_amounts() -> &'static [u64; 172] {
|
||||
DECOMPOSED_AMOUNTS.get_or_init(|| {
|
||||
[
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 20, 30, 40, 50, 60, 70, 80, 90,
|
||||
100, 200, 300, 400, 500, 600, 700, 800, 900,
|
||||
1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000,
|
||||
10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000,
|
||||
100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000,
|
||||
1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000,
|
||||
10000000, 20000000, 30000000, 40000000, 50000000, 60000000, 70000000, 80000000, 90000000,
|
||||
100000000, 200000000, 300000000, 400000000, 500000000, 600000000, 700000000, 800000000, 900000000,
|
||||
1000000000, 2000000000, 3000000000, 4000000000, 5000000000, 6000000000, 7000000000, 8000000000, 9000000000,
|
||||
10000000000, 20000000000, 30000000000, 40000000000, 50000000000, 60000000000, 70000000000, 80000000000, 90000000000,
|
||||
100000000000, 200000000000, 300000000000, 400000000000, 500000000000, 600000000000, 700000000000, 800000000000, 900000000000,
|
||||
1000000000000, 2000000000000, 3000000000000, 4000000000000, 5000000000000, 6000000000000, 7000000000000, 8000000000000, 9000000000000,
|
||||
10000000000000, 20000000000000, 30000000000000, 40000000000000, 50000000000000, 60000000000000, 70000000000000, 80000000000000, 90000000000000,
|
||||
100000000000000, 200000000000000, 300000000000000, 400000000000000, 500000000000000, 600000000000000, 700000000000000, 800000000000000, 900000000000000,
|
||||
1000000000000000, 2000000000000000, 3000000000000000, 4000000000000000, 5000000000000000, 6000000000000000, 7000000000000000, 8000000000000000, 9000000000000000,
|
||||
10000000000000000, 20000000000000000, 30000000000000000, 40000000000000000, 50000000000000000, 60000000000000000, 70000000000000000, 80000000000000000, 90000000000000000,
|
||||
100000000000000000, 200000000000000000, 300000000000000000, 400000000000000000, 500000000000000000, 600000000000000000, 700000000000000000, 800000000000000000, 900000000000000000,
|
||||
1000000000000000000, 2000000000000000000, 3000000000000000000, 4000000000000000000, 5000000000000000000, 6000000000000000000, 7000000000000000000, 8000000000000000000, 9000000000000000000,
|
||||
10000000000000000000
|
||||
]
|
||||
})
|
||||
}
|
||||
/// Decomposed amount table.
|
||||
pub static DECOMPOSED_AMOUNTS: [u64; 172] = [
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 20, 30, 40, 50, 60, 70, 80, 90,
|
||||
100, 200, 300, 400, 500, 600, 700, 800, 900,
|
||||
1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000,
|
||||
10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000,
|
||||
100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000,
|
||||
1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000,
|
||||
10000000, 20000000, 30000000, 40000000, 50000000, 60000000, 70000000, 80000000, 90000000,
|
||||
100000000, 200000000, 300000000, 400000000, 500000000, 600000000, 700000000, 800000000, 900000000,
|
||||
1000000000, 2000000000, 3000000000, 4000000000, 5000000000, 6000000000, 7000000000, 8000000000, 9000000000,
|
||||
10000000000, 20000000000, 30000000000, 40000000000, 50000000000, 60000000000, 70000000000, 80000000000, 90000000000,
|
||||
100000000000, 200000000000, 300000000000, 400000000000, 500000000000, 600000000000, 700000000000, 800000000000, 900000000000,
|
||||
1000000000000, 2000000000000, 3000000000000, 4000000000000, 5000000000000, 6000000000000, 7000000000000, 8000000000000, 9000000000000,
|
||||
10000000000000, 20000000000000, 30000000000000, 40000000000000, 50000000000000, 60000000000000, 70000000000000, 80000000000000, 90000000000000,
|
||||
100000000000000, 200000000000000, 300000000000000, 400000000000000, 500000000000000, 600000000000000, 700000000000000, 800000000000000, 900000000000000,
|
||||
1000000000000000, 2000000000000000, 3000000000000000, 4000000000000000, 5000000000000000, 6000000000000000, 7000000000000000, 8000000000000000, 9000000000000000,
|
||||
10000000000000000, 20000000000000000, 30000000000000000, 40000000000000000, 50000000000000000, 60000000000000000, 70000000000000000, 80000000000000000, 90000000000000000,
|
||||
100000000000000000, 200000000000000000, 300000000000000000, 400000000000000000, 500000000000000000, 600000000000000000, 700000000000000000, 800000000000000000, 900000000000000000,
|
||||
1000000000000000000, 2000000000000000000, 3000000000000000000, 4000000000000000000, 5000000000000000000, 6000000000000000000, 7000000000000000000, 8000000000000000000, 9000000000000000000,
|
||||
10000000000000000000
|
||||
];
|
||||
|
||||
/// Checks that an output amount is decomposed.
|
||||
///
|
||||
|
@ -40,7 +31,7 @@ pub fn decomposed_amounts() -> &'static [u64; 172] {
|
|||
/// ref: <https://monero-book.cuprate.org/consensus_rules/blocks/miner_tx.html#output-amounts>
|
||||
#[inline]
|
||||
pub fn is_decomposed_amount(amount: &u64) -> bool {
|
||||
decomposed_amounts().binary_search(amount).is_ok()
|
||||
DECOMPOSED_AMOUNTS.binary_search(amount).is_ok()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -49,7 +40,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn decomposed_amounts_return_decomposed() {
|
||||
for amount in decomposed_amounts() {
|
||||
for amount in DECOMPOSED_AMOUNTS.iter() {
|
||||
assert!(is_decomposed_amount(amount))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ use proptest::{collection::vec, prelude::*};
|
|||
use monero_serai::transaction::Output;
|
||||
|
||||
use super::*;
|
||||
use crate::decomposed_amount::decomposed_amounts;
|
||||
use crate::decomposed_amount::DECOMPOSED_AMOUNTS;
|
||||
|
||||
#[test]
|
||||
fn test_check_output_amount_v1() {
|
||||
for amount in decomposed_amounts() {
|
||||
for amount in DECOMPOSED_AMOUNTS.iter() {
|
||||
assert!(check_output_amount_v1(*amount, &HardFork::V2).is_ok())
|
||||
}
|
||||
|
||||
|
|
133
helper/src/fs.rs
133
helper/src/fs.rs
|
@ -4,7 +4,7 @@
|
|||
//! Note that this module's functions uses [`dirs`],
|
||||
//! which adheres to the XDG standard on Linux.
|
||||
//!
|
||||
//! This means that the values returned by these functions
|
||||
//! This means that the values returned by these statics
|
||||
//! may change at runtime depending on environment variables,
|
||||
//! for example:
|
||||
//!
|
||||
|
@ -17,7 +17,7 @@
|
|||
//! # if cfg!(target_os = "linux") {
|
||||
//! std::env::set_var("XDG_CONFIG_HOME", "/custom/path");
|
||||
//! assert_eq!(
|
||||
//! cuprate_config_dir().to_string_lossy(),
|
||||
//! CUPRATE_CONFIG_DIR.to_string_lossy(),
|
||||
//! "/custom/path/cuprate"
|
||||
//! );
|
||||
//! # }
|
||||
|
@ -28,10 +28,7 @@
|
|||
//! - <https://docs.rs/dirs>
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Use
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
sync::OnceLock,
|
||||
};
|
||||
use std::{path::PathBuf, sync::LazyLock};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Const
|
||||
/// Cuprate's main directory.
|
||||
|
@ -62,71 +59,59 @@ pub const CUPRATE_DIR: &str = {
|
|||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Directories
|
||||
/// Create a (private) `OnceLock` and accessor function for common PATHs used by Cuprate.
|
||||
/// Create a `LazyLock` for common PATHs used by Cuprate.
|
||||
///
|
||||
/// This currently creates these directories:
|
||||
/// - [`cuprate_cache_dir()`]
|
||||
/// - [`cuprate_config_dir()`]
|
||||
/// - [`cuprate_data_dir()`]
|
||||
/// - [`cuprate_blockchain_dir()`]
|
||||
///
|
||||
/// FIXME: Use `LazyLock` when stabilized.
|
||||
/// <https://github.com/rust-lang/rust/issues/109736>.
|
||||
/// <https://doc.rust-lang.org/std/sync/struct.LazyLock.html>.
|
||||
macro_rules! impl_path_oncelock_and_fn {
|
||||
/// - [`CUPRATE_CACHE_DIR`]
|
||||
/// - [`CUPRATE_CONFIG_DIR`]
|
||||
/// - [`CUPRATE_DATA_DIR`]
|
||||
/// - [`CUPRATE_BLOCKCHAIN_DIR`]
|
||||
macro_rules! impl_path_lazylock {
|
||||
($(
|
||||
$(#[$attr:meta])* // Documentation and any `derive`'s.
|
||||
$fn:ident, // Name of the corresponding access function.
|
||||
$name:ident, // Name of the corresponding `LazyLock`.
|
||||
$dirs_fn:ident, // Name of the `dirs` function to use, the PATH prefix.
|
||||
$sub_dirs:literal // Any sub-directories to add onto the PATH.
|
||||
),* $(,)?) => {$(
|
||||
// Create the `OnceLock` if needed, append
|
||||
// Create the `LazyLock` if needed, append
|
||||
// the Cuprate directory string and return.
|
||||
$(#[$attr])*
|
||||
pub fn $fn() -> &'static Path {
|
||||
/// Local `OnceLock` containing the Path.
|
||||
static ONCE_LOCK: OnceLock<PathBuf> = OnceLock::new();
|
||||
pub static $name: LazyLock<PathBuf> = LazyLock::new(|| {
|
||||
// There's nothing we can do but panic if
|
||||
// we cannot acquire critical system directories.
|
||||
//
|
||||
// Although, this realistically won't panic on
|
||||
// normal systems for all OS's supported by `dirs`.
|
||||
let mut path = dirs::$dirs_fn().unwrap();
|
||||
|
||||
ONCE_LOCK.get_or_init(|| {
|
||||
// There's nothing we can do but panic if
|
||||
// we cannot acquire critical system directories.
|
||||
//
|
||||
// Although, this realistically won't panic on
|
||||
// normal systems for all OS's supported by `dirs`.
|
||||
let mut path = dirs::$dirs_fn().unwrap();
|
||||
// FIXME:
|
||||
// Consider a user who does `HOME=/ ./cuprated`
|
||||
//
|
||||
// Should we say "that's stupid" and panic here?
|
||||
// Or should it be respected?
|
||||
// We really don't want a `rm -rf /` type of situation...
|
||||
assert!(
|
||||
path.parent().is_some(),
|
||||
"SAFETY: returned OS PATH was either root or empty, aborting"
|
||||
);
|
||||
|
||||
// FIXME:
|
||||
// Consider a user who does `HOME=/ ./cuprated`
|
||||
//
|
||||
// Should we say "that's stupid" and panic here?
|
||||
// Or should it be respected?
|
||||
// We really don't want a `rm -rf /` type of situation...
|
||||
assert!(
|
||||
path.parent().is_some(),
|
||||
"SAFETY: returned OS PATH was either root or empty, aborting"
|
||||
);
|
||||
// Returned OS PATH should be absolute, not relative.
|
||||
assert!(path.is_absolute(), "SAFETY: returned OS PATH was not absolute");
|
||||
|
||||
// Returned OS PATH should be absolute, not relative.
|
||||
assert!(path.is_absolute(), "SAFETY: returned OS PATH was not absolute");
|
||||
// Unconditionally prefix with the top-level Cuprate directory.
|
||||
path.push(CUPRATE_DIR);
|
||||
|
||||
// Unconditionally prefix with the top-level Cuprate directory.
|
||||
path.push(CUPRATE_DIR);
|
||||
// Add any sub directories if specified in the macro.
|
||||
if !$sub_dirs.is_empty() {
|
||||
path.push($sub_dirs);
|
||||
}
|
||||
|
||||
// Add any sub directories if specified in the macro.
|
||||
if !$sub_dirs.is_empty() {
|
||||
path.push($sub_dirs);
|
||||
}
|
||||
|
||||
path
|
||||
})
|
||||
}
|
||||
path
|
||||
});
|
||||
)*};
|
||||
}
|
||||
|
||||
// Note that the `OnceLock`'s are prefixed with `__` to indicate:
|
||||
// 1. They're not really to be used directly
|
||||
// 2. To avoid name conflicts
|
||||
impl_path_oncelock_and_fn! {
|
||||
impl_path_lazylock! {
|
||||
/// Cuprate's cache directory.
|
||||
///
|
||||
/// This is the PATH used for any Cuprate cache files.
|
||||
|
@ -136,7 +121,7 @@ impl_path_oncelock_and_fn! {
|
|||
/// | Windows | `C:\Users\Alice\AppData\Local\Cuprate\` |
|
||||
/// | macOS | `/Users/Alice/Library/Caches/Cuprate/` |
|
||||
/// | Linux | `/home/alice/.cache/cuprate/` |
|
||||
cuprate_cache_dir,
|
||||
CUPRATE_CACHE_DIR,
|
||||
cache_dir,
|
||||
"",
|
||||
|
||||
|
@ -149,7 +134,7 @@ impl_path_oncelock_and_fn! {
|
|||
/// | Windows | `C:\Users\Alice\AppData\Roaming\Cuprate\` |
|
||||
/// | macOS | `/Users/Alice/Library/Application Support/Cuprate/` |
|
||||
/// | Linux | `/home/alice/.config/cuprate/` |
|
||||
cuprate_config_dir,
|
||||
CUPRATE_CONFIG_DIR,
|
||||
config_dir,
|
||||
"",
|
||||
|
||||
|
@ -162,7 +147,7 @@ impl_path_oncelock_and_fn! {
|
|||
/// | Windows | `C:\Users\Alice\AppData\Roaming\Cuprate\` |
|
||||
/// | macOS | `/Users/Alice/Library/Application Support/Cuprate/` |
|
||||
/// | Linux | `/home/alice/.local/share/cuprate/` |
|
||||
cuprate_data_dir,
|
||||
CUPRATE_DATA_DIR,
|
||||
data_dir,
|
||||
"",
|
||||
|
||||
|
@ -175,7 +160,7 @@ impl_path_oncelock_and_fn! {
|
|||
/// | Windows | `C:\Users\Alice\AppData\Roaming\Cuprate\blockchain\` |
|
||||
/// | macOS | `/Users/Alice/Library/Application Support/Cuprate/blockchain/` |
|
||||
/// | Linux | `/home/alice/.local/share/cuprate/blockchain/` |
|
||||
cuprate_blockchain_dir,
|
||||
CUPRATE_BLOCKCHAIN_DIR,
|
||||
data_dir,
|
||||
"blockchain",
|
||||
}
|
||||
|
@ -192,58 +177,58 @@ mod test {
|
|||
// - It must `ends_with()` the expected end PATH for the OS
|
||||
#[test]
|
||||
fn path_sanity_check() {
|
||||
assert!(cuprate_cache_dir().is_absolute());
|
||||
assert!(cuprate_config_dir().is_absolute());
|
||||
assert!(cuprate_data_dir().is_absolute());
|
||||
assert!(cuprate_blockchain_dir().is_absolute());
|
||||
assert!(CUPRATE_CACHE_DIR.is_absolute());
|
||||
assert!(CUPRATE_CONFIG_DIR.is_absolute());
|
||||
assert!(CUPRATE_DATA_DIR.is_absolute());
|
||||
assert!(CUPRATE_BLOCKCHAIN_DIR.is_absolute());
|
||||
|
||||
if cfg!(target_os = "windows") {
|
||||
let dir = cuprate_cache_dir();
|
||||
let dir = &*CUPRATE_CACHE_DIR;
|
||||
println!("cuprate_cache_dir: {dir:?}");
|
||||
assert!(dir.ends_with(r"AppData\Local\Cuprate"));
|
||||
|
||||
let dir = cuprate_config_dir();
|
||||
let dir = &*CUPRATE_CONFIG_DIR;
|
||||
println!("cuprate_config_dir: {dir:?}");
|
||||
assert!(dir.ends_with(r"AppData\Roaming\Cuprate"));
|
||||
|
||||
let dir = cuprate_data_dir();
|
||||
let dir = &*CUPRATE_DATA_DIR;
|
||||
println!("cuprate_data_dir: {dir:?}");
|
||||
assert!(dir.ends_with(r"AppData\Roaming\Cuprate"));
|
||||
|
||||
let dir = cuprate_blockchain_dir();
|
||||
let dir = &*CUPRATE_BLOCKCHAIN_DIR;
|
||||
println!("cuprate_blockchain_dir: {dir:?}");
|
||||
assert!(dir.ends_with(r"AppData\Roaming\Cuprate\blockchain"));
|
||||
} else if cfg!(target_os = "macos") {
|
||||
let dir = cuprate_cache_dir();
|
||||
let dir = &*CUPRATE_CACHE_DIR;
|
||||
println!("cuprate_cache_dir: {dir:?}");
|
||||
assert!(dir.ends_with("Library/Caches/Cuprate"));
|
||||
|
||||
let dir = cuprate_config_dir();
|
||||
let dir = &*CUPRATE_CONFIG_DIR;
|
||||
println!("cuprate_config_dir: {dir:?}");
|
||||
assert!(dir.ends_with("Library/Application Support/Cuprate"));
|
||||
|
||||
let dir = cuprate_data_dir();
|
||||
let dir = &*CUPRATE_DATA_DIR;
|
||||
println!("cuprate_data_dir: {dir:?}");
|
||||
assert!(dir.ends_with("Library/Application Support/Cuprate"));
|
||||
|
||||
let dir = cuprate_blockchain_dir();
|
||||
let dir = &*CUPRATE_BLOCKCHAIN_DIR;
|
||||
println!("cuprate_blockchain_dir: {dir:?}");
|
||||
assert!(dir.ends_with("Library/Application Support/Cuprate/blockchain"));
|
||||
} else {
|
||||
// Assumes Linux.
|
||||
let dir = cuprate_cache_dir();
|
||||
let dir = &*CUPRATE_CACHE_DIR;
|
||||
println!("cuprate_cache_dir: {dir:?}");
|
||||
assert!(dir.ends_with(".cache/cuprate"));
|
||||
|
||||
let dir = cuprate_config_dir();
|
||||
let dir = &*CUPRATE_CONFIG_DIR;
|
||||
println!("cuprate_config_dir: {dir:?}");
|
||||
assert!(dir.ends_with(".config/cuprate"));
|
||||
|
||||
let dir = cuprate_data_dir();
|
||||
let dir = &*CUPRATE_DATA_DIR;
|
||||
println!("cuprate_data_dir: {dir:?}");
|
||||
assert!(dir.ends_with(".local/share/cuprate"));
|
||||
|
||||
let dir = cuprate_blockchain_dir();
|
||||
let dir = &*CUPRATE_BLOCKCHAIN_DIR;
|
||||
println!("cuprate_blockchain_dir: {dir:?}");
|
||||
assert!(dir.ends_with(".local/share/cuprate/blockchain"));
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::{borrow::Cow, path::Path};
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use cuprate_database::{config::SyncMode, resize::ResizeAlgorithm};
|
||||
use cuprate_helper::fs::cuprate_blockchain_dir;
|
||||
use cuprate_helper::fs::CUPRATE_BLOCKCHAIN_DIR;
|
||||
|
||||
// re-exports
|
||||
pub use cuprate_database_service::ReaderThreads;
|
||||
|
@ -38,7 +38,7 @@ impl ConfigBuilder {
|
|||
Self {
|
||||
db_directory: None,
|
||||
db_config: cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(
|
||||
cuprate_blockchain_dir(),
|
||||
&*CUPRATE_BLOCKCHAIN_DIR,
|
||||
)),
|
||||
reader_threads: None,
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ impl ConfigBuilder {
|
|||
///
|
||||
/// # Default values
|
||||
/// If [`ConfigBuilder::db_directory`] was not called,
|
||||
/// the default [`cuprate_blockchain_dir`] will be used.
|
||||
/// the default [`CUPRATE_BLOCKCHAIN_DIR`] will be used.
|
||||
///
|
||||
/// For all other values, [`Default::default`] is used.
|
||||
pub fn build(self) -> Config {
|
||||
|
@ -56,7 +56,7 @@ impl ConfigBuilder {
|
|||
// in `helper::fs`. No need to do them here.
|
||||
let db_directory = self
|
||||
.db_directory
|
||||
.unwrap_or_else(|| Cow::Borrowed(cuprate_blockchain_dir()));
|
||||
.unwrap_or_else(|| Cow::Borrowed(&*CUPRATE_BLOCKCHAIN_DIR));
|
||||
|
||||
let reader_threads = self.reader_threads.unwrap_or_default();
|
||||
let db_config = self
|
||||
|
@ -106,7 +106,7 @@ impl ConfigBuilder {
|
|||
#[must_use]
|
||||
pub fn fast(mut self) -> Self {
|
||||
self.db_config =
|
||||
cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(cuprate_blockchain_dir()))
|
||||
cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(&*CUPRATE_BLOCKCHAIN_DIR))
|
||||
.fast();
|
||||
|
||||
self.reader_threads = Some(ReaderThreads::OnePerThread);
|
||||
|
@ -120,7 +120,7 @@ impl ConfigBuilder {
|
|||
#[must_use]
|
||||
pub fn low_power(mut self) -> Self {
|
||||
self.db_config =
|
||||
cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(cuprate_blockchain_dir()))
|
||||
cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(&*CUPRATE_BLOCKCHAIN_DIR))
|
||||
.low_power();
|
||||
|
||||
self.reader_threads = Some(ReaderThreads::One);
|
||||
|
@ -130,7 +130,7 @@ impl ConfigBuilder {
|
|||
|
||||
impl Default for ConfigBuilder {
|
||||
fn default() -> Self {
|
||||
let db_directory = Cow::Borrowed(cuprate_blockchain_dir());
|
||||
let db_directory = Cow::Borrowed(&**CUPRATE_BLOCKCHAIN_DIR);
|
||||
Self {
|
||||
db_directory: Some(db_directory.clone()),
|
||||
db_config: cuprate_database::config::ConfigBuilder::new(db_directory),
|
||||
|
@ -161,7 +161,7 @@ impl Config {
|
|||
/// Create a new [`Config`] with sane default settings.
|
||||
///
|
||||
/// The [`cuprate_database::config::Config::db_directory`]
|
||||
/// will be set to [`cuprate_blockchain_dir`].
|
||||
/// will be set to [`CUPRATE_BLOCKCHAIN_DIR`].
|
||||
///
|
||||
/// All other values will be [`Default::default`].
|
||||
///
|
||||
|
@ -179,8 +179,8 @@ impl Config {
|
|||
///
|
||||
/// let config = Config::new();
|
||||
///
|
||||
/// assert_eq!(config.db_config.db_directory(), cuprate_blockchain_dir());
|
||||
/// assert!(config.db_config.db_file().starts_with(cuprate_blockchain_dir()));
|
||||
/// assert_eq!(config.db_config.db_directory(), &*CUPRATE_BLOCKCHAIN_DIR);
|
||||
/// assert!(config.db_config.db_file().starts_with(&*CUPRATE_BLOCKCHAIN_DIR));
|
||||
/// assert!(config.db_config.db_file().ends_with(DATABASE_DATA_FILENAME));
|
||||
/// assert_eq!(config.db_config.sync_mode, SyncMode::default());
|
||||
/// assert_eq!(config.db_config.resize_algorithm, ResizeAlgorithm::default());
|
||||
|
|
|
@ -268,7 +268,7 @@ mod test {
|
|||
use pretty_assertions::assert_eq;
|
||||
|
||||
use cuprate_database::{Env, EnvInner, TxRw};
|
||||
use cuprate_test_utils::data::{block_v16_tx0, block_v1_tx2, block_v9_tx3};
|
||||
use cuprate_test_utils::data::{BLOCK_V16_TX0, BLOCK_V1_TX2, BLOCK_V9_TX3};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -292,9 +292,9 @@ mod test {
|
|||
assert_all_tables_are_empty(&env);
|
||||
|
||||
let mut blocks = [
|
||||
block_v1_tx2().clone(),
|
||||
block_v9_tx3().clone(),
|
||||
block_v16_tx0().clone(),
|
||||
BLOCK_V1_TX2.clone(),
|
||||
BLOCK_V9_TX3.clone(),
|
||||
BLOCK_V16_TX0.clone(),
|
||||
];
|
||||
// HACK: `add_block()` asserts blocks with non-sequential heights
|
||||
// cannot be added, to get around this, manually edit the block height.
|
||||
|
@ -440,7 +440,7 @@ mod test {
|
|||
let tx_rw = env_inner.tx_rw().unwrap();
|
||||
let mut tables = env_inner.open_tables_mut(&tx_rw).unwrap();
|
||||
|
||||
let mut block = block_v9_tx3().clone();
|
||||
let mut block = BLOCK_V9_TX3.clone();
|
||||
|
||||
block.height = usize::try_from(u32::MAX).unwrap() + 1;
|
||||
add_block(&block, &mut tables).unwrap();
|
||||
|
@ -459,7 +459,7 @@ mod test {
|
|||
let tx_rw = env_inner.tx_rw().unwrap();
|
||||
let mut tables = env_inner.open_tables_mut(&tx_rw).unwrap();
|
||||
|
||||
let mut block = block_v9_tx3().clone();
|
||||
let mut block = BLOCK_V9_TX3.clone();
|
||||
// HACK: `add_block()` asserts blocks with non-sequential heights
|
||||
// cannot be added, to get around this, manually edit the block height.
|
||||
block.height = 0;
|
||||
|
|
|
@ -84,7 +84,7 @@ mod test {
|
|||
use pretty_assertions::assert_eq;
|
||||
|
||||
use cuprate_database::{Env, EnvInner, TxRw};
|
||||
use cuprate_test_utils::data::{block_v16_tx0, block_v1_tx2, block_v9_tx3};
|
||||
use cuprate_test_utils::data::{BLOCK_V16_TX0, BLOCK_V1_TX2, BLOCK_V9_TX3};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -108,9 +108,9 @@ mod test {
|
|||
assert_all_tables_are_empty(&env);
|
||||
|
||||
let mut blocks = [
|
||||
block_v1_tx2().clone(),
|
||||
block_v9_tx3().clone(),
|
||||
block_v16_tx0().clone(),
|
||||
BLOCK_V1_TX2.clone(),
|
||||
BLOCK_V9_TX3.clone(),
|
||||
BLOCK_V16_TX0.clone(),
|
||||
];
|
||||
let blocks_len = blocks.len();
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
//! ```rust
|
||||
//! use hex_literal::hex;
|
||||
//!
|
||||
//! use cuprate_test_utils::data::block_v16_tx0;
|
||||
//! use cuprate_test_utils::data::BLOCK_V16_TX0;
|
||||
//! use cuprate_blockchain::{
|
||||
//! cuprate_database::{
|
||||
//! ConcreteEnv,
|
||||
|
@ -83,7 +83,7 @@
|
|||
//! let mut tables = env_inner.open_tables_mut(&tx_rw)?;
|
||||
//!
|
||||
//! // Write a block to the database.
|
||||
//! let mut block = block_v16_tx0().clone();
|
||||
//! let mut block = BLOCK_V16_TX0.clone();
|
||||
//! # block.height = 0;
|
||||
//! add_block(&block, &mut tables)?;
|
||||
//!
|
||||
|
|
|
@ -322,7 +322,7 @@ mod test {
|
|||
use pretty_assertions::assert_eq;
|
||||
|
||||
use cuprate_database::{Env, EnvInner, TxRw};
|
||||
use cuprate_test_utils::data::{tx_v1_sig0, tx_v1_sig2, tx_v2_rct3};
|
||||
use cuprate_test_utils::data::{TX_V1_SIG0, TX_V1_SIG2, TX_V2_RCT3};
|
||||
|
||||
use crate::{
|
||||
tables::{OpenTables, Tables},
|
||||
|
@ -337,7 +337,7 @@ mod test {
|
|||
assert_all_tables_are_empty(&env);
|
||||
|
||||
// Monero `Transaction`, not database tx.
|
||||
let txs = [tx_v1_sig0(), tx_v1_sig2(), tx_v2_rct3()];
|
||||
let txs = [&*TX_V1_SIG0, &*TX_V1_SIG2, &*TX_V2_RCT3];
|
||||
|
||||
// Add transactions.
|
||||
let tx_ids = {
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
//! use tower::{Service, ServiceExt};
|
||||
//!
|
||||
//! use cuprate_types::{blockchain::{BlockchainReadRequest, BlockchainWriteRequest, BlockchainResponse}, Chain};
|
||||
//! use cuprate_test_utils::data::block_v16_tx0;
|
||||
//! use cuprate_test_utils::data::BLOCK_V16_TX0;
|
||||
//!
|
||||
//! use cuprate_blockchain::{
|
||||
//! cuprate_database::Env,
|
||||
|
@ -86,7 +86,7 @@
|
|||
//! let (mut read_handle, mut write_handle, _) = cuprate_blockchain::service::init(config)?;
|
||||
//!
|
||||
//! // Prepare a request to write block.
|
||||
//! let mut block = block_v16_tx0().clone();
|
||||
//! let mut block = BLOCK_V16_TX0.clone();
|
||||
//! # block.height = 0_usize; // must be 0th height or panic in `add_block()`
|
||||
//! let request = BlockchainWriteRequest::WriteBlock(block);
|
||||
//!
|
||||
|
|
|
@ -16,7 +16,7 @@ use pretty_assertions::assert_eq;
|
|||
use tower::{Service, ServiceExt};
|
||||
|
||||
use cuprate_database::{ConcreteEnv, DatabaseIter, DatabaseRo, Env, EnvInner, RuntimeError};
|
||||
use cuprate_test_utils::data::{block_v16_tx0, block_v1_tx2, block_v9_tx3};
|
||||
use cuprate_test_utils::data::{BLOCK_V16_TX0, BLOCK_V1_TX2, BLOCK_V9_TX3};
|
||||
use cuprate_types::{
|
||||
blockchain::{BlockchainReadRequest, BlockchainResponse, BlockchainWriteRequest},
|
||||
Chain, OutputOnChain, VerifiedBlockInformation,
|
||||
|
@ -61,7 +61,7 @@ fn init_service() -> (
|
|||
#[allow(clippy::future_not_send)] // INVARIANT: tests are using a single threaded runtime
|
||||
async fn test_template(
|
||||
// Which block(s) to add?
|
||||
block_fns: &[fn() -> &'static VerifiedBlockInformation],
|
||||
blocks: &[&VerifiedBlockInformation],
|
||||
// Total amount of generated coins after the block(s) have been added.
|
||||
cumulative_generated_coins: u64,
|
||||
// What are the table lengths be after the block(s) have been added?
|
||||
|
@ -76,8 +76,8 @@ async fn test_template(
|
|||
|
||||
// HACK: `add_block()` asserts blocks with non-sequential heights
|
||||
// cannot be added, to get around this, manually edit the block height.
|
||||
for (i, block_fn) in block_fns.iter().enumerate() {
|
||||
let mut block = block_fn().clone();
|
||||
for (i, block) in blocks.iter().enumerate() {
|
||||
let mut block = (*block).clone();
|
||||
block.height = i;
|
||||
|
||||
// Request a block to be written, assert it was written.
|
||||
|
@ -104,7 +104,7 @@ async fn test_template(
|
|||
get_block_extended_header_from_height(&0, &tables).unwrap(),
|
||||
));
|
||||
|
||||
let extended_block_header_1 = if block_fns.len() > 1 {
|
||||
let extended_block_header_1 = if blocks.len() > 1 {
|
||||
Ok(BlockchainResponse::BlockExtendedHeader(
|
||||
get_block_extended_header_from_height(&1, &tables).unwrap(),
|
||||
))
|
||||
|
@ -116,7 +116,7 @@ async fn test_template(
|
|||
get_block_info(&0, tables.block_infos()).unwrap().block_hash,
|
||||
));
|
||||
|
||||
let block_hash_1 = if block_fns.len() > 1 {
|
||||
let block_hash_1 = if blocks.len() > 1 {
|
||||
Ok(BlockchainResponse::BlockHash(
|
||||
get_block_info(&1, tables.block_infos()).unwrap().block_hash,
|
||||
))
|
||||
|
@ -128,7 +128,7 @@ async fn test_template(
|
|||
get_block_extended_header_from_height(&0, &tables).unwrap(),
|
||||
]));
|
||||
|
||||
let range_0_2 = if block_fns.len() >= 2 {
|
||||
let range_0_2 = if blocks.len() >= 2 {
|
||||
Ok(BlockchainResponse::BlockExtendedHeaderInRange(vec![
|
||||
get_block_extended_header_from_height(&0, &tables).unwrap(),
|
||||
get_block_extended_header_from_height(&1, &tables).unwrap(),
|
||||
|
@ -333,7 +333,7 @@ fn init_drop() {
|
|||
#[tokio::test]
|
||||
async fn v1_tx2() {
|
||||
test_template(
|
||||
&[block_v1_tx2],
|
||||
&[&*BLOCK_V1_TX2],
|
||||
14_535_350_982_449,
|
||||
AssertTableLen {
|
||||
block_infos: 1,
|
||||
|
@ -359,7 +359,7 @@ async fn v1_tx2() {
|
|||
#[tokio::test]
|
||||
async fn v9_tx3() {
|
||||
test_template(
|
||||
&[block_v9_tx3],
|
||||
&[&*BLOCK_V9_TX3],
|
||||
3_403_774_022_163,
|
||||
AssertTableLen {
|
||||
block_infos: 1,
|
||||
|
@ -385,7 +385,7 @@ async fn v9_tx3() {
|
|||
#[tokio::test]
|
||||
async fn v16_tx0() {
|
||||
test_template(
|
||||
&[block_v16_tx0],
|
||||
&[&*BLOCK_V16_TX0],
|
||||
600_000_000_000,
|
||||
AssertTableLen {
|
||||
block_infos: 1,
|
||||
|
|
|
@ -126,7 +126,7 @@ fn resize() {
|
|||
let (env, _tempdir) = tmp_concrete_env();
|
||||
|
||||
// Resize by the OS page size.
|
||||
let page_size = crate::resize::page_size();
|
||||
let page_size = *crate::resize::PAGE_SIZE;
|
||||
let old_size = env.current_map_size();
|
||||
env.resize_map(Some(ResizeAlgorithm::FixedBytes(page_size)));
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
//!
|
||||
//! # Page size
|
||||
//! All free functions in this module will
|
||||
//! return a multiple of the OS page size ([`page_size()`]),
|
||||
//! return a multiple of the OS page size ([`PAGE_SIZE`]),
|
||||
//! [LMDB will error](http://www.lmdb.tech/doc/group__mdb.html#gaa2506ec8dab3d969b0e609cd82e619e5)
|
||||
//! if this is not the case.
|
||||
//!
|
||||
|
@ -18,10 +18,10 @@
|
|||
//! All returned [`NonZeroUsize`] values of the free functions in this module
|
||||
//! (including [`ResizeAlgorithm::resize`]) uphold the following invariants:
|
||||
//! 1. It will always be `>=` the input `current_size_bytes`
|
||||
//! 2. It will always be a multiple of [`page_size()`]
|
||||
//! 2. It will always be a multiple of [`PAGE_SIZE`]
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use std::{num::NonZeroUsize, sync::OnceLock};
|
||||
use std::{num::NonZeroUsize, sync::LazyLock};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- ResizeAlgorithm
|
||||
/// The function/algorithm used by the
|
||||
|
@ -85,21 +85,14 @@ impl Default for ResizeAlgorithm {
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Free functions
|
||||
/// This function retrieves the system’s memory page size.
|
||||
/// This retrieves the system’s memory page size.
|
||||
///
|
||||
/// It is just [`page_size::get`](https://docs.rs/page_size) internally.
|
||||
///
|
||||
/// This caches the result, so this function is cheap after the 1st call.
|
||||
///
|
||||
/// # Panics
|
||||
/// This function will panic if the OS returns of page size of `0` (impossible?).
|
||||
#[inline]
|
||||
pub fn page_size() -> NonZeroUsize {
|
||||
/// Cached result of [`page_size()`].
|
||||
static PAGE_SIZE: OnceLock<NonZeroUsize> = OnceLock::new();
|
||||
*PAGE_SIZE
|
||||
.get_or_init(|| NonZeroUsize::new(page_size::get()).expect("page_size::get() returned 0"))
|
||||
}
|
||||
/// Accessing this [`LazyLock`] will panic if the OS returns of page size of `0` (impossible?).
|
||||
pub static PAGE_SIZE: LazyLock<NonZeroUsize> =
|
||||
LazyLock::new(|| NonZeroUsize::new(page_size::get()).expect("page_size::get() returned 0"));
|
||||
|
||||
/// Memory map resize closely matching `monerod`.
|
||||
///
|
||||
|
@ -122,7 +115,7 @@ pub fn page_size() -> NonZeroUsize {
|
|||
/// assert_eq!(monero(0).get(), N);
|
||||
///
|
||||
/// // Rounds up to nearest OS page size.
|
||||
/// assert_eq!(monero(1).get(), N + page_size().get());
|
||||
/// assert_eq!(monero(1).get(), N + PAGE_SIZE.get());
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
|
@ -143,7 +136,7 @@ pub fn monero(current_size_bytes: usize) -> NonZeroUsize {
|
|||
/// <https://github.com/monero-project/monero/blob/059028a30a8ae9752338a7897329fe8012a310d5/src/blockchain_db/lmdb/db_lmdb.cpp#L553>
|
||||
const ADD_SIZE: usize = 1_usize << 30;
|
||||
|
||||
let page_size = page_size().get();
|
||||
let page_size = PAGE_SIZE.get();
|
||||
let new_size_bytes = current_size_bytes + ADD_SIZE;
|
||||
|
||||
// Round up the new size to the
|
||||
|
@ -167,7 +160,7 @@ pub fn monero(current_size_bytes: usize) -> NonZeroUsize {
|
|||
///
|
||||
/// ```rust
|
||||
/// # use cuprate_database::resize::*;
|
||||
/// let page_size: usize = page_size().get();
|
||||
/// let page_size: usize = PAGE_SIZE.get();
|
||||
///
|
||||
/// // Anything below the page size will round up to the page size.
|
||||
/// for i in 0..=page_size {
|
||||
|
@ -190,7 +183,7 @@ pub fn monero(current_size_bytes: usize) -> NonZeroUsize {
|
|||
/// fixed_bytes(1, usize::MAX);
|
||||
/// ```
|
||||
pub fn fixed_bytes(current_size_bytes: usize, add_bytes: usize) -> NonZeroUsize {
|
||||
let page_size = page_size();
|
||||
let page_size = *PAGE_SIZE;
|
||||
let new_size_bytes = current_size_bytes + add_bytes;
|
||||
|
||||
// Guard against < page_size.
|
||||
|
@ -222,7 +215,7 @@ pub fn fixed_bytes(current_size_bytes: usize, add_bytes: usize) -> NonZeroUsize
|
|||
///
|
||||
/// ```rust
|
||||
/// # use cuprate_database::resize::*;
|
||||
/// let page_size: usize = page_size().get();
|
||||
/// let page_size: usize = PAGE_SIZE.get();
|
||||
///
|
||||
/// // Anything below the page size will round up to the page size.
|
||||
/// for i in 0..=page_size {
|
||||
|
@ -265,7 +258,7 @@ pub fn percent(current_size_bytes: usize, percent: f32) -> NonZeroUsize {
|
|||
_ => 1.0,
|
||||
};
|
||||
|
||||
let page_size = page_size();
|
||||
let page_size = *PAGE_SIZE;
|
||||
|
||||
// INVARIANT: Allow `f32` <-> `usize` casting, we handle all cases.
|
||||
#[allow(
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
//! let tx: Transaction = Transaction::read(&mut TX_E57440).unwrap();
|
||||
//! ```
|
||||
//!
|
||||
//! ## Functions
|
||||
//! The free functions provide access to typed data found in `cuprate_types`:
|
||||
//! ## Statics
|
||||
//! The statics provide access to typed data found in `cuprate_types`:
|
||||
//! ```rust
|
||||
//! # use cuprate_test_utils::data::*;
|
||||
//! use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation};
|
||||
//!
|
||||
//! let block: VerifiedBlockInformation = block_v16_tx0().clone();
|
||||
//! let tx: VerifiedTransactionInformation = tx_v1_sig0().clone();
|
||||
//! let block: VerifiedBlockInformation = BLOCK_V16_TX0.clone();
|
||||
//! let tx: VerifiedTransactionInformation = TX_V1_SIG0.clone();
|
||||
//! ```
|
||||
|
||||
mod constants;
|
||||
|
@ -31,7 +31,7 @@ pub use constants::{
|
|||
TX_9E3F73, TX_B6B439, TX_D7FEBD, TX_E2D393, TX_E57440,
|
||||
};
|
||||
|
||||
mod free;
|
||||
pub use free::{
|
||||
block_v16_tx0, block_v1_tx2, block_v9_tx3, tx_fee, tx_v1_sig0, tx_v1_sig2, tx_v2_rct3,
|
||||
mod statics;
|
||||
pub use statics::{
|
||||
tx_fee, BLOCK_V16_TX0, BLOCK_V1_TX2, BLOCK_V9_TX3, TX_V1_SIG0, TX_V1_SIG2, TX_V2_RCT3,
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! Free functions to access data.
|
||||
//! `static LazyLock`s to access data.
|
||||
|
||||
#![allow(
|
||||
const_item_mutation, // `R: Read` needs `&mut self`
|
||||
|
@ -6,7 +6,7 @@
|
|||
)]
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use std::sync::OnceLock;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use cuprate_helper::map::combine_low_high_bits_to_u128;
|
||||
use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation};
|
||||
|
@ -141,8 +141,7 @@ pub fn tx_fee(tx: &Transaction) -> u64 {
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Blocks
|
||||
/// Generate a block accessor function with this signature:
|
||||
/// `fn() -> &'static VerifiedBlockInformation`
|
||||
/// Generate a `static LazyLock<VerifiedBlockInformation>`.
|
||||
///
|
||||
/// This will use `VerifiedBlockMap` type above to do various
|
||||
/// checks on the input data and makes sure it seems correct.
|
||||
|
@ -153,9 +152,9 @@ pub fn tx_fee(tx: &Transaction) -> u64 {
|
|||
/// - Monero RPC (see cuprate_test_utils::rpc for this)
|
||||
///
|
||||
/// See below for actual usage.
|
||||
macro_rules! verified_block_information_fn {
|
||||
macro_rules! verified_block_information {
|
||||
(
|
||||
fn_name: $fn_name:ident, // Name of the function created
|
||||
name: $name:ident, // Name of the `LazyLock` created
|
||||
block_blob: $block_blob:ident, // Block blob ([u8], found in `constants.rs`)
|
||||
tx_blobs: [$($tx_blob:ident),*], // Array of contained transaction blobs
|
||||
pow_hash: $pow_hash:literal, // PoW hash as a string literal
|
||||
|
@ -183,7 +182,7 @@ macro_rules! verified_block_information_fn {
|
|||
#[doc = "# use hex_literal::hex;"]
|
||||
#[doc = "use cuprate_helper::map::combine_low_high_bits_to_u128;"]
|
||||
#[doc = ""]
|
||||
#[doc = concat!("let block = ", stringify!($fn_name), "();")]
|
||||
#[doc = concat!("let block = &*", stringify!($name), ";")]
|
||||
#[doc = concat!("assert_eq!(&block.block.serialize(), ", stringify!($block_blob), ");")]
|
||||
#[doc = concat!("assert_eq!(block.pow_hash, hex!(\"", $pow_hash, "\"));")]
|
||||
#[doc = concat!("assert_eq!(block.height, ", $height, ");")]
|
||||
|
@ -201,28 +200,25 @@ macro_rules! verified_block_information_fn {
|
|||
"));"
|
||||
)]
|
||||
/// ```
|
||||
pub fn $fn_name() -> &'static VerifiedBlockInformation {
|
||||
static BLOCK: OnceLock<VerifiedBlockInformation> = OnceLock::new();
|
||||
BLOCK.get_or_init(|| {
|
||||
VerifiedBlockMap {
|
||||
block_blob: $block_blob,
|
||||
pow_hash: hex!($pow_hash),
|
||||
height: $height,
|
||||
generated_coins: $generated_coins,
|
||||
weight: $weight,
|
||||
long_term_weight: $long_term_weight,
|
||||
cumulative_difficulty_low: $cumulative_difficulty_low,
|
||||
cumulative_difficulty_high: $cumulative_difficulty_high,
|
||||
txs: &[$($tx_blob),*],
|
||||
}
|
||||
.into_verified()
|
||||
})
|
||||
}
|
||||
pub static $name: LazyLock<VerifiedBlockInformation> = LazyLock::new(|| {
|
||||
VerifiedBlockMap {
|
||||
block_blob: $block_blob,
|
||||
pow_hash: hex!($pow_hash),
|
||||
height: $height,
|
||||
generated_coins: $generated_coins,
|
||||
weight: $weight,
|
||||
long_term_weight: $long_term_weight,
|
||||
cumulative_difficulty_low: $cumulative_difficulty_low,
|
||||
cumulative_difficulty_high: $cumulative_difficulty_high,
|
||||
txs: &[$($tx_blob),*],
|
||||
}
|
||||
.into_verified()
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
verified_block_information_fn! {
|
||||
fn_name: block_v1_tx2,
|
||||
verified_block_information! {
|
||||
name: BLOCK_V1_TX2,
|
||||
block_blob: BLOCK_5ECB7E,
|
||||
tx_blobs: [TX_2180A8, TX_D7FEBD],
|
||||
pow_hash: "c960d540000459480560b7816de968c7470083e5874e10040bdd4cc501000000",
|
||||
|
@ -235,8 +231,8 @@ verified_block_information_fn! {
|
|||
tx_len: 2,
|
||||
}
|
||||
|
||||
verified_block_information_fn! {
|
||||
fn_name: block_v9_tx3,
|
||||
verified_block_information! {
|
||||
name: BLOCK_V9_TX3,
|
||||
block_blob: BLOCK_F91043,
|
||||
tx_blobs: [TX_E2D393, TX_E57440, TX_B6B439],
|
||||
pow_hash: "7c78b5b67a112a66ea69ea51477492057dba9cfeaa2942ee7372c61800000000",
|
||||
|
@ -249,8 +245,8 @@ verified_block_information_fn! {
|
|||
tx_len: 3,
|
||||
}
|
||||
|
||||
verified_block_information_fn! {
|
||||
fn_name: block_v16_tx0,
|
||||
verified_block_information! {
|
||||
name: BLOCK_V16_TX0,
|
||||
block_blob: BLOCK_43BD1F,
|
||||
tx_blobs: [],
|
||||
pow_hash: "10b473b5d097d6bfa0656616951840724dfe38c6fb9c4adf8158800300000000",
|
||||
|
@ -264,13 +260,12 @@ verified_block_information_fn! {
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Transactions
|
||||
/// Generate a transaction accessor function with this signature:
|
||||
/// `fn() -> &'static VerifiedTransactionInformation`
|
||||
/// Generate a `const LazyLock<VerifiedTransactionInformation>`.
|
||||
///
|
||||
/// Same as [`verified_block_information_fn`] but for transactions.
|
||||
macro_rules! transaction_verification_data_fn {
|
||||
/// Same as [`verified_block_information`] but for transactions.
|
||||
macro_rules! transaction_verification_data {
|
||||
(
|
||||
fn_name: $fn_name:ident, // Name of the function created
|
||||
name: $name:ident, // Name of the `LazyLock` created
|
||||
tx_blobs: $tx_blob:ident, // Transaction blob ([u8], found in `constants.rs`)
|
||||
weight: $weight:literal, // Transaction weight
|
||||
hash: $hash:literal, // Transaction hash as a string literal
|
||||
|
@ -280,35 +275,34 @@ macro_rules! transaction_verification_data_fn {
|
|||
/// ```rust
|
||||
#[doc = "# use cuprate_test_utils::data::*;"]
|
||||
#[doc = "# use hex_literal::hex;"]
|
||||
#[doc = concat!("let tx = ", stringify!($fn_name), "();")]
|
||||
#[doc = concat!("let tx = &*", stringify!($name), ";")]
|
||||
#[doc = concat!("assert_eq!(&tx.tx.serialize(), ", stringify!($tx_blob), ");")]
|
||||
#[doc = concat!("assert_eq!(tx.tx_blob, ", stringify!($tx_blob), ");")]
|
||||
#[doc = concat!("assert_eq!(tx.tx_weight, ", $weight, ");")]
|
||||
#[doc = concat!("assert_eq!(tx.tx_hash, hex!(\"", $hash, "\"));")]
|
||||
/// ```
|
||||
pub fn $fn_name() -> &'static VerifiedTransactionInformation {
|
||||
static TX: OnceLock<VerifiedTransactionInformation> = OnceLock::new();
|
||||
TX.get_or_init(|| to_tx_verification_data($tx_blob))
|
||||
}
|
||||
pub static $name: LazyLock<VerifiedTransactionInformation> = LazyLock::new(|| {
|
||||
to_tx_verification_data($tx_blob)
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
transaction_verification_data_fn! {
|
||||
fn_name: tx_v1_sig0,
|
||||
transaction_verification_data! {
|
||||
name: TX_V1_SIG0,
|
||||
tx_blobs: TX_3BC7FF,
|
||||
weight: 248,
|
||||
hash: "3bc7ff015b227e7313cc2e8668bfbb3f3acbee274a9c201d6211cf681b5f6bb1",
|
||||
}
|
||||
|
||||
transaction_verification_data_fn! {
|
||||
fn_name: tx_v1_sig2,
|
||||
transaction_verification_data! {
|
||||
name: TX_V1_SIG2,
|
||||
tx_blobs: TX_9E3F73,
|
||||
weight: 448,
|
||||
hash: "9e3f73e66d7c7293af59c59c1ff5d6aae047289f49e5884c66caaf4aea49fb34",
|
||||
}
|
||||
|
||||
transaction_verification_data_fn! {
|
||||
fn_name: tx_v2_rct3,
|
||||
transaction_verification_data! {
|
||||
name: TX_V2_RCT3,
|
||||
tx_blobs: TX_84D48D,
|
||||
weight: 2743,
|
||||
hash: "84d48dc11ec91950f8b70a85af9db91fe0c8abef71ef5db08304f7344b99ea66",
|
||||
|
@ -328,7 +322,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn block_same_as_rpc() {
|
||||
let rpc = HttpRpcClient::new(None).await;
|
||||
for block in [block_v1_tx2(), block_v9_tx3(), block_v16_tx0()] {
|
||||
for block in [&*BLOCK_V1_TX2, &*BLOCK_V9_TX3, &*BLOCK_V16_TX0] {
|
||||
println!("block_height: {}", block.height);
|
||||
let block_rpc = rpc.get_verified_block_information(block.height).await;
|
||||
assert_eq!(block, &block_rpc);
|
||||
|
@ -342,16 +336,12 @@ mod tests {
|
|||
async fn tx_same_as_rpc() {
|
||||
let rpc = HttpRpcClient::new(None).await;
|
||||
|
||||
let mut txs = [block_v1_tx2(), block_v9_tx3(), block_v16_tx0()]
|
||||
let mut txs = [&*BLOCK_V1_TX2, &*BLOCK_V9_TX3, &*BLOCK_V16_TX0]
|
||||
.into_iter()
|
||||
.flat_map(|block| block.txs.iter().cloned())
|
||||
.collect::<Vec<VerifiedTransactionInformation>>();
|
||||
|
||||
txs.extend([
|
||||
tx_v1_sig0().clone(),
|
||||
tx_v1_sig2().clone(),
|
||||
tx_v2_rct3().clone(),
|
||||
]);
|
||||
txs.extend([TX_V1_SIG0.clone(), TX_V1_SIG2.clone(), TX_V2_RCT3.clone()]);
|
||||
|
||||
for tx in txs {
|
||||
println!("tx_hash: {:?}", tx.tx_hash);
|
Loading…
Reference in a new issue