diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000000..e125cada3c9 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,19 @@ + +[target.'cfg(all())'] +rustflags = [ + # Zebra standard lints for Rust 1.58+ + "-Dunsafe_code", + "-Drust_2021_compatibility", + "-Dclippy::await_holding_lock", + + "-Wmissing_docs", + "-Wnonstandard_style", + "-Wfuture_incompatible", + + "-Aclippy::try_err", + + # TODOs: + + # fix hidden lifetime parameters + #"-Wrust_2018_idioms", +] diff --git a/.gitignore b/.gitignore index 62d81cc249b..283a2e96a77 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,5 @@ # Vscode detrius .vscode/ .zebra-state/ -.cargo/ # Nix configs shell.nix diff --git a/Cargo.lock b/Cargo.lock index 071edc27183..d51db2c7d48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4241,7 +4241,7 @@ dependencies = [ [[package]] name = "zcash_script" version = "0.1.6-alpha.0" -source = "git+https://github.com/ZcashFoundation/zcash_script.git?rev=70738fc9b143c2a23df7c138c87c95b398273402#70738fc9b143c2a23df7c138c87c95b398273402" +source = "git+https://github.com/ZcashFoundation/zcash_script.git?rev=270d32d192c5880f911acf21ef100caa128e6179#270d32d192c5880f911acf21ef100caa128e6179" dependencies = [ "bindgen", "blake2b_simd", diff --git a/book/src/dev/rfcs/0005-state-updates.md b/book/src/dev/rfcs/0005-state-updates.md index c67a5135610..5866eb136f9 100644 --- a/book/src/dev/rfcs/0005-state-updates.md +++ b/book/src/dev/rfcs/0005-state-updates.md @@ -608,7 +608,7 @@ We use the following rocksdb column families: | `tx_by_location` | `TransactionLocation` | `Transaction` | Never | | `hash_by_tx` | `TransactionLocation` | `transaction::Hash` | Never | | `tx_by_hash` | `transaction::Hash` | `TransactionLocation` | Never | -| `utxo_by_outpoint` | `OutLocation` | `transparent::Utxo` | Delete | +| `utxo_by_outpoint` | `OutLocation` | `transparent::Output` | Delete | | `balance_by_transparent_addr` | `transparent::Address` | `Amount \|\| FirstOutLocation` | Update | | `utxo_by_transparent_addr_loc` | `FirstOutLocation` | `AtLeastOne` | Up/Del | | `tx_by_transparent_addr_loc` | `FirstOutLocation` | `AtLeastOne` | Append | diff --git a/book/src/dev/rfcs/0011-async-rust-in-zebra.md b/book/src/dev/rfcs/0011-async-rust-in-zebra.md index ffc4c01e9cb..b3c1212032c 100644 --- a/book/src/dev/rfcs/0011-async-rust-in-zebra.md +++ b/book/src/dev/rfcs/0011-async-rust-in-zebra.md @@ -564,6 +564,13 @@ For example, [`tokio::sync::watch::Receiver::borrow`](https://docs.rs/tokio/1.15 holds a read lock, so the borrowed data should always be cloned. Use `Arc` for efficient clones if needed. +Never have two active watch borrow guards in the same scope, because that can cause a deadlock. The +`watch::Sender` may start acquiring a write lock while the first borrow guard is active but the +second one isn't. That means that the first read lock was acquired, but the second never will be +because starting to acquire the write lock blocks any other read locks from being acquired. At the +same time, the write lock will also never finish acquiring, because it waits for all read locks to +be released, and the first read lock won't be released before the second read lock is acquired. + In all of these cases: - make critical sections as short as possible, and - do not depend on other tasks or locks inside the critical section. diff --git a/tower-batch/src/lib.rs b/tower-batch/src/lib.rs index 6a6e1b88792..2cf9f770337 100644 --- a/tower-batch/src/lib.rs +++ b/tower-batch/src/lib.rs @@ -85,13 +85,6 @@ //! control logic, as it will receive explicit [`Flush`](BatchControl::Flush) //! requests from the wrapper. -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![deny(rust_2021_compatibility)] -#![forbid(unsafe_code)] - pub mod error; pub mod future; mod layer; diff --git a/tower-batch/tests/ed25519.rs b/tower-batch/tests/ed25519.rs index e96a4bec5a8..5906ad2a3f5 100644 --- a/tower-batch/tests/ed25519.rs +++ b/tower-batch/tests/ed25519.rs @@ -1,9 +1,3 @@ -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![forbid(unsafe_code)] - use std::{ future::Future, mem, diff --git a/tower-batch/tests/worker.rs b/tower-batch/tests/worker.rs index bc21209b633..7bec206b316 100644 --- a/tower-batch/tests/worker.rs +++ b/tower-batch/tests/worker.rs @@ -1,9 +1,3 @@ -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![forbid(unsafe_code)] - use std::time::Duration; use tokio_test::{assert_pending, assert_ready, assert_ready_err, task}; use tower::{Service, ServiceExt}; diff --git a/tower-fallback/src/lib.rs b/tower-fallback/src/lib.rs index 2cb4d20eb8a..01249d85bce 100644 --- a/tower-fallback/src/lib.rs +++ b/tower-fallback/src/lib.rs @@ -10,13 +10,6 @@ //! //! [aws-fallback]: https://aws.amazon.com/builders-library/avoiding-fallback-in-distributed-systems/ -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![deny(rust_2021_compatibility)] -#![forbid(unsafe_code)] - pub mod future; mod service; diff --git a/tower-fallback/tests/fallback.rs b/tower-fallback/tests/fallback.rs index 5ca1d3400a2..e84ab05f581 100644 --- a/tower-fallback/tests/fallback.rs +++ b/tower-fallback/tests/fallback.rs @@ -1,9 +1,3 @@ -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![forbid(unsafe_code)] - use tower::{service_fn, Service, ServiceExt}; use tower_fallback::Fallback; diff --git a/zebra-chain/benches/block.rs b/zebra-chain/benches/block.rs index cd9641cccd4..71194e1a614 100644 --- a/zebra-chain/benches/block.rs +++ b/zebra-chain/benches/block.rs @@ -1,9 +1,5 @@ -// Standard lints // Disabled due to warnings in criterion macros -//#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![forbid(unsafe_code)] +#![allow(missing_docs)] use std::io::Cursor; diff --git a/zebra-chain/benches/redpallas.rs b/zebra-chain/benches/redpallas.rs index 0160891d901..49fbf52217e 100644 --- a/zebra-chain/benches/redpallas.rs +++ b/zebra-chain/benches/redpallas.rs @@ -1,6 +1,7 @@ //! Benchmarks for batch verifiication of RedPallas signatures. -use std::convert::TryFrom; +// Disabled due to warnings in criterion macros +#![allow(missing_docs)] use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; use rand::{thread_rng, Rng}; diff --git a/zebra-chain/build.rs b/zebra-chain/build.rs index 91ba008f76c..77b5d3202e7 100644 --- a/zebra-chain/build.rs +++ b/zebra-chain/build.rs @@ -1,3 +1,8 @@ +//! Build script for zebra-chain. +//! +//! Turns the environmental variable `$TEST_FAKE_ACTIVATION_HEIGHTS` +//! into the Rust configuration `cfg(test_fake_activation_heights)`. + use std::env; fn main() { diff --git a/zebra-chain/src/lib.rs b/zebra-chain/src/lib.rs index 79d6a0056a6..848090abc8d 100644 --- a/zebra-chain/src/lib.rs +++ b/zebra-chain/src/lib.rs @@ -6,12 +6,6 @@ #![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")] #![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")] #![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_chain")] -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![deny(rust_2021_compatibility)] -#![forbid(unsafe_code)] // Required by bitvec! macro #![recursion_limit = "256"] diff --git a/zebra-client/src/lib.rs b/zebra-client/src/lib.rs index 298924110ea..d7d37127711 100644 --- a/zebra-client/src/lib.rs +++ b/zebra-client/src/lib.rs @@ -3,9 +3,3 @@ #![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")] #![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")] #![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_client")] -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![deny(rust_2021_compatibility)] -#![forbid(unsafe_code)] diff --git a/zebra-consensus/src/lib.rs b/zebra-consensus/src/lib.rs index 6d27f6787ea..86a0e0f9970 100644 --- a/zebra-consensus/src/lib.rs +++ b/zebra-consensus/src/lib.rs @@ -33,13 +33,6 @@ #![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")] #![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")] #![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_consensus")] -// Standard lints -// Warn on missing docs for all modules after cleaning the API surface -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![deny(rust_2021_compatibility)] -#![forbid(unsafe_code)] mod block; mod checkpoint; diff --git a/zebra-network/src/lib.rs b/zebra-network/src/lib.rs index 02f69188235..fd547bb0db3 100644 --- a/zebra-network/src/lib.rs +++ b/zebra-network/src/lib.rs @@ -119,12 +119,6 @@ #![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")] #![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")] #![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_network")] -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![deny(rust_2021_compatibility)] -#![forbid(unsafe_code)] #[macro_use] extern crate pin_project; diff --git a/zebra-rpc/src/lib.rs b/zebra-rpc/src/lib.rs index 02f87917a0d..5515e74018c 100644 --- a/zebra-rpc/src/lib.rs +++ b/zebra-rpc/src/lib.rs @@ -3,9 +3,3 @@ #![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")] #![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")] #![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_rpc")] -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![deny(rust_2021_compatibility)] -#![forbid(unsafe_code)] diff --git a/zebra-script/src/lib.rs b/zebra-script/src/lib.rs index effdda7d277..ab4208f6959 100644 --- a/zebra-script/src/lib.rs +++ b/zebra-script/src/lib.rs @@ -2,14 +2,10 @@ #![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")] #![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")] #![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_script")] -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![deny(rust_2021_compatibility)] -// we allow unsafe code, so we can call zcash_script - -use std::{convert::TryInto, sync::Arc}; +// We allow unsafe code, so we can call zcash_script +#![allow(unsafe_code)] + +use std::sync::Arc; use displaydoc::Display; use thiserror::Error; diff --git a/zebra-state/build.rs b/zebra-state/build.rs index 91ba008f76c..a03774a1620 100644 --- a/zebra-state/build.rs +++ b/zebra-state/build.rs @@ -1,3 +1,8 @@ +//! Build script for zebra-state. +//! +//! Turns the environmental variable `$TEST_FAKE_ACTIVATION_HEIGHTS` +//! into the Rust configuration `cfg(test_fake_activation_heights)`. + use std::env; fn main() { diff --git a/zebra-state/src/lib.rs b/zebra-state/src/lib.rs index c01a633f7ef..a8f80441a80 100644 --- a/zebra-state/src/lib.rs +++ b/zebra-state/src/lib.rs @@ -11,12 +11,6 @@ #![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")] #![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")] #![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_state")] -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![deny(rust_2021_compatibility)] -#![forbid(unsafe_code)] #[cfg(any(test, feature = "proptest-impl"))] mod arbitrary; diff --git a/zebra-state/src/service/chain_tip.rs b/zebra-state/src/service/chain_tip.rs index f2983cf0788..0174675b1a0 100644 --- a/zebra-state/src/service/chain_tip.rs +++ b/zebra-state/src/service/chain_tip.rs @@ -131,8 +131,8 @@ impl ChainTipSender { active_value: None, }; - let current = LatestChainTip::new(receiver.clone()); - let change = ChainTipChange::new(receiver, network); + let current = LatestChainTip::new(receiver); + let change = ChainTipChange::new(current.clone(), network); sender.update(initial_tip); @@ -246,47 +246,80 @@ impl LatestChainTip { fn new(receiver: watch::Receiver) -> Self { Self { receiver } } + + /// Retrieve a result `R` from the current [`ChainTipBlock`], if it's available. + /// + /// This helper method is a shorter way to borrow the value from the [`watch::Receiver`] and + /// extract some information from it, while also adding the current chain tip block's fields as + /// records to the current span. + /// + /// A single read lock is kept during the execution of the method, and it is dropped at the end + /// of it. + /// + /// # Correctness + /// + /// To prevent deadlocks: + /// + /// - `receiver.borrow()` should not be called before this method while in the same scope. + /// - `receiver.borrow()` should not be called inside the `action` closure. + /// + /// It is important to avoid calling `borrow` more than once in the same scope, which + /// effectively tries to acquire two read locks to the shared data in the watch channel. If + /// that is done, there's a chance that the [`watch::Sender`] tries to send a value, which + /// starts acquiring a write-lock, and prevents further read-locks from being acquired until + /// the update is finished. + /// + /// What can happen in that scenario is: + /// + /// 1. The receiver manages to acquire a read-lock for the first `borrow` + /// 2. The sender starts acquiring the write-lock + /// 3. The receiver fails to acquire a read-lock for the second `borrow` + /// + /// Now both the sender and the receivers hang, because the sender won't release the lock until + /// it can update the value, and the receiver won't release its first read-lock until it + /// acquires the second read-lock and finishes what it's doing. + fn with_chain_tip_block(&self, action: impl FnOnce(&ChainTipBlock) -> R) -> Option { + let span = tracing::Span::current(); + let borrow_guard = self.receiver.borrow(); + let chain_tip_block = borrow_guard.as_ref(); + + span.record( + "height", + &tracing::field::debug(chain_tip_block.map(|block| block.height)), + ); + span.record( + "hash", + &tracing::field::debug(chain_tip_block.map(|block| block.hash)), + ); + span.record( + "transaction_count", + &tracing::field::debug(chain_tip_block.map(|block| block.transaction_hashes.len())), + ); + + chain_tip_block.map(action) + } } impl ChainTip for LatestChainTip { /// Return the height of the best chain tip. - #[instrument( - skip(self), - fields( - height = ?self.receiver.borrow().as_ref().map(|block| block.height), - hash = ?self.receiver.borrow().as_ref().map(|block| block.hash), - ))] + #[instrument(skip(self))] fn best_tip_height(&self) -> Option { - self.receiver.borrow().as_ref().map(|block| block.height) + self.with_chain_tip_block(|block| block.height) } /// Return the block hash of the best chain tip. - #[instrument( - skip(self), - fields( - height = ?self.receiver.borrow().as_ref().map(|block| block.height), - hash = ?self.receiver.borrow().as_ref().map(|block| block.hash), - ))] + #[instrument(skip(self))] fn best_tip_hash(&self) -> Option { - self.receiver.borrow().as_ref().map(|block| block.hash) + self.with_chain_tip_block(|block| block.hash) } /// Return the mined transaction IDs of the transactions in the best chain tip block. /// /// All transactions with these mined IDs should be rejected from the mempool, /// even if their authorizing data is different. - #[instrument( - skip(self), - fields( - height = ?self.receiver.borrow().as_ref().map(|block| block.height), - hash = ?self.receiver.borrow().as_ref().map(|block| block.hash), - transaction_count = ?self.receiver.borrow().as_ref().map(|block| block.transaction_hashes.len()), - ))] + #[instrument(skip(self))] fn best_tip_mined_transaction_ids(&self) -> Arc<[transaction::Hash]> { - self.receiver - .borrow() - .as_ref() - .map(|block| block.transaction_hashes.clone()) + self.with_chain_tip_block(|block| block.transaction_hashes.clone()) .unwrap_or_else(|| Arc::new([])) } } @@ -306,7 +339,7 @@ impl ChainTip for LatestChainTip { #[derive(Debug)] pub struct ChainTipChange { /// The receiver for the current chain tip's data. - receiver: watch::Receiver, + latest_chain_tip: LatestChainTip, /// The most recent [`block::Hash`] provided by this instance. /// @@ -377,8 +410,6 @@ impl ChainTipChange { #[instrument( skip(self), fields( - current_height = ?self.receiver.borrow().as_ref().map(|block| block.height), - current_hash = ?self.receiver.borrow().as_ref().map(|block| block.hash), last_change_hash = ?self.last_change_hash, network = ?self.network, ))] @@ -400,25 +431,25 @@ impl ChainTipChange { #[instrument( skip(self), fields( - current_height = ?self.receiver.borrow().as_ref().map(|block| block.height), - current_hash = ?self.receiver.borrow().as_ref().map(|block| block.hash), last_change_hash = ?self.last_change_hash, network = ?self.network, ))] pub fn last_tip_change(&mut self) -> Option { - // Obtain the tip block. - let block = self.best_tip_block()?; + let block = self.latest_chain_tip.with_chain_tip_block(|block| { + if Some(block.hash) != self.last_change_hash { + Some(block.clone()) + } else { + // Ignore an unchanged tip. + None + } + })??; - // Ignore an unchanged tip. - if Some(block.hash) == self.last_change_hash { - return None; - } + let block_hash = block.hash; + let tip_action = self.action(block); - let action = self.action(block.clone()); + self.last_change_hash = Some(block_hash); - self.last_change_hash = Some(block.hash); - - Some(action) + Some(tip_action) } /// Return an action based on `block` and the last change we returned. @@ -466,10 +497,10 @@ impl ChainTipChange { } } - /// Create a new [`ChainTipChange`] from a watch channel receiver and [`Network`]. - fn new(receiver: watch::Receiver, network: Network) -> Self { + /// Create a new [`ChainTipChange`] from a [`LatestChainTip`] receiver and [`Network`]. + fn new(latest_chain_tip: LatestChainTip, network: Network) -> Self { Self { - receiver, + latest_chain_tip, last_change_hash: None, network, } @@ -485,37 +516,38 @@ impl ChainTipChange { // after the change notification. // Any block update after the change will do, // we'll catch up with the tip after the next change. - self.receiver.changed().await?; - - // Wait until there is actually Some block, - // so we don't have `Option`s inside `TipAction`s. - if let Some(block) = self.best_tip_block() { - // Wait until we have a new block - // - // last_tip_change() updates last_change_hash, but it doesn't call receiver.changed(). - // So code that uses both sync and async methods can have spurious pending changes. - // - // TODO: use `receiver.borrow_and_update()` in `best_tip_block()`, - // once we upgrade to tokio 1.0 (#2200) - // and remove this extra check - if Some(block.hash) != self.last_change_hash { - return Ok(block); - } + self.latest_chain_tip.receiver.changed().await?; + + // Wait until we have a new block + // + // last_tip_change() updates last_change_hash, but it doesn't call receiver.changed(). + // So code that uses both sync and async methods can have spurious pending changes. + // + // TODO: use `receiver.borrow_and_update()` in `with_chain_tip_block()`, + // once we upgrade to tokio 1.0 (#2200) + // and remove this extra check + let new_block = self + .latest_chain_tip + .with_chain_tip_block(|block| { + if Some(block.hash) != self.last_change_hash { + Some(block.clone()) + } else { + None + } + }) + .flatten(); + + if let Some(block) = new_block { + return Ok(block); } } } - - /// Return the current best [`ChainTipBlock`], - /// or `None` if no block has been committed yet. - fn best_tip_block(&self) -> Option { - self.receiver.borrow().clone() - } } impl Clone for ChainTipChange { fn clone(&self) -> Self { Self { - receiver: self.receiver.clone(), + latest_chain_tip: self.latest_chain_tip.clone(), // clear the previous change hash, so the first action is a reset last_change_hash: None, diff --git a/zebra-state/tests/basic.rs b/zebra-state/tests/basic.rs index 0c8048c85bd..9ecb5516e07 100644 --- a/zebra-state/tests/basic.rs +++ b/zebra-state/tests/basic.rs @@ -1,9 +1,3 @@ -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![forbid(unsafe_code)] - use color_eyre::eyre::Report; use once_cell::sync::Lazy; use std::sync::Arc; diff --git a/zebra-test/src/lib.rs b/zebra-test/src/lib.rs index b1c30d03e52..093779a3db6 100644 --- a/zebra-test/src/lib.rs +++ b/zebra-test/src/lib.rs @@ -2,12 +2,6 @@ #![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")] #![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")] #![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_test")] -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![deny(rust_2021_compatibility)] -#![forbid(unsafe_code)] // Each lazy_static variable uses additional recursion #![recursion_limit = "512"] diff --git a/zebra-test/src/service_extensions.rs b/zebra-test/src/service_extensions.rs index 0aa9648e331..38ad27f2d7b 100644 --- a/zebra-test/src/service_extensions.rs +++ b/zebra-test/src/service_extensions.rs @@ -8,12 +8,15 @@ use tower::{Service, ServiceExt}; /// An extension trait to check if a [`Service`] is immediately ready to be called. pub trait IsReady: Service { /// Poll the [`Service`] once, and return true if it is immediately ready to be called. + #[allow(clippy::wrong_self_convention)] fn is_ready(&mut self) -> BoxFuture; /// Poll the [`Service`] once, and return true if it is pending. + #[allow(clippy::wrong_self_convention)] fn is_pending(&mut self) -> BoxFuture; /// Poll the [`Service`] once, and return true if it has failed. + #[allow(clippy::wrong_self_convention)] fn is_failed(&mut self) -> BoxFuture; } diff --git a/zebra-test/tests/command.rs b/zebra-test/tests/command.rs index 12dba0b9882..4a4823010d8 100644 --- a/zebra-test/tests/command.rs +++ b/zebra-test/tests/command.rs @@ -1,9 +1,3 @@ -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![forbid(unsafe_code)] - use std::{process::Command, time::Duration}; use color_eyre::eyre::Result; diff --git a/zebra-test/tests/transcript.rs b/zebra-test/tests/transcript.rs index b8d3ffbb039..8818cb7f9fa 100644 --- a/zebra-test/tests/transcript.rs +++ b/zebra-test/tests/transcript.rs @@ -1,9 +1,3 @@ -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![forbid(unsafe_code)] - use tower::{Service, ServiceExt}; use zebra_test::transcript::ExpectedTranscriptError; use zebra_test::transcript::Transcript; diff --git a/zebra-utils/src/bin/zebra-checkpoints/main.rs b/zebra-utils/src/bin/zebra-checkpoints/main.rs index 634e7a9bbcf..f8523404961 100644 --- a/zebra-utils/src/bin/zebra-checkpoints/main.rs +++ b/zebra-utils/src/bin/zebra-checkpoints/main.rs @@ -8,12 +8,6 @@ //! zebra-consensus accepts an ordered list of checkpoints, starting with the //! genesis block. Checkpoint heights can be chosen arbitrarily. -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![forbid(unsafe_code)] - use color_eyre::eyre::{ensure, Result}; use serde_json::Value; use std::process::Stdio; diff --git a/zebra-utils/src/lib.rs b/zebra-utils/src/lib.rs index d619fb0df66..b1306e7deee 100644 --- a/zebra-utils/src/lib.rs +++ b/zebra-utils/src/lib.rs @@ -4,9 +4,3 @@ #![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")] #![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")] #![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_utils")] -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![deny(rust_2021_compatibility)] -#![forbid(unsafe_code)] diff --git a/zebrad/build.rs b/zebrad/build.rs index 318c31224f9..66c3c4034b7 100644 --- a/zebrad/build.rs +++ b/zebrad/build.rs @@ -1,3 +1,8 @@ +//! Build script for zebrad. +//! +//! Turns Zebra version information into build-time environmental variables, +//! so that it can be compiled into `zebrad`, and used in diagnostics. + use vergen::{vergen, Config, SemverKind, ShaKind}; /// Disable vergen env vars that could cause spurious reproducible build diff --git a/zebrad/src/bin/zebrad/main.rs b/zebrad/src/bin/zebrad/main.rs index 8717bcbbf9c..9856713a683 100644 --- a/zebrad/src/bin/zebrad/main.rs +++ b/zebrad/src/bin/zebrad/main.rs @@ -1,11 +1,5 @@ //! Main entry point for Zebrad -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![forbid(unsafe_code)] - use zebrad::application::APPLICATION; /// Boot Zebrad diff --git a/zebrad/src/lib.rs b/zebrad/src/lib.rs index cfa4ac629ca..0e1ba85ac59 100644 --- a/zebrad/src/lib.rs +++ b/zebrad/src/lib.rs @@ -17,12 +17,6 @@ #![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")] #![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")] #![doc(html_root_url = "https://doc.zebra.zfnd.org/zebrad")] -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![deny(rust_2021_compatibility)] -#![forbid(unsafe_code)] // Tracing causes false positives on this lint: // https://github.com/tokio-rs/tracing/issues/553 #![allow(clippy::cognitive_complexity)] diff --git a/zebrad/tests/acceptance.rs b/zebrad/tests/acceptance.rs index 7bac70bcce9..a7558103ff3 100644 --- a/zebrad/tests/acceptance.rs +++ b/zebrad/tests/acceptance.rs @@ -21,12 +21,6 @@ //! or you have poor network connectivity, //! skip all the network tests by setting the `ZEBRA_SKIP_NETWORK_TESTS` environmental variable. -// Standard lints -#![warn(missing_docs)] -#![allow(clippy::try_err)] -#![deny(clippy::await_holding_lock)] -#![forbid(unsafe_code)] - use color_eyre::{ eyre::{Result, WrapErr}, Help,