From eead49beb09b4a0a8c4a2b0f38683311f53eb891 Mon Sep 17 00:00:00 2001 From: hinto-janai Date: Mon, 2 Sep 2024 13:12:54 -0400 Subject: [PATCH] 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` --- Cargo.lock | 44 +++++--- Cargo.toml | 6 +- helper/Cargo.toml | 3 + helper/src/asynch.rs | 8 +- helper/src/atomic.rs | 2 + helper/src/fs.rs | 89 +++++---------- helper/src/lib.rs | 32 ------ helper/src/map.rs | 3 +- helper/src/network.rs | 8 +- helper/src/num.rs | 3 +- helper/src/thread.rs | 10 +- helper/src/time.rs | 2 + rpc/interface/Cargo.toml | 8 +- rpc/interface/src/lib.rs | 103 ++---------------- rpc/json-rpc/Cargo.toml | 5 +- rpc/json-rpc/src/lib.rs | 90 --------------- rpc/json-rpc/src/response.rs | 4 +- rpc/json-rpc/src/tests.rs | 1 + rpc/types/Cargo.toml | 9 +- rpc/types/src/lib.rs | 97 ++--------------- rpc/types/src/misc/mod.rs | 1 + storage/blockchain/Cargo.toml | 3 + storage/blockchain/src/{config => }/config.rs | 42 ++++++- storage/blockchain/src/config/mod.rs | 44 -------- storage/blockchain/src/lib.rs | 100 +---------------- storage/blockchain/src/service/free.rs | 4 +- storage/blockchain/src/service/tests.rs | 3 +- storage/database/Cargo.toml | 5 +- storage/database/src/backend/heed/env.rs | 2 +- storage/database/src/backend/heed/storable.rs | 4 +- storage/database/src/backend/redb/database.rs | 10 +- storage/database/src/config/mod.rs | 1 + storage/database/src/env.rs | 2 +- storage/database/src/key.rs | 4 +- storage/database/src/lib.rs | 102 +++-------------- storage/txpool/Cargo.toml | 3 + storage/txpool/src/config.rs | 2 +- storage/txpool/src/lib.rs | 14 +++ storage/txpool/src/ops/key_images.rs | 4 +- storage/txpool/src/service/free.rs | 4 +- storage/txpool/src/service/read.rs | 8 +- storage/txpool/src/service/write.rs | 2 +- storage/txpool/src/types.rs | 10 +- types/Cargo.toml | 6 +- types/src/lib.rs | 75 +------------ 45 files changed, 240 insertions(+), 742 deletions(-) rename storage/blockchain/src/{config => }/config.rs (82%) delete mode 100644 storage/blockchain/src/config/mod.rs diff --git a/Cargo.lock b/Cargo.lock index d004f95..950044c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", ] diff --git a/Cargo.toml b/Cargo.toml index 1a0c667..0a98eab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/helper/Cargo.toml b/helper/Cargo.toml index 9af25c6..c74e40f 100644 --- a/helper/Cargo.toml +++ b/helper/Cargo.toml @@ -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 \ No newline at end of file diff --git a/helper/src/asynch.rs b/helper/src/asynch.rs index ea89dd7..9868191 100644 --- a/helper/src/asynch.rs +++ b/helper/src/asynch.rs @@ -19,7 +19,7 @@ pub struct InfallibleOneshotReceiver(oneshot::Receiver); impl From> for InfallibleOneshotReceiver { fn from(value: oneshot::Receiver) -> 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::(); + let (tx, rx) = oneshot::channel::(); 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(); diff --git a/helper/src/atomic.rs b/helper/src/atomic.rs index f253737..4795896 100644 --- a/helper/src/atomic.rs +++ b/helper/src/atomic.rs @@ -49,6 +49,8 @@ pub type AtomicF64 = AtomicCell; //---------------------------------------------------------------------------------------------------- TESTS #[cfg(test)] mod tests { + #![allow(clippy::float_cmp)] + use super::*; #[test] diff --git a/helper/src/fs.rs b/helper/src/fs.rs index 7290361..5d62a64 100644 --- a/helper/src/fs.rs +++ b/helper/src/fs.rs @@ -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)); } } } diff --git a/helper/src/lib.rs b/helper/src/lib.rs index 4dd3105..de0d955 100644 --- a/helper/src/lib.rs +++ b/helper/src/lib.rs @@ -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 diff --git a/helper/src/map.rs b/helper/src/map.rs index 82d5494..ea6dfc4 100644 --- a/helper/src/map.rs +++ b/helper/src/map.rs @@ -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. diff --git a/helper/src/network.rs b/helper/src/network.rs index 684e71a..f3224b3 100644 --- a/helper/src/network.rs +++ b/helper/src/network.rs @@ -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, } } } diff --git a/helper/src/num.rs b/helper/src/num.rs index f90357e..674ed35 100644 --- a/helper/src/num.rs +++ b/helper/src/num.rs @@ -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(array: impl AsRef<[T]>) -> T where T: Add diff --git a/helper/src/thread.rs b/helper/src/thread.rs index 96958ff..04a2606 100644 --- a/helper/src/thread.rs +++ b/helper/src/thread.rs @@ -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 . /// /// # 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); } } } diff --git a/helper/src/time.rs b/helper/src/time.rs index 28aff7f..ce39c2d 100644 --- a/helper/src/time.rs +++ b/helper/src/time.rs @@ -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) } diff --git a/rpc/interface/Cargo.toml b/rpc/interface/Cargo.toml index a83c0f0..5f17317 100644 --- a/rpc/interface/Cargo.toml +++ b/rpc/interface/Cargo.toml @@ -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"] } \ No newline at end of file +ureq = { version = "2.10.0", features = ["json"] } + +[lints] +workspace = true \ No newline at end of file diff --git a/rpc/interface/src/lib.rs b/rpc/interface/src/lib.rs index 43bd9e1..d437697 100644 --- a/rpc/interface/src/lib.rs +++ b/rpc/interface/src/lib.rs @@ -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; +} diff --git a/rpc/json-rpc/Cargo.toml b/rpc/json-rpc/Cargo.toml index 777f326..5d2544e 100644 --- a/rpc/json-rpc/Cargo.toml +++ b/rpc/json-rpc/Cargo.toml @@ -17,4 +17,7 @@ serde_json = { workspace = true, features = ["std"] } thiserror = { workspace = true } [dev-dependencies] -pretty_assertions = { workspace = true } \ No newline at end of file +pretty_assertions = { workspace = true } + +[lints] +workspace = true \ No newline at end of file diff --git a/rpc/json-rpc/src/lib.rs b/rpc/json-rpc/src/lib.rs index ce7467a..dfc4b18 100644 --- a/rpc/json-rpc/src/lib.rs +++ b/rpc/json-rpc/src/lib.rs @@ -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; diff --git a/rpc/json-rpc/src/response.rs b/rpc/json-rpc/src/response.rs index efd768b..2b84606 100644 --- a/rpc/json-rpc/src/response.rs +++ b/rpc/json-rpc/src/response.rs @@ -304,14 +304,14 @@ where if payload.is_none() { payload = Some(Ok(map.next_value::()?)); } 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::()?)); } else { - return Err(serde::de::Error::duplicate_field("result/error")); + return Err(Error::duplicate_field("result/error")); } } Key::Unknown => { diff --git a/rpc/json-rpc/src/tests.rs b/rpc/json-rpc/src/tests.rs index ff8f049..3ee6088 100644 --- a/rpc/json-rpc/src/tests.rs +++ b/rpc/json-rpc/src/tests.rs @@ -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(json: &'static str, expected: T) where T: DeserializeOwned + std::fmt::Debug + Clone + PartialEq, diff --git a/rpc/types/Cargo.toml b/rpc/types/Cargo.toml index 9c99681..08b13b1 100644 --- a/rpc/types/Cargo.toml +++ b/rpc/types/Cargo.toml @@ -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 } \ No newline at end of file +serde = { workspace = true } +serde_json = { workspace = true } + +[lints] +workspace = true \ No newline at end of file diff --git a/rpc/types/src/lib.rs b/rpc/types/src/lib.rs index c5f890f..51ea3cc 100644 --- a/rpc/types/src/lib.rs +++ b/rpc/types/src/lib.rs @@ -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; +} diff --git a/rpc/types/src/misc/mod.rs b/rpc/types/src/misc/mod.rs index bd6454d..c5c1840 100644 --- a/rpc/types/src/misc/mod.rs +++ b/rpc/types/src/misc/mod.rs @@ -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; diff --git a/storage/blockchain/Cargo.toml b/storage/blockchain/Cargo.toml index 58da21e..e039903 100644 --- a/storage/blockchain/Cargo.toml +++ b/storage/blockchain/Cargo.toml @@ -48,3 +48,6 @@ pretty_assertions = { workspace = true } proptest = { workspace = true } hex = { workspace = true } hex-literal = { workspace = true } + +[lints] +workspace = true diff --git a/storage/blockchain/src/config/config.rs b/storage/blockchain/src/config.rs similarity index 82% rename from storage/blockchain/src/config/config.rs rename to storage/blockchain/src/config.rs index 957c67c..e4b7606 100644 --- a/storage/blockchain/src/config/config.rs +++ b/storage/blockchain/src/config.rs @@ -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> { +//! 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}; diff --git a/storage/blockchain/src/config/mod.rs b/storage/blockchain/src/config/mod.rs deleted file mode 100644 index 555a6e6..0000000 --- a/storage/blockchain/src/config/mod.rs +++ /dev/null @@ -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> { -//! 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}; diff --git a/storage/blockchain/src/lib.rs b/storage/blockchain/src/lib.rs index e544a69..f66cd99 100644 --- a/storage/blockchain/src/lib.rs +++ b/storage/blockchain/src/lib.rs @@ -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 diff --git a/storage/blockchain/src/service/free.rs b/storage/blockchain/src/service/free.rs index e748bbb..2e7c908 100644 --- a/storage/blockchain/src/service/free.rs +++ b/storage/blockchain/src/service/free.rs @@ -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)) } diff --git a/storage/blockchain/src/service/tests.rs b/storage/blockchain/src/service/tests.rs index ed13f7b..b68b544 100644 --- a/storage/blockchain/src/service/tests.rs +++ b/storage/blockchain/src/service/tests.rs @@ -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; diff --git a/storage/database/Cargo.toml b/storage/database/Cargo.toml index a70457f..0ef4a97 100644 --- a/storage/database/Cargo.toml +++ b/storage/database/Cargo.toml @@ -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" } \ No newline at end of file +tempfile = { version = "3.10.0" } + +[lints] +workspace = true \ No newline at end of file diff --git a/storage/database/src/backend/heed/env.rs b/storage/database/src/backend/heed/env.rs index 0c2847f..8c71e61 100644 --- a/storage/database/src/backend/heed/env.rs +++ b/storage/database/src/backend/heed/env.rs @@ -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? } diff --git a/storage/database/src/backend/heed/storable.rs b/storage/database/src/backend/heed/storable.rs index 3566e88..da0e0cb 100644 --- a/storage/database/src/backend/heed/storable.rs +++ b/storage/database/src/backend/heed/storable.rs @@ -78,8 +78,8 @@ mod test { println!("left: {left:?}, right: {right:?}, expected: {expected:?}"); assert_eq!( as heed::Comparator>::compare( - & as heed::BytesEncode>::bytes_encode(&left).unwrap(), - & as heed::BytesEncode>::bytes_encode(&right).unwrap() + & as BytesEncode>::bytes_encode(&left).unwrap(), + & as BytesEncode>::bytes_encode(&right).unwrap() ), expected ); diff --git a/storage/database/src/backend/redb/database.rs b/storage/database/src/backend/redb/database.rs index cd9a0be..dafb241 100644 --- a/storage/database/src/backend/redb/database.rs +++ b/storage/database/src/backend/redb/database.rs @@ -23,7 +23,7 @@ use crate::{ /// Shared [`DatabaseRo::get()`]. #[inline] fn get( - db: &impl redb::ReadableTable, StorableRedb>, + db: &impl ReadableTable, StorableRedb>, key: &T::Key, ) -> Result { Ok(db.get(key)?.ok_or(RuntimeError::KeyNotFound)?.value()) @@ -32,7 +32,7 @@ fn get( /// Shared [`DatabaseRo::len()`]. #[inline] fn len( - db: &impl redb::ReadableTable, StorableRedb>, + db: &impl ReadableTable, StorableRedb>, ) -> Result { Ok(db.len()?) } @@ -40,7 +40,7 @@ fn len( /// Shared [`DatabaseRo::first()`]. #[inline] fn first( - db: &impl redb::ReadableTable, StorableRedb>, + db: &impl ReadableTable, StorableRedb>, ) -> 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( /// Shared [`DatabaseRo::last()`]. #[inline] fn last( - db: &impl redb::ReadableTable, StorableRedb>, + db: &impl ReadableTable, StorableRedb>, ) -> 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( /// Shared [`DatabaseRo::is_empty()`]. #[inline] fn is_empty( - db: &impl redb::ReadableTable, StorableRedb>, + db: &impl ReadableTable, StorableRedb>, ) -> Result { Ok(db.is_empty()?) } diff --git a/storage/database/src/config/mod.rs b/storage/database/src/config/mod.rs index 19a324e..c6ed0c0 100644 --- a/storage/database/src/config/mod.rs +++ b/storage/database/src/config/mod.rs @@ -33,6 +33,7 @@ //! # Ok(()) } //! ``` +#[allow(clippy::module_inception)] mod config; pub use config::{Config, ConfigBuilder, READER_THREADS_DEFAULT}; diff --git a/storage/database/src/env.rs b/storage/database/src/env.rs index cae4973..8294443 100644 --- a/storage/database/src/env.rs +++ b/storage/database/src/env.rs @@ -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. diff --git a/storage/database/src/key.rs b/storage/database/src/key.rs index 3273d4e..2f3855a 100644 --- a/storage/database/src/key.rs +++ b/storage/database/src/key.rs @@ -163,11 +163,11 @@ impl KeyCompare { #[inline] pub const fn as_compare_fn(self) -> fn(&[u8], &[u8]) -> Ordering { match self { - Self::Default => std::cmp::Ord::cmp, + Self::Default => Ord::cmp, Self::Number => |left, right| { let left = ::from_bytes(left); let right = ::from_bytes(right); - std::cmp::Ord::cmp(&left, &right) + Ord::cmp(&left, &right) }, Self::Custom(f) => f, } diff --git a/storage/database/src/lib.rs b/storage/database/src/lib.rs index 5946fe5..45bfc53 100644 --- a/storage/database/src/lib.rs +++ b/storage/database/src/lib.rs @@ -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( diff --git a/storage/txpool/Cargo.toml b/storage/txpool/Cargo.toml index d5ea77d..70211d9 100644 --- a/storage/txpool/Cargo.toml +++ b/storage/txpool/Cargo.toml @@ -41,3 +41,6 @@ cuprate-test-utils = { path = "../../test-utils" } tokio = { workspace = true } tempfile = { workspace = true } hex-literal = { workspace = true } + +[lints] +workspace = true \ No newline at end of file diff --git a/storage/txpool/src/config.rs b/storage/txpool/src/config.rs index 8d09b5e..1ef0d73 100644 --- a/storage/txpool/src/config.rs +++ b/storage/txpool/src/config.rs @@ -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, diff --git a/storage/txpool/src/lib.rs b/storage/txpool/src/lib.rs index f200c34..243dc4d 100644 --- a/storage/txpool/src/lib.rs +++ b/storage/txpool/src/lib.rs @@ -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 _; +} diff --git a/storage/txpool/src/ops/key_images.rs b/storage/txpool/src/ops/key_images.rs index c6e4415..04aa1b4 100644 --- a/storage/txpool/src/ops/key_images.rs +++ b/storage/txpool/src/ops/key_images.rs @@ -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, @@ -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, ) -> Result<(), RuntimeError> { diff --git a/storage/txpool/src/service/free.rs b/storage/txpool/src/service/free.rs index 614ab5c..003da55 100644 --- a/storage/txpool/src/service/free.rs +++ b/storage/txpool/src/service/free.rs @@ -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)) } diff --git a/storage/txpool/src/service/read.rs b/storage/txpool/src/service/read.rs index c2fee66..5654164 100644 --- a/storage/txpool/src/service/read.rs +++ b/storage/txpool/src/service/read.rs @@ -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, threads: ReaderThreads) -> TxpoolReadHandle { +pub(super) fn init_read_service(env: Arc, threads: ReaderThreads) -> TxpoolReadHandle { init_read_service_with_pool(env, init_thread_pool(threads)) } @@ -35,10 +35,7 @@ pub fn init_read_service(env: Arc, 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, - pool: Arc, -) -> TxpoolReadHandle { +fn init_read_service_with_pool(env: Arc, pool: Arc) -> 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 diff --git a/storage/txpool/src/service/write.rs b/storage/txpool/src/service/write.rs index f6bdb38..8a3b1bf 100644 --- a/storage/txpool/src/service/write.rs +++ b/storage/txpool/src/service/write.rs @@ -16,7 +16,7 @@ use crate::{ //---------------------------------------------------------------------------------------------------- init_write_service /// Initialize the txpool write service from a [`ConcreteEnv`]. -pub fn init_write_service(env: Arc) -> TxpoolWriteHandle { +pub(super) fn init_write_service(env: Arc) -> TxpoolWriteHandle { DatabaseWriteHandle::init(env, handle_txpool_request) } diff --git a/storage/txpool/src/types.rs b/storage/txpool/src/types.rs index 5c89d3b..09b0ce0 100644 --- a/storage/txpool/src/types.rs +++ b/storage/txpool/src/types.rs @@ -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 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 for CachedVerificationState { } } +#[allow(clippy::fallible_impl_from)] // only panics in invalid states impl From for RawCachedVerificationState { fn from(value: CachedVerificationState) -> Self { match value { diff --git a/types/Cargo.toml b/types/Cargo.toml index 4c31cfc..4b9204b 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -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] \ No newline at end of file +[dev-dependencies] + +[lints] +workspace = true \ No newline at end of file diff --git a/types/src/lib.rs b/types/src/lib.rs index d70f4c3..0b0dbe6 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -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