mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-11-16 15:58:17 +00:00
lints: opt in manual lint crates (#263)
* cargo.toml: transfer existing lints * rpc/interface: lints * rpc/json-rpc: lints * rpc/types: lints * storage/blockchain: lints * rpc/types: fix lints * cargo.toml: fix lint group priority * storage/blockchain: fix lints * fix misc lints * storage/database: fixes * storage/txpool: opt in lints + fixes * types: opt in + fixes * helper: opt in + fixes * types: remove borsh * rpc/interface: fix test * test fixes * database: fix lints * fix lint * tabs -> spaces * blockchain: `config/` -> `config.rs`
This commit is contained in:
parent
b837d350a4
commit
eead49beb0
45 changed files with 240 additions and 742 deletions
44
Cargo.lock
generated
44
Cargo.lock
generated
|
@ -17,6 +17,12 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
|
@ -160,7 +166,7 @@ dependencies = [
|
|||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"miniz_oxide 0.7.3",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
@ -798,6 +804,7 @@ dependencies = [
|
|||
"cuprate-helper",
|
||||
"cuprate-json-rpc",
|
||||
"cuprate-rpc-types",
|
||||
"cuprate-test-utils",
|
||||
"futures",
|
||||
"paste",
|
||||
"serde",
|
||||
|
@ -813,12 +820,9 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"cuprate-epee-encoding",
|
||||
"cuprate-fixed-bytes",
|
||||
"cuprate-json-rpc",
|
||||
"cuprate-test-utils",
|
||||
"cuprate-types",
|
||||
"monero-serai",
|
||||
"paste",
|
||||
"pretty_assertions",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
@ -875,7 +879,6 @@ dependencies = [
|
|||
name = "cuprate-types"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"bytes",
|
||||
"cuprate-epee-encoding",
|
||||
"cuprate-fixed-bytes",
|
||||
|
@ -1082,12 +1085,12 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
|
|||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.30"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
|
||||
checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
"miniz_oxide 0.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1241,9 +1244,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.4.5"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab"
|
||||
checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205"
|
||||
dependencies = [
|
||||
"atomic-waker",
|
||||
"bytes",
|
||||
|
@ -1737,6 +1740,15 @@ dependencies = [
|
|||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
|
@ -2399,9 +2411,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.7.0"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
|
||||
checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
|
@ -2960,9 +2972,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
|||
|
||||
[[package]]
|
||||
name = "ureq"
|
||||
version = "2.10.0"
|
||||
version = "2.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72139d247e5f97a3eff96229a7ae85ead5328a39efe76f8bf5a06313d505b6ea"
|
||||
checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"flate2",
|
||||
|
@ -3085,9 +3097,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
|||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.26.3"
|
||||
version = "0.26.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd"
|
||||
checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
|
|
@ -279,13 +279,15 @@ upper_case_acronyms = "deny"
|
|||
# allow_attributes_without_reason = "deny"
|
||||
# missing_assert_message = "deny"
|
||||
# missing_docs_in_private_items = "deny"
|
||||
# undocumented_unsafe_blocks = "deny"
|
||||
undocumented_unsafe_blocks = "deny"
|
||||
# multiple_unsafe_ops_per_block = "deny"
|
||||
# single_char_lifetime_names = "deny"
|
||||
# wildcard_enum_match_arm = "deny"
|
||||
|
||||
[workspace.lints.rust]
|
||||
# Cold
|
||||
future_incompatible = { level = "deny", priority = -1 }
|
||||
nonstandard_style = { level = "deny", priority = -1 }
|
||||
absolute_paths_not_starting_with_crate = "deny"
|
||||
explicit_outlives_requirements = "deny"
|
||||
keyword_idents_2018 = "deny"
|
||||
|
@ -306,7 +308,7 @@ ambiguous_glob_imports = "deny"
|
|||
unused_unsafe = "deny"
|
||||
|
||||
# Warm
|
||||
let_underscore_drop = "deny"
|
||||
let_underscore = { level = "deny", priority = -1 }
|
||||
unreachable_pub = "deny"
|
||||
unused_qualifications = "deny"
|
||||
variant_size_differences = "deny"
|
||||
|
|
|
@ -40,3 +40,6 @@ target_os_lib = { package = "libc", version = "0.2.151", optional = true }
|
|||
|
||||
[dev-dependencies]
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
|
@ -19,7 +19,7 @@ pub struct InfallibleOneshotReceiver<T>(oneshot::Receiver<T>);
|
|||
|
||||
impl<T> From<oneshot::Receiver<T>> for InfallibleOneshotReceiver<T> {
|
||||
fn from(value: oneshot::Receiver<T>) -> Self {
|
||||
InfallibleOneshotReceiver(value)
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ where
|
|||
{
|
||||
let (tx, rx) = oneshot::channel();
|
||||
rayon::spawn(move || {
|
||||
let _ = tx.send(f());
|
||||
drop(tx.send(f()));
|
||||
});
|
||||
rx.await.expect("The sender must not be dropped")
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ mod test {
|
|||
#[tokio::test]
|
||||
// Assert that basic channel operations work.
|
||||
async fn infallible_oneshot_receiver() {
|
||||
let (tx, rx) = futures::channel::oneshot::channel::<String>();
|
||||
let (tx, rx) = oneshot::channel::<String>();
|
||||
let msg = "hello world!".to_string();
|
||||
|
||||
tx.send(msg.clone()).unwrap();
|
||||
|
@ -84,7 +84,7 @@ mod test {
|
|||
let barrier = Arc::new(Barrier::new(2));
|
||||
let task = |barrier: &Barrier| barrier.wait();
|
||||
|
||||
let b_2 = barrier.clone();
|
||||
let b_2 = Arc::clone(&barrier);
|
||||
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
|
||||
|
|
|
@ -49,6 +49,8 @@ pub type AtomicF64 = AtomicCell<f64>;
|
|||
//---------------------------------------------------------------------------------------------------- TESTS
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#![allow(clippy::float_cmp)]
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -190,72 +190,41 @@ 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());
|
||||
// Array of (PATH, expected_path_as_string).
|
||||
//
|
||||
// The different OS's will set the expected path below.
|
||||
let mut array = [
|
||||
(&*CUPRATE_CACHE_DIR, ""),
|
||||
(&*CUPRATE_CONFIG_DIR, ""),
|
||||
(&*CUPRATE_DATA_DIR, ""),
|
||||
(&*CUPRATE_BLOCKCHAIN_DIR, ""),
|
||||
(&*CUPRATE_TXPOOL_DIR, ""),
|
||||
];
|
||||
|
||||
if cfg!(target_os = "windows") {
|
||||
let dir = &*CUPRATE_CACHE_DIR;
|
||||
println!("cuprate_cache_dir: {dir:?}");
|
||||
assert!(dir.ends_with(r"AppData\Local\Cuprate"));
|
||||
|
||||
let dir = &*CUPRATE_CONFIG_DIR;
|
||||
println!("cuprate_config_dir: {dir:?}");
|
||||
assert!(dir.ends_with(r"AppData\Roaming\Cuprate"));
|
||||
|
||||
let dir = &*CUPRATE_DATA_DIR;
|
||||
println!("cuprate_data_dir: {dir:?}");
|
||||
assert!(dir.ends_with(r"AppData\Roaming\Cuprate"));
|
||||
|
||||
let dir = &*CUPRATE_BLOCKCHAIN_DIR;
|
||||
println!("cuprate_blockchain_dir: {dir:?}");
|
||||
assert!(dir.ends_with(r"AppData\Roaming\Cuprate\blockchain"));
|
||||
|
||||
let dir = &*CUPRATE_TXPOOL_DIR;
|
||||
println!("cuprate_txpool_dir: {dir:?}");
|
||||
assert!(dir.ends_with(r"AppData\Roaming\Cuprate\txpool"));
|
||||
array[0].1 = r"AppData\Local\Cuprate";
|
||||
array[1].1 = r"AppData\Roaming\Cuprate";
|
||||
array[2].1 = r"AppData\Roaming\Cuprate";
|
||||
array[3].1 = r"AppData\Roaming\Cuprate\blockchain";
|
||||
array[4].1 = r"AppData\Roaming\Cuprate\txpool";
|
||||
} else if cfg!(target_os = "macos") {
|
||||
let dir = &*CUPRATE_CACHE_DIR;
|
||||
println!("cuprate_cache_dir: {dir:?}");
|
||||
assert!(dir.ends_with("Library/Caches/Cuprate"));
|
||||
|
||||
let dir = &*CUPRATE_CONFIG_DIR;
|
||||
println!("cuprate_config_dir: {dir:?}");
|
||||
assert!(dir.ends_with("Library/Application Support/Cuprate"));
|
||||
|
||||
let dir = &*CUPRATE_DATA_DIR;
|
||||
println!("cuprate_data_dir: {dir:?}");
|
||||
assert!(dir.ends_with("Library/Application Support/Cuprate"));
|
||||
|
||||
let dir = &*CUPRATE_BLOCKCHAIN_DIR;
|
||||
println!("cuprate_blockchain_dir: {dir:?}");
|
||||
assert!(dir.ends_with("Library/Application Support/Cuprate/blockchain"));
|
||||
|
||||
let dir = &*CUPRATE_TXPOOL_DIR;
|
||||
println!("cuprate_txpool_dir: {dir:?}");
|
||||
assert!(dir.ends_with("Library/Application Support/Cuprate/txpool"));
|
||||
array[0].1 = "Library/Caches/Cuprate";
|
||||
array[1].1 = "Library/Application Support/Cuprate";
|
||||
array[2].1 = "Library/Application Support/Cuprate";
|
||||
array[3].1 = "Library/Application Support/Cuprate/blockchain";
|
||||
array[4].1 = "Library/Application Support/Cuprate/txpool";
|
||||
} else {
|
||||
// Assumes Linux.
|
||||
let dir = &*CUPRATE_CACHE_DIR;
|
||||
println!("cuprate_cache_dir: {dir:?}");
|
||||
assert!(dir.ends_with(".cache/cuprate"));
|
||||
array[0].1 = ".cache/cuprate";
|
||||
array[1].1 = ".config/cuprate";
|
||||
array[2].1 = ".local/share/cuprate";
|
||||
array[3].1 = ".local/share/cuprate/blockchain";
|
||||
array[4].1 = ".local/share/cuprate/txpool";
|
||||
};
|
||||
|
||||
let dir = &*CUPRATE_CONFIG_DIR;
|
||||
println!("cuprate_config_dir: {dir:?}");
|
||||
assert!(dir.ends_with(".config/cuprate"));
|
||||
|
||||
let dir = &*CUPRATE_DATA_DIR;
|
||||
println!("cuprate_data_dir: {dir:?}");
|
||||
assert!(dir.ends_with(".local/share/cuprate"));
|
||||
|
||||
let dir = &*CUPRATE_BLOCKCHAIN_DIR;
|
||||
println!("cuprate_blockchain_dir: {dir:?}");
|
||||
assert!(dir.ends_with(".local/share/cuprate/blockchain"));
|
||||
|
||||
let dir = &*CUPRATE_TXPOOL_DIR;
|
||||
println!("cuprate_txpool_dir: {dir:?}");
|
||||
assert!(dir.ends_with(".local/share/cuprate/txpool"));
|
||||
for (path, expected) in array {
|
||||
assert!(path.is_absolute());
|
||||
assert!(path.ends_with(expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +1,4 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
//---------------------------------------------------------------------------------------------------- Lints
|
||||
#![allow(clippy::len_zero, clippy::type_complexity, clippy::module_inception)]
|
||||
#![deny(nonstandard_style, deprecated, missing_docs, unused_mut)]
|
||||
#![forbid(
|
||||
unused_unsafe,
|
||||
future_incompatible,
|
||||
break_with_label_and_loop,
|
||||
coherence_leak_check,
|
||||
duplicate_macro_attributes,
|
||||
exported_private_dependencies,
|
||||
for_loops_over_fallibles,
|
||||
large_assignments,
|
||||
overlapping_range_endpoints,
|
||||
// private_in_public,
|
||||
semicolon_in_expressions_from_macros,
|
||||
redundant_semicolons,
|
||||
unconditional_recursion,
|
||||
unreachable_patterns,
|
||||
unused_allocation,
|
||||
unused_braces,
|
||||
unused_comparisons,
|
||||
unused_doc_comments,
|
||||
unused_parens,
|
||||
unused_labels,
|
||||
while_true,
|
||||
keyword_idents,
|
||||
non_ascii_idents,
|
||||
noop_method_call,
|
||||
unreachable_pub,
|
||||
single_use_lifetimes,
|
||||
// variant_size_differences,
|
||||
)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Public API
|
||||
|
|
|
@ -29,6 +29,7 @@ use crate::cast::{u64_to_usize, usize_to_u64};
|
|||
/// ```
|
||||
#[inline]
|
||||
pub const fn split_u128_into_low_high_bits(value: u128) -> (u64, u64) {
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
(value as u64, (value >> 64) as u64)
|
||||
}
|
||||
|
||||
|
@ -60,7 +61,7 @@ pub const fn combine_low_high_bits_to_u128(low_bits: u64, high_bits: u64) -> u12
|
|||
/// Map a [`u64`] to a [`Timelock`].
|
||||
///
|
||||
/// Height/time is not differentiated via type, but rather:
|
||||
/// "height is any value less than 500_000_000 and timestamp is any value above"
|
||||
/// "height is any value less than `500_000_000` and timestamp is any value above"
|
||||
/// so the `u64/usize` is stored without any tag.
|
||||
///
|
||||
/// See [`timelock_to_u64`] for the inverse function.
|
||||
|
|
|
@ -30,11 +30,11 @@ pub enum Network {
|
|||
|
||||
impl Network {
|
||||
/// Returns the network ID for the current network.
|
||||
pub fn network_id(&self) -> [u8; 16] {
|
||||
pub const fn network_id(&self) -> [u8; 16] {
|
||||
match self {
|
||||
Network::Mainnet => MAINNET_NETWORK_ID,
|
||||
Network::Testnet => TESTNET_NETWORK_ID,
|
||||
Network::Stagenet => STAGENET_NETWORK_ID,
|
||||
Self::Mainnet => MAINNET_NETWORK_ID,
|
||||
Self::Testnet => TESTNET_NETWORK_ID,
|
||||
Self::Stagenet => STAGENET_NETWORK_ID,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,8 +89,9 @@ where
|
|||
/// assert_eq!(median(vec), 5);
|
||||
/// ```
|
||||
///
|
||||
/// # Safety
|
||||
/// # Invariant
|
||||
/// If not sorted the output will be invalid.
|
||||
#[allow(clippy::debug_assert_with_mut_call)]
|
||||
pub fn median<T>(array: impl AsRef<[T]>) -> T
|
||||
where
|
||||
T: Add<Output = T>
|
||||
|
|
|
@ -28,10 +28,10 @@ macro_rules! impl_thread_percent {
|
|||
$(
|
||||
$(#[$doc])*
|
||||
pub fn $fn_name() -> NonZeroUsize {
|
||||
// SAFETY:
|
||||
// unwrap here is okay because:
|
||||
// - THREADS().get() is always non-zero
|
||||
// - max() guards against 0
|
||||
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss, clippy::cast_precision_loss)]
|
||||
NonZeroUsize::new(max(1, (threads().get() as f64 * $percent).floor() as usize)).unwrap()
|
||||
}
|
||||
)*
|
||||
|
@ -58,10 +58,10 @@ impl_thread_percent! {
|
|||
/// Originally from <https://docs.rs/lpt>.
|
||||
///
|
||||
/// # Windows
|
||||
/// Uses SetThreadPriority() with THREAD_PRIORITY_IDLE (-15).
|
||||
/// Uses `SetThreadPriority()` with `THREAD_PRIORITY_IDLE` (-15).
|
||||
///
|
||||
/// # Unix
|
||||
/// Uses libc::nice() with the max nice level.
|
||||
/// Uses `libc::nice()` with the max nice level.
|
||||
///
|
||||
/// On macOS and *BSD: +20
|
||||
/// On Linux: +19
|
||||
|
@ -74,7 +74,7 @@ pub fn low_priority_thread() {
|
|||
// SAFETY: calling C.
|
||||
// We are _lowering_ our priority, not increasing, so this function should never fail.
|
||||
unsafe {
|
||||
let _ = SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);
|
||||
drop(SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ pub fn low_priority_thread() {
|
|||
// SAFETY: calling C.
|
||||
// We are _lowering_ our priority, not increasing, so this function should never fail.
|
||||
unsafe {
|
||||
let _ = libc::nice(NICE_MAX);
|
||||
libc::nice(NICE_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,6 +129,7 @@ pub const fn secs_to_clock(seconds: u32) -> (u8, u8, u8) {
|
|||
debug_assert!(m < 60);
|
||||
debug_assert!(s < 60);
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)] // checked above
|
||||
(h as u8, m, s)
|
||||
}
|
||||
|
||||
|
@ -153,6 +154,7 @@ pub fn time() -> u32 {
|
|||
///
|
||||
/// This is guaranteed to return a value between `0..=86399`
|
||||
pub fn time_utc() -> u32 {
|
||||
#[allow(clippy::cast_sign_loss)] // checked in function calls
|
||||
unix_clock(chrono::offset::Local::now().timestamp() as u64)
|
||||
}
|
||||
|
||||
|
|
|
@ -20,13 +20,17 @@ cuprate-helper = { path = "../../helper", features = ["asynch"], default-
|
|||
|
||||
axum = { version = "0.7.5", features = ["json"], default-features = false }
|
||||
serde = { workspace = true, optional = true }
|
||||
serde_json = { workspace = true, features = ["std"] }
|
||||
tower = { workspace = true }
|
||||
paste = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
cuprate-test-utils = { path = "../../test-utils" }
|
||||
|
||||
axum = { version = "0.7.5", features = ["json", "tokio", "http2"] }
|
||||
serde_json = { workspace = true, features = ["std"] }
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
ureq = { version = "2.10.0", features = ["json"] }
|
||||
ureq = { version = "2.10.0", features = ["json"] }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
|
@ -1,99 +1,6 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
//---------------------------------------------------------------------------------------------------- Lints
|
||||
// Forbid lints.
|
||||
// Our code, and code generated (e.g macros) cannot overrule these.
|
||||
#![forbid(
|
||||
// `unsafe` is allowed but it _must_ be
|
||||
// commented with `SAFETY: reason`.
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
|
||||
// Never.
|
||||
unused_unsafe,
|
||||
redundant_semicolons,
|
||||
unused_allocation,
|
||||
coherence_leak_check,
|
||||
while_true,
|
||||
|
||||
// Maybe can be put into `#[deny]`.
|
||||
unconditional_recursion,
|
||||
for_loops_over_fallibles,
|
||||
unused_braces,
|
||||
unused_labels,
|
||||
keyword_idents,
|
||||
non_ascii_idents,
|
||||
variant_size_differences,
|
||||
single_use_lifetimes,
|
||||
|
||||
// Probably can be put into `#[deny]`.
|
||||
future_incompatible,
|
||||
let_underscore,
|
||||
break_with_label_and_loop,
|
||||
duplicate_macro_attributes,
|
||||
exported_private_dependencies,
|
||||
large_assignments,
|
||||
overlapping_range_endpoints,
|
||||
semicolon_in_expressions_from_macros,
|
||||
noop_method_call,
|
||||
)]
|
||||
// Deny lints.
|
||||
// Some of these are `#[allow]`'ed on a per-case basis.
|
||||
#![deny(
|
||||
clippy::all,
|
||||
clippy::correctness,
|
||||
clippy::suspicious,
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::perf,
|
||||
clippy::pedantic,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
unused_doc_comments,
|
||||
unused_mut,
|
||||
missing_docs,
|
||||
deprecated,
|
||||
unused_comparisons,
|
||||
nonstandard_style,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(
|
||||
// FIXME: this lint affects crates outside of
|
||||
// `database/` for some reason, allow for now.
|
||||
clippy::cargo_common_metadata,
|
||||
|
||||
// FIXME: adding `#[must_use]` onto everything
|
||||
// might just be more annoying than useful...
|
||||
// although it is sometimes nice.
|
||||
clippy::must_use_candidate,
|
||||
|
||||
// FIXME: good lint but too many false positives
|
||||
// with our `Env` + `RwLock` setup.
|
||||
clippy::significant_drop_tightening,
|
||||
|
||||
// FIXME: good lint but is less clear in most cases.
|
||||
clippy::items_after_statements,
|
||||
|
||||
// TODO
|
||||
rustdoc::bare_urls,
|
||||
|
||||
clippy::multiple_crate_versions,
|
||||
clippy::module_name_repetitions,
|
||||
clippy::module_inception,
|
||||
clippy::redundant_pub_crate,
|
||||
clippy::option_if_let_else,
|
||||
)]
|
||||
// Allow some lints in tests.
|
||||
#![cfg_attr(
|
||||
test,
|
||||
allow(
|
||||
clippy::cognitive_complexity,
|
||||
clippy::needless_pass_by_value,
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::too_many_lines
|
||||
)
|
||||
)]
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Mod
|
||||
mod route;
|
||||
mod router_builder;
|
||||
mod rpc_error;
|
||||
|
@ -110,3 +17,13 @@ pub use rpc_handler::RpcHandler;
|
|||
pub use rpc_handler_dummy::RpcHandlerDummy;
|
||||
pub use rpc_request::RpcRequest;
|
||||
pub use rpc_response::RpcResponse;
|
||||
|
||||
// false-positive: used in `README.md`'s doc-test.
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
extern crate axum;
|
||||
extern crate cuprate_test_utils;
|
||||
extern crate serde_json;
|
||||
extern crate tokio;
|
||||
extern crate ureq;
|
||||
}
|
||||
|
|
|
@ -17,4 +17,7 @@ serde_json = { workspace = true, features = ["std"] }
|
|||
thiserror = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = { workspace = true }
|
||||
pretty_assertions = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
|
@ -1,94 +1,5 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
//---------------------------------------------------------------------------------------------------- Lints
|
||||
// Forbid lints.
|
||||
// Our code, and code generated (e.g macros) cannot overrule these.
|
||||
#![forbid(
|
||||
// `unsafe` is allowed but it _must_ be
|
||||
// commented with `SAFETY: reason`.
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
|
||||
// Never.
|
||||
unused_unsafe,
|
||||
redundant_semicolons,
|
||||
unused_allocation,
|
||||
coherence_leak_check,
|
||||
while_true,
|
||||
|
||||
// Maybe can be put into `#[deny]`.
|
||||
unconditional_recursion,
|
||||
for_loops_over_fallibles,
|
||||
unused_braces,
|
||||
unused_labels,
|
||||
keyword_idents,
|
||||
non_ascii_idents,
|
||||
variant_size_differences,
|
||||
single_use_lifetimes,
|
||||
|
||||
// Probably can be put into `#[deny]`.
|
||||
future_incompatible,
|
||||
let_underscore,
|
||||
break_with_label_and_loop,
|
||||
duplicate_macro_attributes,
|
||||
exported_private_dependencies,
|
||||
large_assignments,
|
||||
overlapping_range_endpoints,
|
||||
semicolon_in_expressions_from_macros,
|
||||
noop_method_call,
|
||||
unreachable_pub,
|
||||
)]
|
||||
// Deny lints.
|
||||
// Some of these are `#[allow]`'ed on a per-case basis.
|
||||
#![deny(
|
||||
clippy::all,
|
||||
clippy::correctness,
|
||||
clippy::suspicious,
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::perf,
|
||||
clippy::pedantic,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
clippy::missing_docs_in_private_items,
|
||||
unused_mut,
|
||||
missing_docs,
|
||||
deprecated,
|
||||
unused_comparisons,
|
||||
nonstandard_style
|
||||
)]
|
||||
#![allow(
|
||||
// FIXME: this lint affects crates outside of
|
||||
// `database/` for some reason, allow for now.
|
||||
clippy::cargo_common_metadata,
|
||||
|
||||
// FIXME: adding `#[must_use]` onto everything
|
||||
// might just be more annoying than useful...
|
||||
// although it is sometimes nice.
|
||||
clippy::must_use_candidate,
|
||||
|
||||
// FIXME: good lint but too many false positives
|
||||
// with our `Env` + `RwLock` setup.
|
||||
clippy::significant_drop_tightening,
|
||||
|
||||
// FIXME: good lint but is less clear in most cases.
|
||||
clippy::items_after_statements,
|
||||
|
||||
clippy::module_name_repetitions,
|
||||
clippy::module_inception,
|
||||
clippy::redundant_pub_crate,
|
||||
clippy::option_if_let_else,
|
||||
)]
|
||||
// Allow some lints in tests.
|
||||
#![cfg_attr(
|
||||
test,
|
||||
allow(
|
||||
clippy::cognitive_complexity,
|
||||
clippy::needless_pass_by_value,
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::too_many_lines
|
||||
)
|
||||
)]
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Mod/Use
|
||||
pub mod error;
|
||||
|
||||
mod id;
|
||||
|
@ -103,6 +14,5 @@ pub use request::Request;
|
|||
mod response;
|
||||
pub use response::Response;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- TESTS
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
|
|
@ -304,14 +304,14 @@ where
|
|||
if payload.is_none() {
|
||||
payload = Some(Ok(map.next_value::<T>()?));
|
||||
} else {
|
||||
return Err(serde::de::Error::duplicate_field("result/error"));
|
||||
return Err(Error::duplicate_field("result/error"));
|
||||
}
|
||||
}
|
||||
Key::Error => {
|
||||
if payload.is_none() {
|
||||
payload = Some(Err(map.next_value::<ErrorObject>()?));
|
||||
} else {
|
||||
return Err(serde::de::Error::duplicate_field("result/error"));
|
||||
return Err(Error::duplicate_field("result/error"));
|
||||
}
|
||||
}
|
||||
Key::Unknown => {
|
||||
|
|
|
@ -52,6 +52,7 @@ where
|
|||
}
|
||||
|
||||
/// Tests an input JSON string matches an expected type `T`.
|
||||
#[allow(clippy::needless_pass_by_value)] // serde signature
|
||||
fn assert_de<T>(json: &'static str, expected: T)
|
||||
where
|
||||
T: DeserializeOwned + std::fmt::Debug + Clone + PartialEq,
|
||||
|
|
|
@ -18,13 +18,14 @@ cuprate-epee-encoding = { path = "../../net/epee-encoding", optional = true }
|
|||
cuprate-fixed-bytes = { path = "../../net/fixed-bytes" }
|
||||
cuprate-types = { path = "../../types" }
|
||||
|
||||
monero-serai = { workspace = true }
|
||||
paste = { workspace = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
cuprate-test-utils = { path = "../../test-utils" }
|
||||
cuprate-json-rpc = { path = "../json-rpc" }
|
||||
|
||||
serde_json = { workspace = true }
|
||||
pretty_assertions = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
|
@ -1,96 +1,6 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
//---------------------------------------------------------------------------------------------------- Lints
|
||||
// Forbid lints.
|
||||
// Our code, and code generated (e.g macros) cannot overrule these.
|
||||
#![forbid(
|
||||
// `unsafe` is allowed but it _must_ be
|
||||
// commented with `SAFETY: reason`.
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
|
||||
// Never.
|
||||
unused_unsafe,
|
||||
redundant_semicolons,
|
||||
unused_allocation,
|
||||
coherence_leak_check,
|
||||
while_true,
|
||||
|
||||
// Maybe can be put into `#[deny]`.
|
||||
unconditional_recursion,
|
||||
for_loops_over_fallibles,
|
||||
unused_braces,
|
||||
unused_labels,
|
||||
keyword_idents,
|
||||
non_ascii_idents,
|
||||
variant_size_differences,
|
||||
single_use_lifetimes,
|
||||
|
||||
// Probably can be put into `#[deny]`.
|
||||
future_incompatible,
|
||||
let_underscore,
|
||||
break_with_label_and_loop,
|
||||
duplicate_macro_attributes,
|
||||
exported_private_dependencies,
|
||||
large_assignments,
|
||||
overlapping_range_endpoints,
|
||||
semicolon_in_expressions_from_macros,
|
||||
noop_method_call,
|
||||
)]
|
||||
// Deny lints.
|
||||
// Some of these are `#[allow]`'ed on a per-case basis.
|
||||
#![deny(
|
||||
clippy::all,
|
||||
clippy::correctness,
|
||||
clippy::suspicious,
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::perf,
|
||||
clippy::pedantic,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
unused_doc_comments,
|
||||
unused_mut,
|
||||
missing_docs,
|
||||
deprecated,
|
||||
unused_comparisons,
|
||||
nonstandard_style,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(
|
||||
// FIXME: this lint affects crates outside of
|
||||
// `database/` for some reason, allow for now.
|
||||
clippy::cargo_common_metadata,
|
||||
|
||||
// FIXME: adding `#[must_use]` onto everything
|
||||
// might just be more annoying than useful...
|
||||
// although it is sometimes nice.
|
||||
clippy::must_use_candidate,
|
||||
|
||||
// FIXME: good lint but too many false positives
|
||||
// with our `Env` + `RwLock` setup.
|
||||
clippy::significant_drop_tightening,
|
||||
|
||||
// FIXME: good lint but is less clear in most cases.
|
||||
clippy::items_after_statements,
|
||||
|
||||
clippy::multiple_crate_versions,
|
||||
clippy::module_name_repetitions,
|
||||
clippy::module_inception,
|
||||
clippy::redundant_pub_crate,
|
||||
clippy::option_if_let_else,
|
||||
)]
|
||||
// Allow some lints in tests.
|
||||
#![cfg_attr(
|
||||
test,
|
||||
allow(
|
||||
clippy::cognitive_complexity,
|
||||
clippy::needless_pass_by_value,
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::too_many_lines
|
||||
)
|
||||
)]
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Mod
|
||||
mod constants;
|
||||
mod defaults;
|
||||
mod free;
|
||||
|
@ -112,3 +22,10 @@ pub use constants::{
|
|||
CORE_RPC_VERSION_MINOR,
|
||||
};
|
||||
pub use rpc_call::{RpcCall, RpcCallValue};
|
||||
|
||||
// false-positive: used in tests
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
extern crate cuprate_test_utils;
|
||||
extern crate serde_json;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
mod binary_string;
|
||||
mod distribution;
|
||||
mod key_image_spent_status;
|
||||
#[allow(clippy::module_inception)]
|
||||
mod misc;
|
||||
mod pool_info_extent;
|
||||
mod status;
|
||||
|
|
|
@ -48,3 +48,6 @@ pretty_assertions = { workspace = true }
|
|||
proptest = { workspace = true }
|
||||
hex = { workspace = true }
|
||||
hex-literal = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -1,4 +1,44 @@
|
|||
//! The main [`Config`] struct, holding all configurable values.
|
||||
//! Database configuration.
|
||||
//!
|
||||
//! This module contains the main [`Config`]uration struct
|
||||
//! for the database [`Env`](cuprate_database::Env)ironment,
|
||||
//! and blockchain-specific configuration.
|
||||
//!
|
||||
//! It also contains types related to configuration settings.
|
||||
//!
|
||||
//! The main constructor is the [`ConfigBuilder`].
|
||||
//!
|
||||
//! These configurations are processed at runtime, meaning
|
||||
//! the `Env` can/will dynamically adjust its behavior based
|
||||
//! on these values.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```rust
|
||||
//! use cuprate_blockchain::{
|
||||
//! cuprate_database::{Env, config::SyncMode},
|
||||
//! config::{ConfigBuilder, ReaderThreads},
|
||||
//! };
|
||||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! let tmp_dir = tempfile::tempdir()?;
|
||||
//! let db_dir = tmp_dir.path().to_owned();
|
||||
//!
|
||||
//! let config = ConfigBuilder::new()
|
||||
//! // Use a custom database directory.
|
||||
//! .db_directory(db_dir.into())
|
||||
//! // Use as many reader threads as possible (when using `service`).
|
||||
//! .reader_threads(ReaderThreads::OnePerThread)
|
||||
//! // Use the fastest sync mode.
|
||||
//! .sync_mode(SyncMode::Fast)
|
||||
//! // Build into `Config`
|
||||
//! .build();
|
||||
//!
|
||||
//! // Start a database `service` using this configuration.
|
||||
//! let (_, _, env) = cuprate_blockchain::service::init(config.clone())?;
|
||||
//! // It's using the config we provided.
|
||||
//! assert_eq!(env.config(), &config.db_config);
|
||||
//! # Ok(()) }
|
||||
//! ```
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use std::{borrow::Cow, path::Path};
|
|
@ -1,44 +0,0 @@
|
|||
//! Database configuration.
|
||||
//!
|
||||
//! This module contains the main [`Config`]uration struct
|
||||
//! for the database [`Env`](cuprate_database::Env)ironment,
|
||||
//! and blockchain-specific configuration.
|
||||
//!
|
||||
//! It also contains types related to configuration settings.
|
||||
//!
|
||||
//! The main constructor is the [`ConfigBuilder`].
|
||||
//!
|
||||
//! These configurations are processed at runtime, meaning
|
||||
//! the `Env` can/will dynamically adjust its behavior based
|
||||
//! on these values.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```rust
|
||||
//! use cuprate_blockchain::{
|
||||
//! cuprate_database::{Env, config::SyncMode},
|
||||
//! config::{ConfigBuilder, ReaderThreads},
|
||||
//! };
|
||||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! let tmp_dir = tempfile::tempdir()?;
|
||||
//! let db_dir = tmp_dir.path().to_owned();
|
||||
//!
|
||||
//! let config = ConfigBuilder::new()
|
||||
//! // Use a custom database directory.
|
||||
//! .db_directory(db_dir.into())
|
||||
//! // Use as many reader threads as possible (when using `service`).
|
||||
//! .reader_threads(ReaderThreads::OnePerThread)
|
||||
//! // Use the fastest sync mode.
|
||||
//! .sync_mode(SyncMode::Fast)
|
||||
//! // Build into `Config`
|
||||
//! .build();
|
||||
//!
|
||||
//! // Start a database `service` using this configuration.
|
||||
//! let (_, _, env) = cuprate_blockchain::service::init(config.clone())?;
|
||||
//! // It's using the config we provided.
|
||||
//! assert_eq!(env.config(), &config.db_config);
|
||||
//! # Ok(()) }
|
||||
//! ```
|
||||
|
||||
mod config;
|
||||
pub use config::{Config, ConfigBuilder, ReaderThreads};
|
|
@ -1,103 +1,9 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
//---------------------------------------------------------------------------------------------------- Lints
|
||||
// Forbid lints.
|
||||
// Our code, and code generated (e.g macros) cannot overrule these.
|
||||
#![forbid(
|
||||
// `unsafe` is allowed but it _must_ be
|
||||
// commented with `SAFETY: reason`.
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
|
||||
// Never.
|
||||
unused_unsafe,
|
||||
redundant_semicolons,
|
||||
unused_allocation,
|
||||
coherence_leak_check,
|
||||
while_true,
|
||||
clippy::missing_docs_in_private_items,
|
||||
|
||||
// Maybe can be put into `#[deny]`.
|
||||
unconditional_recursion,
|
||||
for_loops_over_fallibles,
|
||||
unused_braces,
|
||||
unused_labels,
|
||||
keyword_idents,
|
||||
non_ascii_idents,
|
||||
variant_size_differences,
|
||||
single_use_lifetimes,
|
||||
|
||||
// Probably can be put into `#[deny]`.
|
||||
future_incompatible,
|
||||
let_underscore,
|
||||
break_with_label_and_loop,
|
||||
duplicate_macro_attributes,
|
||||
exported_private_dependencies,
|
||||
large_assignments,
|
||||
overlapping_range_endpoints,
|
||||
semicolon_in_expressions_from_macros,
|
||||
noop_method_call,
|
||||
unreachable_pub,
|
||||
)]
|
||||
// Deny lints.
|
||||
// Some of these are `#[allow]`'ed on a per-case basis.
|
||||
#![deny(
|
||||
clippy::all,
|
||||
clippy::correctness,
|
||||
clippy::suspicious,
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::perf,
|
||||
clippy::pedantic,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
unused_crate_dependencies,
|
||||
unused_doc_comments,
|
||||
unused_mut,
|
||||
missing_docs,
|
||||
deprecated,
|
||||
unused_comparisons,
|
||||
nonstandard_style
|
||||
)]
|
||||
#![allow(
|
||||
// FIXME: this lint affects crates outside of
|
||||
// `database/` for some reason, allow for now.
|
||||
clippy::cargo_common_metadata,
|
||||
|
||||
// FIXME: adding `#[must_use]` onto everything
|
||||
// might just be more annoying than useful...
|
||||
// although it is sometimes nice.
|
||||
clippy::must_use_candidate,
|
||||
|
||||
// FIXME: good lint but too many false positives
|
||||
// with our `Env` + `RwLock` setup.
|
||||
clippy::significant_drop_tightening,
|
||||
|
||||
// FIXME: good lint but is less clear in most cases.
|
||||
clippy::items_after_statements,
|
||||
|
||||
clippy::module_name_repetitions,
|
||||
clippy::module_inception,
|
||||
clippy::redundant_pub_crate,
|
||||
clippy::option_if_let_else,
|
||||
)]
|
||||
// Allow some lints when running in debug mode.
|
||||
#![cfg_attr(
|
||||
debug_assertions,
|
||||
allow(
|
||||
clippy::todo,
|
||||
clippy::multiple_crate_versions,
|
||||
// unused_crate_dependencies,
|
||||
)
|
||||
)]
|
||||
// Allow some lints in tests.
|
||||
#![cfg_attr(
|
||||
test,
|
||||
allow(
|
||||
clippy::cognitive_complexity,
|
||||
clippy::needless_pass_by_value,
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::too_many_lines
|
||||
)
|
||||
// See `cuprate-database` for reasoning.
|
||||
clippy::significant_drop_tightening
|
||||
)]
|
||||
|
||||
// Only allow building 64-bit targets.
|
||||
//
|
||||
// This allows us to assume 64-bit
|
||||
|
|
|
@ -37,8 +37,8 @@ pub fn init(
|
|||
let db = Arc::new(crate::open(config)?);
|
||||
|
||||
// Spawn the Reader thread pool and Writer.
|
||||
let readers = init_read_service(db.clone(), reader_threads);
|
||||
let writer = init_write_service(db.clone());
|
||||
let readers = init_read_service(Arc::clone(&db), reader_threads);
|
||||
let writer = init_write_service(Arc::clone(&db));
|
||||
|
||||
Ok((readers, writer, db))
|
||||
}
|
||||
|
|
|
@ -304,8 +304,9 @@ async fn test_template(
|
|||
// Assert we get back the same map of
|
||||
// `Amount`'s and `AmountIndex`'s.
|
||||
let mut response_output_count = 0;
|
||||
#[allow(clippy::iter_over_hash_type)] // order doesn't matter in this test
|
||||
for (amount, output_map) in response {
|
||||
let amount_index_set = map.get(&amount).unwrap();
|
||||
let amount_index_set = &map[&amount];
|
||||
|
||||
for (amount_index, output) in output_map {
|
||||
response_output_count += 1;
|
||||
|
|
|
@ -32,4 +32,7 @@ serde = { workspace = true, optional = true }
|
|||
[dev-dependencies]
|
||||
bytemuck = { version = "1.14.3", features = ["must_cast", "derive", "min_const_generics", "extern_crate_alloc"] }
|
||||
page_size = { version = "0.6.0" }
|
||||
tempfile = { version = "3.10.0" }
|
||||
tempfile = { version = "3.10.0" }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
|
@ -70,7 +70,7 @@ impl Drop for ConcreteEnv {
|
|||
// We need to do `mdb_env_set_flags(&env, MDB_NOSYNC|MDB_ASYNCMAP, 0)`
|
||||
// to clear the no sync and async flags such that the below `self.sync()`
|
||||
// _actually_ synchronously syncs.
|
||||
if let Err(_e) = crate::Env::sync(self) {
|
||||
if let Err(_e) = Env::sync(self) {
|
||||
// TODO: log error?
|
||||
}
|
||||
|
||||
|
|
|
@ -78,8 +78,8 @@ mod test {
|
|||
println!("left: {left:?}, right: {right:?}, expected: {expected:?}");
|
||||
assert_eq!(
|
||||
<StorableHeed::<T> as heed::Comparator>::compare(
|
||||
&<StorableHeed::<T> as heed::BytesEncode>::bytes_encode(&left).unwrap(),
|
||||
&<StorableHeed::<T> as heed::BytesEncode>::bytes_encode(&right).unwrap()
|
||||
&<StorableHeed::<T> as BytesEncode>::bytes_encode(&left).unwrap(),
|
||||
&<StorableHeed::<T> as BytesEncode>::bytes_encode(&right).unwrap()
|
||||
),
|
||||
expected
|
||||
);
|
||||
|
|
|
@ -23,7 +23,7 @@ use crate::{
|
|||
/// Shared [`DatabaseRo::get()`].
|
||||
#[inline]
|
||||
fn get<T: Table + 'static>(
|
||||
db: &impl redb::ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||
key: &T::Key,
|
||||
) -> Result<T::Value, RuntimeError> {
|
||||
Ok(db.get(key)?.ok_or(RuntimeError::KeyNotFound)?.value())
|
||||
|
@ -32,7 +32,7 @@ fn get<T: Table + 'static>(
|
|||
/// Shared [`DatabaseRo::len()`].
|
||||
#[inline]
|
||||
fn len<T: Table>(
|
||||
db: &impl redb::ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||
) -> Result<u64, RuntimeError> {
|
||||
Ok(db.len()?)
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ fn len<T: Table>(
|
|||
/// Shared [`DatabaseRo::first()`].
|
||||
#[inline]
|
||||
fn first<T: Table>(
|
||||
db: &impl redb::ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||
) -> Result<(T::Key, T::Value), RuntimeError> {
|
||||
let (key, value) = db.first()?.ok_or(RuntimeError::KeyNotFound)?;
|
||||
Ok((key.value(), value.value()))
|
||||
|
@ -49,7 +49,7 @@ fn first<T: Table>(
|
|||
/// Shared [`DatabaseRo::last()`].
|
||||
#[inline]
|
||||
fn last<T: Table>(
|
||||
db: &impl redb::ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||
) -> Result<(T::Key, T::Value), RuntimeError> {
|
||||
let (key, value) = db.last()?.ok_or(RuntimeError::KeyNotFound)?;
|
||||
Ok((key.value(), value.value()))
|
||||
|
@ -58,7 +58,7 @@ fn last<T: Table>(
|
|||
/// Shared [`DatabaseRo::is_empty()`].
|
||||
#[inline]
|
||||
fn is_empty<T: Table>(
|
||||
db: &impl redb::ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||
) -> Result<bool, RuntimeError> {
|
||||
Ok(db.is_empty()?)
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
//! # Ok(()) }
|
||||
//! ```
|
||||
|
||||
#[allow(clippy::module_inception)]
|
||||
mod config;
|
||||
pub use config::{Config, ConfigBuilder, READER_THREADS_DEFAULT};
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ pub trait Env: Sized {
|
|||
// We have the direct PATH to the file,
|
||||
// no need to use backend-specific functions.
|
||||
//
|
||||
// SAFETY: as we are only accessing the metadata of
|
||||
// INVARIANT: as we are only accessing the metadata of
|
||||
// the file and not reading the bytes, it should be
|
||||
// fine even with a memory mapped file being actively
|
||||
// written to.
|
||||
|
|
|
@ -163,11 +163,11 @@ impl KeyCompare {
|
|||
#[inline]
|
||||
pub const fn as_compare_fn<K: Key>(self) -> fn(&[u8], &[u8]) -> Ordering {
|
||||
match self {
|
||||
Self::Default => std::cmp::Ord::cmp,
|
||||
Self::Default => Ord::cmp,
|
||||
Self::Number => |left, right| {
|
||||
let left = <K as Storable>::from_bytes(left);
|
||||
let right = <K as Storable>::from_bytes(right);
|
||||
std::cmp::Ord::cmp(&left, &right)
|
||||
Ord::cmp(&left, &right)
|
||||
},
|
||||
Self::Custom(f) => f,
|
||||
}
|
||||
|
|
|
@ -1,94 +1,18 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
//---------------------------------------------------------------------------------------------------- Lints
|
||||
// Forbid lints.
|
||||
// Our code, and code generated (e.g macros) cannot overrule these.
|
||||
#![forbid(
|
||||
// `unsafe` is allowed but it _must_ be
|
||||
// commented with `SAFETY: reason`.
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
|
||||
// Never.
|
||||
unused_unsafe,
|
||||
redundant_semicolons,
|
||||
unused_allocation,
|
||||
coherence_leak_check,
|
||||
while_true,
|
||||
clippy::missing_docs_in_private_items,
|
||||
|
||||
// Maybe can be put into `#[deny]`.
|
||||
unconditional_recursion,
|
||||
for_loops_over_fallibles,
|
||||
unused_braces,
|
||||
unused_labels,
|
||||
keyword_idents,
|
||||
non_ascii_idents,
|
||||
variant_size_differences,
|
||||
single_use_lifetimes,
|
||||
|
||||
// Probably can be put into `#[deny]`.
|
||||
future_incompatible,
|
||||
let_underscore,
|
||||
break_with_label_and_loop,
|
||||
duplicate_macro_attributes,
|
||||
exported_private_dependencies,
|
||||
large_assignments,
|
||||
overlapping_range_endpoints,
|
||||
semicolon_in_expressions_from_macros,
|
||||
noop_method_call,
|
||||
unreachable_pub,
|
||||
)]
|
||||
// Deny lints.
|
||||
// Some of these are `#[allow]`'ed on a per-case basis.
|
||||
#![deny(
|
||||
clippy::all,
|
||||
clippy::correctness,
|
||||
clippy::suspicious,
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::perf,
|
||||
clippy::pedantic,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
unused_crate_dependencies,
|
||||
unused_doc_comments,
|
||||
unused_mut,
|
||||
missing_docs,
|
||||
deprecated,
|
||||
unused_comparisons,
|
||||
nonstandard_style
|
||||
)]
|
||||
#![allow(
|
||||
// FIXME: this lint affects crates outside of
|
||||
// `database/` for some reason, allow for now.
|
||||
clippy::cargo_common_metadata,
|
||||
|
||||
// FIXME: adding `#[must_use]` onto everything
|
||||
// might just be more annoying than useful...
|
||||
// although it is sometimes nice.
|
||||
clippy::must_use_candidate,
|
||||
|
||||
// FIXME: good lint but too many false positives
|
||||
// with our `Env` + `RwLock` setup.
|
||||
clippy::significant_drop_tightening,
|
||||
|
||||
// FIXME: good lint but is less clear in most cases.
|
||||
clippy::items_after_statements,
|
||||
|
||||
clippy::module_name_repetitions,
|
||||
clippy::module_inception,
|
||||
clippy::redundant_pub_crate,
|
||||
clippy::option_if_let_else,
|
||||
|
||||
// unused_crate_dependencies, // false-positive with `paste`
|
||||
)]
|
||||
// Allow some lints when running in debug mode.
|
||||
#![cfg_attr(
|
||||
debug_assertions,
|
||||
allow(
|
||||
clippy::todo,
|
||||
clippy::multiple_crate_versions,
|
||||
// unused_crate_dependencies,
|
||||
)
|
||||
// This lint is allowed because the following
|
||||
// code exists a lot in this crate:
|
||||
//
|
||||
// ```rust
|
||||
// let env_inner = env.env_inner();
|
||||
// let tx_rw = env_inner.tx_rw()?;
|
||||
// OpenTables::create_tables(&env_inner, &tx_rw)?;
|
||||
// ```
|
||||
//
|
||||
// Rust thinks `env_inner` can be dropped earlier
|
||||
// but it cannot, we need it for the lifetime of
|
||||
// the database transaction + tables.
|
||||
clippy::significant_drop_tightening
|
||||
)]
|
||||
// Allow some lints in tests.
|
||||
#![cfg_attr(
|
||||
|
|
|
@ -41,3 +41,6 @@ cuprate-test-utils = { path = "../../test-utils" }
|
|||
tokio = { workspace = true }
|
||||
tempfile = { workspace = true }
|
||||
hex-literal = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
|
@ -211,7 +211,7 @@ impl Config {
|
|||
/// assert_eq!(config.reader_threads, ReaderThreads::default());
|
||||
/// ```
|
||||
pub fn new() -> Self {
|
||||
Config {
|
||||
Self {
|
||||
db_config: DbConfig::new(Cow::Borrowed(&*CUPRATE_TXPOOL_DIR)),
|
||||
reader_threads: ReaderThreads::default(),
|
||||
max_txpool_weight: 0,
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![allow(
|
||||
// See `cuprate-database` for reasoning.
|
||||
clippy::significant_drop_tightening
|
||||
)]
|
||||
|
||||
pub mod config;
|
||||
mod free;
|
||||
|
@ -13,3 +17,13 @@ pub use free::open;
|
|||
|
||||
//re-exports
|
||||
pub use cuprate_database;
|
||||
|
||||
// TODO: remove when used.
|
||||
use tower as _;
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use cuprate_test_utils as _;
|
||||
use hex_literal as _;
|
||||
use tempfile as _;
|
||||
use tokio as _;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::{ops::TxPoolWriteError, tables::SpentKeyImages, types::TransactionHas
|
|||
///
|
||||
/// # Panics
|
||||
/// This function will panic if any of the [`Input`]s are not [`Input::ToKey`]
|
||||
pub fn add_tx_key_images(
|
||||
pub(super) fn add_tx_key_images(
|
||||
inputs: &[Input],
|
||||
tx_hash: &TransactionHash,
|
||||
kis_table: &mut impl DatabaseRw<SpentKeyImages>,
|
||||
|
@ -31,7 +31,7 @@ pub fn add_tx_key_images(
|
|||
///
|
||||
/// # Panics
|
||||
/// This function will panic if any of the [`Input`]s are not [`Input::ToKey`]
|
||||
pub fn remove_tx_key_images(
|
||||
pub(super) fn remove_tx_key_images(
|
||||
inputs: &[Input],
|
||||
kis_table: &mut impl DatabaseRw<SpentKeyImages>,
|
||||
) -> Result<(), RuntimeError> {
|
||||
|
|
|
@ -30,8 +30,8 @@ pub fn init(
|
|||
let db = Arc::new(crate::open(config)?);
|
||||
|
||||
// Spawn the Reader thread pool and Writer.
|
||||
let readers = init_read_service(db.clone(), reader_threads);
|
||||
let writer = init_write_service(db.clone());
|
||||
let readers = init_read_service(Arc::clone(&db), reader_threads);
|
||||
let writer = init_write_service(Arc::clone(&db));
|
||||
|
||||
Ok((readers, writer, db))
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ use crate::{
|
|||
/// Should be called _once_ per actual database.
|
||||
#[cold]
|
||||
#[inline(never)] // Only called once.
|
||||
pub fn init_read_service(env: Arc<ConcreteEnv>, threads: ReaderThreads) -> TxpoolReadHandle {
|
||||
pub(super) fn init_read_service(env: Arc<ConcreteEnv>, threads: ReaderThreads) -> TxpoolReadHandle {
|
||||
init_read_service_with_pool(env, init_thread_pool(threads))
|
||||
}
|
||||
|
||||
|
@ -35,10 +35,7 @@ pub fn init_read_service(env: Arc<ConcreteEnv>, threads: ReaderThreads) -> Txpoo
|
|||
/// Should be called _once_ per actual database.
|
||||
#[cold]
|
||||
#[inline(never)] // Only called once.
|
||||
pub fn init_read_service_with_pool(
|
||||
env: Arc<ConcreteEnv>,
|
||||
pool: Arc<ThreadPool>,
|
||||
) -> TxpoolReadHandle {
|
||||
fn init_read_service_with_pool(env: Arc<ConcreteEnv>, pool: Arc<ThreadPool>) -> TxpoolReadHandle {
|
||||
DatabaseReadService::new(env, pool, map_request)
|
||||
}
|
||||
|
||||
|
@ -53,6 +50,7 @@ pub fn init_read_service_with_pool(
|
|||
/// 1. `Request` is mapped to a handler function
|
||||
/// 2. Handler function is called
|
||||
/// 3. [`TxpoolReadResponse`] is returned
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
fn map_request(
|
||||
env: &ConcreteEnv, // Access to the database
|
||||
request: TxpoolReadRequest, // The request we must fulfill
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::{
|
|||
|
||||
//---------------------------------------------------------------------------------------------------- init_write_service
|
||||
/// Initialize the txpool write service from a [`ConcreteEnv`].
|
||||
pub fn init_write_service(env: Arc<ConcreteEnv>) -> TxpoolWriteHandle {
|
||||
pub(super) fn init_write_service(env: Arc<ConcreteEnv>) -> TxpoolWriteHandle {
|
||||
DatabaseWriteHandle::init(env, handle_txpool_request)
|
||||
}
|
||||
|
||||
|
|
|
@ -35,10 +35,11 @@ bitflags::bitflags! {
|
|||
pub struct TransactionInfo {
|
||||
/// The transaction's fee.
|
||||
pub fee: u64,
|
||||
/// The transaction`s weight.
|
||||
/// The transaction's weight.
|
||||
pub weight: usize,
|
||||
/// [`TxStateFlags`] of this transaction.
|
||||
pub flags: TxStateFlags,
|
||||
#[allow(clippy::pub_underscore_fields)]
|
||||
/// Explicit padding so that we have no implicit padding bytes in `repr(C)`.
|
||||
///
|
||||
/// Allows potential future expansion of this type.
|
||||
|
@ -68,21 +69,21 @@ impl From<RawCachedVerificationState> for CachedVerificationState {
|
|||
fn from(value: RawCachedVerificationState) -> Self {
|
||||
// if the hash is all `0`s then there is no hash this is valid at.
|
||||
if value.raw_valid_at_hash == [0; 32] {
|
||||
return CachedVerificationState::NotVerified;
|
||||
return Self::NotVerified;
|
||||
}
|
||||
|
||||
let raw_valid_past_timestamp = u64::from_le_bytes(value.raw_valid_past_timestamp);
|
||||
|
||||
// if the timestamp is 0, there is no timestamp that needs to be passed.
|
||||
if raw_valid_past_timestamp == 0 {
|
||||
return CachedVerificationState::ValidAtHashAndHF {
|
||||
return Self::ValidAtHashAndHF {
|
||||
block_hash: value.raw_valid_at_hash,
|
||||
hf: HardFork::from_version(value.raw_hf)
|
||||
.expect("hard-fork values stored in the DB should always be valid"),
|
||||
};
|
||||
}
|
||||
|
||||
CachedVerificationState::ValidAtHashAndHFWithTimeBasedLock {
|
||||
Self::ValidAtHashAndHFWithTimeBasedLock {
|
||||
block_hash: value.raw_valid_at_hash,
|
||||
hf: HardFork::from_version(value.raw_hf)
|
||||
.expect("hard-fork values stored in the DB should always be valid"),
|
||||
|
@ -91,6 +92,7 @@ impl From<RawCachedVerificationState> for CachedVerificationState {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::fallible_impl_from)] // only panics in invalid states
|
||||
impl From<CachedVerificationState> for RawCachedVerificationState {
|
||||
fn from(value: CachedVerificationState) -> Self {
|
||||
match value {
|
||||
|
|
|
@ -23,10 +23,12 @@ bytes = { workspace = true }
|
|||
curve25519-dalek = { workspace = true }
|
||||
monero-serai = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"], optional = true }
|
||||
borsh = { workspace = true, optional = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
proptest = { workspace = true, optional = true }
|
||||
proptest-derive = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
[dev-dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
|
@ -1,76 +1,6 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
//---------------------------------------------------------------------------------------------------- Lints
|
||||
// Forbid lints.
|
||||
// Our code, and code generated (e.g macros) cannot overrule these.
|
||||
#![forbid(
|
||||
// `unsafe` is allowed but it _must_ be
|
||||
// commented with `SAFETY: reason`.
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
|
||||
// Never.
|
||||
unused_unsafe,
|
||||
redundant_semicolons,
|
||||
unused_allocation,
|
||||
coherence_leak_check,
|
||||
single_use_lifetimes,
|
||||
while_true,
|
||||
clippy::missing_docs_in_private_items,
|
||||
|
||||
// Maybe can be put into `#[deny]`.
|
||||
unconditional_recursion,
|
||||
for_loops_over_fallibles,
|
||||
unused_braces,
|
||||
unused_doc_comments,
|
||||
unused_labels,
|
||||
keyword_idents,
|
||||
non_ascii_idents,
|
||||
variant_size_differences,
|
||||
|
||||
// Probably can be put into `#[deny]`.
|
||||
future_incompatible,
|
||||
let_underscore,
|
||||
break_with_label_and_loop,
|
||||
duplicate_macro_attributes,
|
||||
exported_private_dependencies,
|
||||
large_assignments,
|
||||
overlapping_range_endpoints,
|
||||
semicolon_in_expressions_from_macros,
|
||||
noop_method_call,
|
||||
unreachable_pub,
|
||||
)]
|
||||
// Deny lints.
|
||||
// Some of these are `#[allow]`'ed on a per-case basis.
|
||||
#![deny(
|
||||
clippy::all,
|
||||
clippy::correctness,
|
||||
clippy::suspicious,
|
||||
clippy::style,
|
||||
clippy::complexity,
|
||||
clippy::perf,
|
||||
clippy::pedantic,
|
||||
clippy::nursery,
|
||||
clippy::cargo,
|
||||
unused_mut,
|
||||
missing_docs,
|
||||
deprecated,
|
||||
unused_comparisons,
|
||||
nonstandard_style
|
||||
)]
|
||||
#![allow(
|
||||
// FIXME: this lint affects crates outside of
|
||||
// `database/` for some reason, allow for now.
|
||||
clippy::cargo_common_metadata,
|
||||
|
||||
// FIXME: adding `#[must_use]` onto everything
|
||||
// might just be more annoying than useful...
|
||||
// although it is sometimes nice.
|
||||
clippy::must_use_candidate,
|
||||
|
||||
clippy::module_name_repetitions,
|
||||
clippy::module_inception,
|
||||
clippy::redundant_pub_crate,
|
||||
clippy::option_if_let_else,
|
||||
)]
|
||||
// `proptest` needs this internally.
|
||||
#![cfg_attr(any(feature = "proptest"), allow(non_local_definitions))]
|
||||
// Allow some lints when running in debug mode.
|
||||
#![cfg_attr(debug_assertions, allow(clippy::todo, clippy::multiple_crate_versions))]
|
||||
|
||||
|
@ -97,4 +27,5 @@ pub use types::{
|
|||
//---------------------------------------------------------------------------------------------------- Feature-gated
|
||||
#[cfg(feature = "blockchain")]
|
||||
pub mod blockchain;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Private
|
||||
|
|
Loading…
Reference in a new issue