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:
hinto-janai 2024-08-20 17:53:32 -04:00 committed by GitHub
parent 59adf6dcf8
commit aeb070ae8d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 186 additions and 227 deletions

View file

@ -1,36 +1,27 @@
use std::sync::OnceLock;
/// Decomposed amount table.
///
static DECOMPOSED_AMOUNTS: OnceLock<[u64; 172]> = OnceLock::new();
#[rustfmt::skip] #[rustfmt::skip]
pub fn decomposed_amounts() -> &'static [u64; 172] { /// Decomposed amount table.
DECOMPOSED_AMOUNTS.get_or_init(|| { pub static DECOMPOSED_AMOUNTS: [u64; 172] = [
[ 1, 2, 3, 4, 5, 6, 7, 8, 9,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 90,
10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900,
100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000,
1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000,
10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000, 100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000,
100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000,
1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000, 20000000, 30000000, 40000000, 50000000, 60000000, 70000000, 80000000, 90000000,
10000000, 20000000, 30000000, 40000000, 50000000, 60000000, 70000000, 80000000, 90000000, 100000000, 200000000, 300000000, 400000000, 500000000, 600000000, 700000000, 800000000, 900000000,
100000000, 200000000, 300000000, 400000000, 500000000, 600000000, 700000000, 800000000, 900000000, 1000000000, 2000000000, 3000000000, 4000000000, 5000000000, 6000000000, 7000000000, 8000000000, 9000000000,
1000000000, 2000000000, 3000000000, 4000000000, 5000000000, 6000000000, 7000000000, 8000000000, 9000000000, 10000000000, 20000000000, 30000000000, 40000000000, 50000000000, 60000000000, 70000000000, 80000000000, 90000000000,
10000000000, 20000000000, 30000000000, 40000000000, 50000000000, 60000000000, 70000000000, 80000000000, 90000000000, 100000000000, 200000000000, 300000000000, 400000000000, 500000000000, 600000000000, 700000000000, 800000000000, 900000000000,
100000000000, 200000000000, 300000000000, 400000000000, 500000000000, 600000000000, 700000000000, 800000000000, 900000000000, 1000000000000, 2000000000000, 3000000000000, 4000000000000, 5000000000000, 6000000000000, 7000000000000, 8000000000000, 9000000000000,
1000000000000, 2000000000000, 3000000000000, 4000000000000, 5000000000000, 6000000000000, 7000000000000, 8000000000000, 9000000000000, 10000000000000, 20000000000000, 30000000000000, 40000000000000, 50000000000000, 60000000000000, 70000000000000, 80000000000000, 90000000000000,
10000000000000, 20000000000000, 30000000000000, 40000000000000, 50000000000000, 60000000000000, 70000000000000, 80000000000000, 90000000000000, 100000000000000, 200000000000000, 300000000000000, 400000000000000, 500000000000000, 600000000000000, 700000000000000, 800000000000000, 900000000000000,
100000000000000, 200000000000000, 300000000000000, 400000000000000, 500000000000000, 600000000000000, 700000000000000, 800000000000000, 900000000000000, 1000000000000000, 2000000000000000, 3000000000000000, 4000000000000000, 5000000000000000, 6000000000000000, 7000000000000000, 8000000000000000, 9000000000000000,
1000000000000000, 2000000000000000, 3000000000000000, 4000000000000000, 5000000000000000, 6000000000000000, 7000000000000000, 8000000000000000, 9000000000000000, 10000000000000000, 20000000000000000, 30000000000000000, 40000000000000000, 50000000000000000, 60000000000000000, 70000000000000000, 80000000000000000, 90000000000000000,
10000000000000000, 20000000000000000, 30000000000000000, 40000000000000000, 50000000000000000, 60000000000000000, 70000000000000000, 80000000000000000, 90000000000000000, 100000000000000000, 200000000000000000, 300000000000000000, 400000000000000000, 500000000000000000, 600000000000000000, 700000000000000000, 800000000000000000, 900000000000000000,
100000000000000000, 200000000000000000, 300000000000000000, 400000000000000000, 500000000000000000, 600000000000000000, 700000000000000000, 800000000000000000, 900000000000000000, 1000000000000000000, 2000000000000000000, 3000000000000000000, 4000000000000000000, 5000000000000000000, 6000000000000000000, 7000000000000000000, 8000000000000000000, 9000000000000000000,
1000000000000000000, 2000000000000000000, 3000000000000000000, 4000000000000000000, 5000000000000000000, 6000000000000000000, 7000000000000000000, 8000000000000000000, 9000000000000000000, 10000000000000000000
10000000000000000000 ];
]
})
}
/// Checks that an output amount is decomposed. /// 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> /// ref: <https://monero-book.cuprate.org/consensus_rules/blocks/miner_tx.html#output-amounts>
#[inline] #[inline]
pub fn is_decomposed_amount(amount: &u64) -> bool { pub fn is_decomposed_amount(amount: &u64) -> bool {
decomposed_amounts().binary_search(amount).is_ok() DECOMPOSED_AMOUNTS.binary_search(amount).is_ok()
} }
#[cfg(test)] #[cfg(test)]
@ -49,7 +40,7 @@ mod tests {
#[test] #[test]
fn decomposed_amounts_return_decomposed() { fn decomposed_amounts_return_decomposed() {
for amount in decomposed_amounts() { for amount in DECOMPOSED_AMOUNTS.iter() {
assert!(is_decomposed_amount(amount)) assert!(is_decomposed_amount(amount))
} }
} }

View file

@ -10,11 +10,11 @@ use proptest::{collection::vec, prelude::*};
use monero_serai::transaction::Output; use monero_serai::transaction::Output;
use super::*; use super::*;
use crate::decomposed_amount::decomposed_amounts; use crate::decomposed_amount::DECOMPOSED_AMOUNTS;
#[test] #[test]
fn test_check_output_amount_v1() { 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()) assert!(check_output_amount_v1(*amount, &HardFork::V2).is_ok())
} }

View file

@ -4,7 +4,7 @@
//! Note that this module's functions uses [`dirs`], //! Note that this module's functions uses [`dirs`],
//! which adheres to the XDG standard on Linux. //! 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, //! may change at runtime depending on environment variables,
//! for example: //! for example:
//! //!
@ -17,7 +17,7 @@
//! # if cfg!(target_os = "linux") { //! # if cfg!(target_os = "linux") {
//! std::env::set_var("XDG_CONFIG_HOME", "/custom/path"); //! std::env::set_var("XDG_CONFIG_HOME", "/custom/path");
//! assert_eq!( //! assert_eq!(
//! cuprate_config_dir().to_string_lossy(), //! CUPRATE_CONFIG_DIR.to_string_lossy(),
//! "/custom/path/cuprate" //! "/custom/path/cuprate"
//! ); //! );
//! # } //! # }
@ -28,10 +28,7 @@
//! - <https://docs.rs/dirs> //! - <https://docs.rs/dirs>
//---------------------------------------------------------------------------------------------------- Use //---------------------------------------------------------------------------------------------------- Use
use std::{ use std::{path::PathBuf, sync::LazyLock};
path::{Path, PathBuf},
sync::OnceLock,
};
//---------------------------------------------------------------------------------------------------- Const //---------------------------------------------------------------------------------------------------- Const
/// Cuprate's main directory. /// Cuprate's main directory.
@ -62,71 +59,59 @@ pub const CUPRATE_DIR: &str = {
}; };
//---------------------------------------------------------------------------------------------------- Directories //---------------------------------------------------------------------------------------------------- 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: /// This currently creates these directories:
/// - [`cuprate_cache_dir()`] /// - [`CUPRATE_CACHE_DIR`]
/// - [`cuprate_config_dir()`] /// - [`CUPRATE_CONFIG_DIR`]
/// - [`cuprate_data_dir()`] /// - [`CUPRATE_DATA_DIR`]
/// - [`cuprate_blockchain_dir()`] /// - [`CUPRATE_BLOCKCHAIN_DIR`]
/// macro_rules! impl_path_lazylock {
/// 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 {
($( ($(
$(#[$attr:meta])* // Documentation and any `derive`'s. $(#[$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. $dirs_fn:ident, // Name of the `dirs` function to use, the PATH prefix.
$sub_dirs:literal // Any sub-directories to add onto the PATH. $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. // the Cuprate directory string and return.
$(#[$attr])* $(#[$attr])*
pub fn $fn() -> &'static Path { pub static $name: LazyLock<PathBuf> = LazyLock::new(|| {
/// Local `OnceLock` containing the Path. // There's nothing we can do but panic if
static ONCE_LOCK: OnceLock<PathBuf> = OnceLock::new(); // 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(|| { // FIXME:
// There's nothing we can do but panic if // Consider a user who does `HOME=/ ./cuprated`
// we cannot acquire critical system directories. //
// // Should we say "that's stupid" and panic here?
// Although, this realistically won't panic on // Or should it be respected?
// normal systems for all OS's supported by `dirs`. // We really don't want a `rm -rf /` type of situation...
let mut path = dirs::$dirs_fn().unwrap(); assert!(
path.parent().is_some(),
"SAFETY: returned OS PATH was either root or empty, aborting"
);
// FIXME: // Returned OS PATH should be absolute, not relative.
// Consider a user who does `HOME=/ ./cuprated` assert!(path.is_absolute(), "SAFETY: returned OS PATH was not absolute");
//
// 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. // Unconditionally prefix with the top-level Cuprate directory.
assert!(path.is_absolute(), "SAFETY: returned OS PATH was not absolute"); path.push(CUPRATE_DIR);
// Unconditionally prefix with the top-level Cuprate directory. // Add any sub directories if specified in the macro.
path.push(CUPRATE_DIR); if !$sub_dirs.is_empty() {
path.push($sub_dirs);
}
// Add any sub directories if specified in the macro. path
if !$sub_dirs.is_empty() { });
path.push($sub_dirs);
}
path
})
}
)*}; )*};
} }
// Note that the `OnceLock`'s are prefixed with `__` to indicate: impl_path_lazylock! {
// 1. They're not really to be used directly
// 2. To avoid name conflicts
impl_path_oncelock_and_fn! {
/// Cuprate's cache directory. /// Cuprate's cache directory.
/// ///
/// This is the PATH used for any Cuprate cache files. /// 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\` | /// | Windows | `C:\Users\Alice\AppData\Local\Cuprate\` |
/// | macOS | `/Users/Alice/Library/Caches/Cuprate/` | /// | macOS | `/Users/Alice/Library/Caches/Cuprate/` |
/// | Linux | `/home/alice/.cache/cuprate/` | /// | Linux | `/home/alice/.cache/cuprate/` |
cuprate_cache_dir, CUPRATE_CACHE_DIR,
cache_dir, cache_dir,
"", "",
@ -149,7 +134,7 @@ impl_path_oncelock_and_fn! {
/// | Windows | `C:\Users\Alice\AppData\Roaming\Cuprate\` | /// | Windows | `C:\Users\Alice\AppData\Roaming\Cuprate\` |
/// | macOS | `/Users/Alice/Library/Application Support/Cuprate/` | /// | macOS | `/Users/Alice/Library/Application Support/Cuprate/` |
/// | Linux | `/home/alice/.config/cuprate/` | /// | Linux | `/home/alice/.config/cuprate/` |
cuprate_config_dir, CUPRATE_CONFIG_DIR,
config_dir, config_dir,
"", "",
@ -162,7 +147,7 @@ impl_path_oncelock_and_fn! {
/// | Windows | `C:\Users\Alice\AppData\Roaming\Cuprate\` | /// | Windows | `C:\Users\Alice\AppData\Roaming\Cuprate\` |
/// | macOS | `/Users/Alice/Library/Application Support/Cuprate/` | /// | macOS | `/Users/Alice/Library/Application Support/Cuprate/` |
/// | Linux | `/home/alice/.local/share/cuprate/` | /// | Linux | `/home/alice/.local/share/cuprate/` |
cuprate_data_dir, CUPRATE_DATA_DIR,
data_dir, data_dir,
"", "",
@ -175,7 +160,7 @@ impl_path_oncelock_and_fn! {
/// | Windows | `C:\Users\Alice\AppData\Roaming\Cuprate\blockchain\` | /// | Windows | `C:\Users\Alice\AppData\Roaming\Cuprate\blockchain\` |
/// | macOS | `/Users/Alice/Library/Application Support/Cuprate/blockchain/` | /// | macOS | `/Users/Alice/Library/Application Support/Cuprate/blockchain/` |
/// | Linux | `/home/alice/.local/share/cuprate/blockchain/` | /// | Linux | `/home/alice/.local/share/cuprate/blockchain/` |
cuprate_blockchain_dir, CUPRATE_BLOCKCHAIN_DIR,
data_dir, data_dir,
"blockchain", "blockchain",
} }
@ -192,58 +177,58 @@ mod test {
// - It must `ends_with()` the expected end PATH for the OS // - It must `ends_with()` the expected end PATH for the OS
#[test] #[test]
fn path_sanity_check() { fn path_sanity_check() {
assert!(cuprate_cache_dir().is_absolute()); assert!(CUPRATE_CACHE_DIR.is_absolute());
assert!(cuprate_config_dir().is_absolute()); assert!(CUPRATE_CONFIG_DIR.is_absolute());
assert!(cuprate_data_dir().is_absolute()); assert!(CUPRATE_DATA_DIR.is_absolute());
assert!(cuprate_blockchain_dir().is_absolute()); assert!(CUPRATE_BLOCKCHAIN_DIR.is_absolute());
if cfg!(target_os = "windows") { if cfg!(target_os = "windows") {
let dir = cuprate_cache_dir(); let dir = &*CUPRATE_CACHE_DIR;
println!("cuprate_cache_dir: {dir:?}"); println!("cuprate_cache_dir: {dir:?}");
assert!(dir.ends_with(r"AppData\Local\Cuprate")); assert!(dir.ends_with(r"AppData\Local\Cuprate"));
let dir = cuprate_config_dir(); let dir = &*CUPRATE_CONFIG_DIR;
println!("cuprate_config_dir: {dir:?}"); println!("cuprate_config_dir: {dir:?}");
assert!(dir.ends_with(r"AppData\Roaming\Cuprate")); assert!(dir.ends_with(r"AppData\Roaming\Cuprate"));
let dir = cuprate_data_dir(); let dir = &*CUPRATE_DATA_DIR;
println!("cuprate_data_dir: {dir:?}"); println!("cuprate_data_dir: {dir:?}");
assert!(dir.ends_with(r"AppData\Roaming\Cuprate")); assert!(dir.ends_with(r"AppData\Roaming\Cuprate"));
let dir = cuprate_blockchain_dir(); let dir = &*CUPRATE_BLOCKCHAIN_DIR;
println!("cuprate_blockchain_dir: {dir:?}"); println!("cuprate_blockchain_dir: {dir:?}");
assert!(dir.ends_with(r"AppData\Roaming\Cuprate\blockchain")); assert!(dir.ends_with(r"AppData\Roaming\Cuprate\blockchain"));
} else if cfg!(target_os = "macos") { } else if cfg!(target_os = "macos") {
let dir = cuprate_cache_dir(); let dir = &*CUPRATE_CACHE_DIR;
println!("cuprate_cache_dir: {dir:?}"); println!("cuprate_cache_dir: {dir:?}");
assert!(dir.ends_with("Library/Caches/Cuprate")); assert!(dir.ends_with("Library/Caches/Cuprate"));
let dir = cuprate_config_dir(); let dir = &*CUPRATE_CONFIG_DIR;
println!("cuprate_config_dir: {dir:?}"); println!("cuprate_config_dir: {dir:?}");
assert!(dir.ends_with("Library/Application Support/Cuprate")); assert!(dir.ends_with("Library/Application Support/Cuprate"));
let dir = cuprate_data_dir(); let dir = &*CUPRATE_DATA_DIR;
println!("cuprate_data_dir: {dir:?}"); println!("cuprate_data_dir: {dir:?}");
assert!(dir.ends_with("Library/Application Support/Cuprate")); assert!(dir.ends_with("Library/Application Support/Cuprate"));
let dir = cuprate_blockchain_dir(); let dir = &*CUPRATE_BLOCKCHAIN_DIR;
println!("cuprate_blockchain_dir: {dir:?}"); println!("cuprate_blockchain_dir: {dir:?}");
assert!(dir.ends_with("Library/Application Support/Cuprate/blockchain")); assert!(dir.ends_with("Library/Application Support/Cuprate/blockchain"));
} else { } else {
// Assumes Linux. // Assumes Linux.
let dir = cuprate_cache_dir(); let dir = &*CUPRATE_CACHE_DIR;
println!("cuprate_cache_dir: {dir:?}"); println!("cuprate_cache_dir: {dir:?}");
assert!(dir.ends_with(".cache/cuprate")); assert!(dir.ends_with(".cache/cuprate"));
let dir = cuprate_config_dir(); let dir = &*CUPRATE_CONFIG_DIR;
println!("cuprate_config_dir: {dir:?}"); println!("cuprate_config_dir: {dir:?}");
assert!(dir.ends_with(".config/cuprate")); assert!(dir.ends_with(".config/cuprate"));
let dir = cuprate_data_dir(); let dir = &*CUPRATE_DATA_DIR;
println!("cuprate_data_dir: {dir:?}"); println!("cuprate_data_dir: {dir:?}");
assert!(dir.ends_with(".local/share/cuprate")); assert!(dir.ends_with(".local/share/cuprate"));
let dir = cuprate_blockchain_dir(); let dir = &*CUPRATE_BLOCKCHAIN_DIR;
println!("cuprate_blockchain_dir: {dir:?}"); println!("cuprate_blockchain_dir: {dir:?}");
assert!(dir.ends_with(".local/share/cuprate/blockchain")); assert!(dir.ends_with(".local/share/cuprate/blockchain"));
} }

View file

@ -7,7 +7,7 @@ use std::{borrow::Cow, path::Path};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use cuprate_database::{config::SyncMode, resize::ResizeAlgorithm}; use cuprate_database::{config::SyncMode, resize::ResizeAlgorithm};
use cuprate_helper::fs::cuprate_blockchain_dir; use cuprate_helper::fs::CUPRATE_BLOCKCHAIN_DIR;
// re-exports // re-exports
pub use cuprate_database_service::ReaderThreads; pub use cuprate_database_service::ReaderThreads;
@ -38,7 +38,7 @@ impl ConfigBuilder {
Self { Self {
db_directory: None, db_directory: None,
db_config: cuprate_database::config::ConfigBuilder::new(Cow::Borrowed( db_config: cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(
cuprate_blockchain_dir(), &*CUPRATE_BLOCKCHAIN_DIR,
)), )),
reader_threads: None, reader_threads: None,
} }
@ -48,7 +48,7 @@ impl ConfigBuilder {
/// ///
/// # Default values /// # Default values
/// If [`ConfigBuilder::db_directory`] was not called, /// 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. /// For all other values, [`Default::default`] is used.
pub fn build(self) -> Config { pub fn build(self) -> Config {
@ -56,7 +56,7 @@ impl ConfigBuilder {
// in `helper::fs`. No need to do them here. // in `helper::fs`. No need to do them here.
let db_directory = self let db_directory = self
.db_directory .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 reader_threads = self.reader_threads.unwrap_or_default();
let db_config = self let db_config = self
@ -106,7 +106,7 @@ impl ConfigBuilder {
#[must_use] #[must_use]
pub fn fast(mut self) -> Self { pub fn fast(mut self) -> Self {
self.db_config = self.db_config =
cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(cuprate_blockchain_dir())) cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(&*CUPRATE_BLOCKCHAIN_DIR))
.fast(); .fast();
self.reader_threads = Some(ReaderThreads::OnePerThread); self.reader_threads = Some(ReaderThreads::OnePerThread);
@ -120,7 +120,7 @@ impl ConfigBuilder {
#[must_use] #[must_use]
pub fn low_power(mut self) -> Self { pub fn low_power(mut self) -> Self {
self.db_config = 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(); .low_power();
self.reader_threads = Some(ReaderThreads::One); self.reader_threads = Some(ReaderThreads::One);
@ -130,7 +130,7 @@ impl ConfigBuilder {
impl Default for ConfigBuilder { impl Default for ConfigBuilder {
fn default() -> Self { fn default() -> Self {
let db_directory = Cow::Borrowed(cuprate_blockchain_dir()); let db_directory = Cow::Borrowed(&**CUPRATE_BLOCKCHAIN_DIR);
Self { Self {
db_directory: Some(db_directory.clone()), db_directory: Some(db_directory.clone()),
db_config: cuprate_database::config::ConfigBuilder::new(db_directory), db_config: cuprate_database::config::ConfigBuilder::new(db_directory),
@ -161,7 +161,7 @@ impl Config {
/// Create a new [`Config`] with sane default settings. /// Create a new [`Config`] with sane default settings.
/// ///
/// The [`cuprate_database::config::Config::db_directory`] /// 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`]. /// All other values will be [`Default::default`].
/// ///
@ -179,8 +179,8 @@ impl Config {
/// ///
/// let config = Config::new(); /// let config = Config::new();
/// ///
/// assert_eq!(config.db_config.db_directory(), 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().starts_with(&*CUPRATE_BLOCKCHAIN_DIR));
/// assert!(config.db_config.db_file().ends_with(DATABASE_DATA_FILENAME)); /// 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.sync_mode, SyncMode::default());
/// assert_eq!(config.db_config.resize_algorithm, ResizeAlgorithm::default()); /// assert_eq!(config.db_config.resize_algorithm, ResizeAlgorithm::default());

View file

@ -268,7 +268,7 @@ mod test {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use cuprate_database::{Env, EnvInner, TxRw}; 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::*; use super::*;
@ -292,9 +292,9 @@ mod test {
assert_all_tables_are_empty(&env); assert_all_tables_are_empty(&env);
let mut blocks = [ let mut blocks = [
block_v1_tx2().clone(), BLOCK_V1_TX2.clone(),
block_v9_tx3().clone(), BLOCK_V9_TX3.clone(),
block_v16_tx0().clone(), BLOCK_V16_TX0.clone(),
]; ];
// HACK: `add_block()` asserts blocks with non-sequential heights // HACK: `add_block()` asserts blocks with non-sequential heights
// cannot be added, to get around this, manually edit the block height. // 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 tx_rw = env_inner.tx_rw().unwrap();
let mut tables = env_inner.open_tables_mut(&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; block.height = usize::try_from(u32::MAX).unwrap() + 1;
add_block(&block, &mut tables).unwrap(); add_block(&block, &mut tables).unwrap();
@ -459,7 +459,7 @@ mod test {
let tx_rw = env_inner.tx_rw().unwrap(); let tx_rw = env_inner.tx_rw().unwrap();
let mut tables = env_inner.open_tables_mut(&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 // HACK: `add_block()` asserts blocks with non-sequential heights
// cannot be added, to get around this, manually edit the block height. // cannot be added, to get around this, manually edit the block height.
block.height = 0; block.height = 0;

View file

@ -84,7 +84,7 @@ mod test {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use cuprate_database::{Env, EnvInner, TxRw}; 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::*; use super::*;
@ -108,9 +108,9 @@ mod test {
assert_all_tables_are_empty(&env); assert_all_tables_are_empty(&env);
let mut blocks = [ let mut blocks = [
block_v1_tx2().clone(), BLOCK_V1_TX2.clone(),
block_v9_tx3().clone(), BLOCK_V9_TX3.clone(),
block_v16_tx0().clone(), BLOCK_V16_TX0.clone(),
]; ];
let blocks_len = blocks.len(); let blocks_len = blocks.len();

View file

@ -54,7 +54,7 @@
//! ```rust //! ```rust
//! use hex_literal::hex; //! use hex_literal::hex;
//! //!
//! use cuprate_test_utils::data::block_v16_tx0; //! use cuprate_test_utils::data::BLOCK_V16_TX0;
//! use cuprate_blockchain::{ //! use cuprate_blockchain::{
//! cuprate_database::{ //! cuprate_database::{
//! ConcreteEnv, //! ConcreteEnv,
@ -83,7 +83,7 @@
//! let mut tables = env_inner.open_tables_mut(&tx_rw)?; //! let mut tables = env_inner.open_tables_mut(&tx_rw)?;
//! //!
//! // Write a block to the database. //! // Write a block to the database.
//! let mut block = block_v16_tx0().clone(); //! let mut block = BLOCK_V16_TX0.clone();
//! # block.height = 0; //! # block.height = 0;
//! add_block(&block, &mut tables)?; //! add_block(&block, &mut tables)?;
//! //!

View file

@ -322,7 +322,7 @@ mod test {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use cuprate_database::{Env, EnvInner, TxRw}; 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::{ use crate::{
tables::{OpenTables, Tables}, tables::{OpenTables, Tables},
@ -337,7 +337,7 @@ mod test {
assert_all_tables_are_empty(&env); assert_all_tables_are_empty(&env);
// Monero `Transaction`, not database tx. // 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. // Add transactions.
let tx_ids = { let tx_ids = {

View file

@ -66,7 +66,7 @@
//! use tower::{Service, ServiceExt}; //! use tower::{Service, ServiceExt};
//! //!
//! use cuprate_types::{blockchain::{BlockchainReadRequest, BlockchainWriteRequest, BlockchainResponse}, Chain}; //! 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::{ //! use cuprate_blockchain::{
//! cuprate_database::Env, //! cuprate_database::Env,
@ -86,7 +86,7 @@
//! let (mut read_handle, mut write_handle, _) = cuprate_blockchain::service::init(config)?; //! let (mut read_handle, mut write_handle, _) = cuprate_blockchain::service::init(config)?;
//! //!
//! // Prepare a request to write block. //! // 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()` //! # block.height = 0_usize; // must be 0th height or panic in `add_block()`
//! let request = BlockchainWriteRequest::WriteBlock(block); //! let request = BlockchainWriteRequest::WriteBlock(block);
//! //!

View file

@ -16,7 +16,7 @@ use pretty_assertions::assert_eq;
use tower::{Service, ServiceExt}; use tower::{Service, ServiceExt};
use cuprate_database::{ConcreteEnv, DatabaseIter, DatabaseRo, Env, EnvInner, RuntimeError}; 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::{ use cuprate_types::{
blockchain::{BlockchainReadRequest, BlockchainResponse, BlockchainWriteRequest}, blockchain::{BlockchainReadRequest, BlockchainResponse, BlockchainWriteRequest},
Chain, OutputOnChain, VerifiedBlockInformation, Chain, OutputOnChain, VerifiedBlockInformation,
@ -61,7 +61,7 @@ fn init_service() -> (
#[allow(clippy::future_not_send)] // INVARIANT: tests are using a single threaded runtime #[allow(clippy::future_not_send)] // INVARIANT: tests are using a single threaded runtime
async fn test_template( async fn test_template(
// Which block(s) to add? // Which block(s) to add?
block_fns: &[fn() -> &'static VerifiedBlockInformation], blocks: &[&VerifiedBlockInformation],
// Total amount of generated coins after the block(s) have been added. // Total amount of generated coins after the block(s) have been added.
cumulative_generated_coins: u64, cumulative_generated_coins: u64,
// What are the table lengths be after the block(s) have been added? // 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 // HACK: `add_block()` asserts blocks with non-sequential heights
// cannot be added, to get around this, manually edit the block height. // cannot be added, to get around this, manually edit the block height.
for (i, block_fn) in block_fns.iter().enumerate() { for (i, block) in blocks.iter().enumerate() {
let mut block = block_fn().clone(); let mut block = (*block).clone();
block.height = i; block.height = i;
// Request a block to be written, assert it was written. // 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(), 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( Ok(BlockchainResponse::BlockExtendedHeader(
get_block_extended_header_from_height(&1, &tables).unwrap(), 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, 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( Ok(BlockchainResponse::BlockHash(
get_block_info(&1, tables.block_infos()).unwrap().block_hash, 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(), 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![ Ok(BlockchainResponse::BlockExtendedHeaderInRange(vec![
get_block_extended_header_from_height(&0, &tables).unwrap(), get_block_extended_header_from_height(&0, &tables).unwrap(),
get_block_extended_header_from_height(&1, &tables).unwrap(), get_block_extended_header_from_height(&1, &tables).unwrap(),
@ -333,7 +333,7 @@ fn init_drop() {
#[tokio::test] #[tokio::test]
async fn v1_tx2() { async fn v1_tx2() {
test_template( test_template(
&[block_v1_tx2], &[&*BLOCK_V1_TX2],
14_535_350_982_449, 14_535_350_982_449,
AssertTableLen { AssertTableLen {
block_infos: 1, block_infos: 1,
@ -359,7 +359,7 @@ async fn v1_tx2() {
#[tokio::test] #[tokio::test]
async fn v9_tx3() { async fn v9_tx3() {
test_template( test_template(
&[block_v9_tx3], &[&*BLOCK_V9_TX3],
3_403_774_022_163, 3_403_774_022_163,
AssertTableLen { AssertTableLen {
block_infos: 1, block_infos: 1,
@ -385,7 +385,7 @@ async fn v9_tx3() {
#[tokio::test] #[tokio::test]
async fn v16_tx0() { async fn v16_tx0() {
test_template( test_template(
&[block_v16_tx0], &[&*BLOCK_V16_TX0],
600_000_000_000, 600_000_000_000,
AssertTableLen { AssertTableLen {
block_infos: 1, block_infos: 1,

View file

@ -126,7 +126,7 @@ fn resize() {
let (env, _tempdir) = tmp_concrete_env(); let (env, _tempdir) = tmp_concrete_env();
// Resize by the OS page size. // 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(); let old_size = env.current_map_size();
env.resize_map(Some(ResizeAlgorithm::FixedBytes(page_size))); env.resize_map(Some(ResizeAlgorithm::FixedBytes(page_size)));

View file

@ -10,7 +10,7 @@
//! //!
//! # Page size //! # Page size
//! All free functions in this module will //! 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) //! [LMDB will error](http://www.lmdb.tech/doc/group__mdb.html#gaa2506ec8dab3d969b0e609cd82e619e5)
//! if this is not the case. //! if this is not the case.
//! //!
@ -18,10 +18,10 @@
//! All returned [`NonZeroUsize`] values of the free functions in this module //! All returned [`NonZeroUsize`] values of the free functions in this module
//! (including [`ResizeAlgorithm::resize`]) uphold the following invariants: //! (including [`ResizeAlgorithm::resize`]) uphold the following invariants:
//! 1. It will always be `>=` the input `current_size_bytes` //! 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 //---------------------------------------------------------------------------------------------------- Import
use std::{num::NonZeroUsize, sync::OnceLock}; use std::{num::NonZeroUsize, sync::LazyLock};
//---------------------------------------------------------------------------------------------------- ResizeAlgorithm //---------------------------------------------------------------------------------------------------- ResizeAlgorithm
/// The function/algorithm used by the /// The function/algorithm used by the
@ -85,21 +85,14 @@ impl Default for ResizeAlgorithm {
} }
//---------------------------------------------------------------------------------------------------- Free functions //---------------------------------------------------------------------------------------------------- Free functions
/// This function retrieves the systems memory page size. /// This retrieves the systems memory page size.
/// ///
/// It is just [`page_size::get`](https://docs.rs/page_size) internally. /// 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 /// # Panics
/// This function will panic if the OS returns of page size of `0` (impossible?). /// Accessing this [`LazyLock`] will panic if the OS returns of page size of `0` (impossible?).
#[inline] pub static PAGE_SIZE: LazyLock<NonZeroUsize> =
pub fn page_size() -> NonZeroUsize { LazyLock::new(|| NonZeroUsize::new(page_size::get()).expect("page_size::get() returned 0"));
/// 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"))
}
/// Memory map resize closely matching `monerod`. /// Memory map resize closely matching `monerod`.
/// ///
@ -122,7 +115,7 @@ pub fn page_size() -> NonZeroUsize {
/// assert_eq!(monero(0).get(), N); /// assert_eq!(monero(0).get(), N);
/// ///
/// // Rounds up to nearest OS page size. /// // 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 /// # 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> /// <https://github.com/monero-project/monero/blob/059028a30a8ae9752338a7897329fe8012a310d5/src/blockchain_db/lmdb/db_lmdb.cpp#L553>
const ADD_SIZE: usize = 1_usize << 30; 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; let new_size_bytes = current_size_bytes + ADD_SIZE;
// Round up the new size to the // Round up the new size to the
@ -167,7 +160,7 @@ pub fn monero(current_size_bytes: usize) -> NonZeroUsize {
/// ///
/// ```rust /// ```rust
/// # use cuprate_database::resize::*; /// # 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. /// // Anything below the page size will round up to the page size.
/// for i in 0..=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); /// fixed_bytes(1, usize::MAX);
/// ``` /// ```
pub fn fixed_bytes(current_size_bytes: usize, add_bytes: usize) -> NonZeroUsize { 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; let new_size_bytes = current_size_bytes + add_bytes;
// Guard against < page_size. // Guard against < page_size.
@ -222,7 +215,7 @@ pub fn fixed_bytes(current_size_bytes: usize, add_bytes: usize) -> NonZeroUsize
/// ///
/// ```rust /// ```rust
/// # use cuprate_database::resize::*; /// # 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. /// // Anything below the page size will round up to the page size.
/// for i in 0..=page_size { /// for i in 0..=page_size {
@ -265,7 +258,7 @@ pub fn percent(current_size_bytes: usize, percent: f32) -> NonZeroUsize {
_ => 1.0, _ => 1.0,
}; };
let page_size = page_size(); let page_size = *PAGE_SIZE;
// INVARIANT: Allow `f32` <-> `usize` casting, we handle all cases. // INVARIANT: Allow `f32` <-> `usize` casting, we handle all cases.
#[allow( #[allow(

View file

@ -15,14 +15,14 @@
//! let tx: Transaction = Transaction::read(&mut TX_E57440).unwrap(); //! let tx: Transaction = Transaction::read(&mut TX_E57440).unwrap();
//! ``` //! ```
//! //!
//! ## Functions //! ## Statics
//! The free functions provide access to typed data found in `cuprate_types`: //! The statics provide access to typed data found in `cuprate_types`:
//! ```rust //! ```rust
//! # use cuprate_test_utils::data::*; //! # use cuprate_test_utils::data::*;
//! use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation}; //! use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation};
//! //!
//! let block: VerifiedBlockInformation = block_v16_tx0().clone(); //! let block: VerifiedBlockInformation = BLOCK_V16_TX0.clone();
//! let tx: VerifiedTransactionInformation = tx_v1_sig0().clone(); //! let tx: VerifiedTransactionInformation = TX_V1_SIG0.clone();
//! ``` //! ```
mod constants; mod constants;
@ -31,7 +31,7 @@ pub use constants::{
TX_9E3F73, TX_B6B439, TX_D7FEBD, TX_E2D393, TX_E57440, TX_9E3F73, TX_B6B439, TX_D7FEBD, TX_E2D393, TX_E57440,
}; };
mod free; mod statics;
pub use free::{ pub use statics::{
block_v16_tx0, block_v1_tx2, block_v9_tx3, tx_fee, tx_v1_sig0, tx_v1_sig2, tx_v2_rct3, tx_fee, BLOCK_V16_TX0, BLOCK_V1_TX2, BLOCK_V9_TX3, TX_V1_SIG0, TX_V1_SIG2, TX_V2_RCT3,
}; };

View file

@ -1,4 +1,4 @@
//! Free functions to access data. //! `static LazyLock`s to access data.
#![allow( #![allow(
const_item_mutation, // `R: Read` needs `&mut self` const_item_mutation, // `R: Read` needs `&mut self`
@ -6,7 +6,7 @@
)] )]
//---------------------------------------------------------------------------------------------------- Import //---------------------------------------------------------------------------------------------------- Import
use std::sync::OnceLock; use std::sync::LazyLock;
use cuprate_helper::map::combine_low_high_bits_to_u128; use cuprate_helper::map::combine_low_high_bits_to_u128;
use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation}; use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation};
@ -141,8 +141,7 @@ pub fn tx_fee(tx: &Transaction) -> u64 {
} }
//---------------------------------------------------------------------------------------------------- Blocks //---------------------------------------------------------------------------------------------------- Blocks
/// Generate a block accessor function with this signature: /// Generate a `static LazyLock<VerifiedBlockInformation>`.
/// `fn() -> &'static VerifiedBlockInformation`
/// ///
/// This will use `VerifiedBlockMap` type above to do various /// This will use `VerifiedBlockMap` type above to do various
/// checks on the input data and makes sure it seems correct. /// 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) /// - Monero RPC (see cuprate_test_utils::rpc for this)
/// ///
/// See below for actual usage. /// 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`) block_blob: $block_blob:ident, // Block blob ([u8], found in `constants.rs`)
tx_blobs: [$($tx_blob:ident),*], // Array of contained transaction blobs tx_blobs: [$($tx_blob:ident),*], // Array of contained transaction blobs
pow_hash: $pow_hash:literal, // PoW hash as a string literal 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 hex_literal::hex;"]
#[doc = "use cuprate_helper::map::combine_low_high_bits_to_u128;"] #[doc = "use cuprate_helper::map::combine_low_high_bits_to_u128;"]
#[doc = ""] #[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.block.serialize(), ", stringify!($block_blob), ");")]
#[doc = concat!("assert_eq!(block.pow_hash, hex!(\"", $pow_hash, "\"));")] #[doc = concat!("assert_eq!(block.pow_hash, hex!(\"", $pow_hash, "\"));")]
#[doc = concat!("assert_eq!(block.height, ", $height, ");")] #[doc = concat!("assert_eq!(block.height, ", $height, ");")]
@ -201,28 +200,25 @@ macro_rules! verified_block_information_fn {
"));" "));"
)] )]
/// ``` /// ```
pub fn $fn_name() -> &'static VerifiedBlockInformation { pub static $name: LazyLock<VerifiedBlockInformation> = LazyLock::new(|| {
static BLOCK: OnceLock<VerifiedBlockInformation> = OnceLock::new(); VerifiedBlockMap {
BLOCK.get_or_init(|| { block_blob: $block_blob,
VerifiedBlockMap { pow_hash: hex!($pow_hash),
block_blob: $block_blob, height: $height,
pow_hash: hex!($pow_hash), generated_coins: $generated_coins,
height: $height, weight: $weight,
generated_coins: $generated_coins, long_term_weight: $long_term_weight,
weight: $weight, cumulative_difficulty_low: $cumulative_difficulty_low,
long_term_weight: $long_term_weight, cumulative_difficulty_high: $cumulative_difficulty_high,
cumulative_difficulty_low: $cumulative_difficulty_low, txs: &[$($tx_blob),*],
cumulative_difficulty_high: $cumulative_difficulty_high, }
txs: &[$($tx_blob),*], .into_verified()
} });
.into_verified()
})
}
}; };
} }
verified_block_information_fn! { verified_block_information! {
fn_name: block_v1_tx2, name: BLOCK_V1_TX2,
block_blob: BLOCK_5ECB7E, block_blob: BLOCK_5ECB7E,
tx_blobs: [TX_2180A8, TX_D7FEBD], tx_blobs: [TX_2180A8, TX_D7FEBD],
pow_hash: "c960d540000459480560b7816de968c7470083e5874e10040bdd4cc501000000", pow_hash: "c960d540000459480560b7816de968c7470083e5874e10040bdd4cc501000000",
@ -235,8 +231,8 @@ verified_block_information_fn! {
tx_len: 2, tx_len: 2,
} }
verified_block_information_fn! { verified_block_information! {
fn_name: block_v9_tx3, name: BLOCK_V9_TX3,
block_blob: BLOCK_F91043, block_blob: BLOCK_F91043,
tx_blobs: [TX_E2D393, TX_E57440, TX_B6B439], tx_blobs: [TX_E2D393, TX_E57440, TX_B6B439],
pow_hash: "7c78b5b67a112a66ea69ea51477492057dba9cfeaa2942ee7372c61800000000", pow_hash: "7c78b5b67a112a66ea69ea51477492057dba9cfeaa2942ee7372c61800000000",
@ -249,8 +245,8 @@ verified_block_information_fn! {
tx_len: 3, tx_len: 3,
} }
verified_block_information_fn! { verified_block_information! {
fn_name: block_v16_tx0, name: BLOCK_V16_TX0,
block_blob: BLOCK_43BD1F, block_blob: BLOCK_43BD1F,
tx_blobs: [], tx_blobs: [],
pow_hash: "10b473b5d097d6bfa0656616951840724dfe38c6fb9c4adf8158800300000000", pow_hash: "10b473b5d097d6bfa0656616951840724dfe38c6fb9c4adf8158800300000000",
@ -264,13 +260,12 @@ verified_block_information_fn! {
} }
//---------------------------------------------------------------------------------------------------- Transactions //---------------------------------------------------------------------------------------------------- Transactions
/// Generate a transaction accessor function with this signature: /// Generate a `const LazyLock<VerifiedTransactionInformation>`.
/// `fn() -> &'static VerifiedTransactionInformation`
/// ///
/// Same as [`verified_block_information_fn`] but for transactions. /// Same as [`verified_block_information`] but for transactions.
macro_rules! transaction_verification_data_fn { 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`) tx_blobs: $tx_blob:ident, // Transaction blob ([u8], found in `constants.rs`)
weight: $weight:literal, // Transaction weight weight: $weight:literal, // Transaction weight
hash: $hash:literal, // Transaction hash as a string literal hash: $hash:literal, // Transaction hash as a string literal
@ -280,35 +275,34 @@ macro_rules! transaction_verification_data_fn {
/// ```rust /// ```rust
#[doc = "# use cuprate_test_utils::data::*;"] #[doc = "# use cuprate_test_utils::data::*;"]
#[doc = "# use hex_literal::hex;"] #[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.serialize(), ", stringify!($tx_blob), ");")]
#[doc = concat!("assert_eq!(tx.tx_blob, ", 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_weight, ", $weight, ");")]
#[doc = concat!("assert_eq!(tx.tx_hash, hex!(\"", $hash, "\"));")] #[doc = concat!("assert_eq!(tx.tx_hash, hex!(\"", $hash, "\"));")]
/// ``` /// ```
pub fn $fn_name() -> &'static VerifiedTransactionInformation { pub static $name: LazyLock<VerifiedTransactionInformation> = LazyLock::new(|| {
static TX: OnceLock<VerifiedTransactionInformation> = OnceLock::new(); to_tx_verification_data($tx_blob)
TX.get_or_init(|| to_tx_verification_data($tx_blob)) });
}
}; };
} }
transaction_verification_data_fn! { transaction_verification_data! {
fn_name: tx_v1_sig0, name: TX_V1_SIG0,
tx_blobs: TX_3BC7FF, tx_blobs: TX_3BC7FF,
weight: 248, weight: 248,
hash: "3bc7ff015b227e7313cc2e8668bfbb3f3acbee274a9c201d6211cf681b5f6bb1", hash: "3bc7ff015b227e7313cc2e8668bfbb3f3acbee274a9c201d6211cf681b5f6bb1",
} }
transaction_verification_data_fn! { transaction_verification_data! {
fn_name: tx_v1_sig2, name: TX_V1_SIG2,
tx_blobs: TX_9E3F73, tx_blobs: TX_9E3F73,
weight: 448, weight: 448,
hash: "9e3f73e66d7c7293af59c59c1ff5d6aae047289f49e5884c66caaf4aea49fb34", hash: "9e3f73e66d7c7293af59c59c1ff5d6aae047289f49e5884c66caaf4aea49fb34",
} }
transaction_verification_data_fn! { transaction_verification_data! {
fn_name: tx_v2_rct3, name: TX_V2_RCT3,
tx_blobs: TX_84D48D, tx_blobs: TX_84D48D,
weight: 2743, weight: 2743,
hash: "84d48dc11ec91950f8b70a85af9db91fe0c8abef71ef5db08304f7344b99ea66", hash: "84d48dc11ec91950f8b70a85af9db91fe0c8abef71ef5db08304f7344b99ea66",
@ -328,7 +322,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn block_same_as_rpc() { async fn block_same_as_rpc() {
let rpc = HttpRpcClient::new(None).await; 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); println!("block_height: {}", block.height);
let block_rpc = rpc.get_verified_block_information(block.height).await; let block_rpc = rpc.get_verified_block_information(block.height).await;
assert_eq!(block, &block_rpc); assert_eq!(block, &block_rpc);
@ -342,16 +336,12 @@ mod tests {
async fn tx_same_as_rpc() { async fn tx_same_as_rpc() {
let rpc = HttpRpcClient::new(None).await; 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() .into_iter()
.flat_map(|block| block.txs.iter().cloned()) .flat_map(|block| block.txs.iter().cloned())
.collect::<Vec<VerifiedTransactionInformation>>(); .collect::<Vec<VerifiedTransactionInformation>>();
txs.extend([ txs.extend([TX_V1_SIG0.clone(), TX_V1_SIG2.clone(), TX_V2_RCT3.clone()]);
tx_v1_sig0().clone(),
tx_v1_sig2().clone(),
tx_v2_rct3().clone(),
]);
for tx in txs { for tx in txs {
println!("tx_hash: {:?}", tx.tx_hash); println!("tx_hash: {:?}", tx.tx_hash);