Standardise clippy lints and require docs (#2238)

* Standardise lints across Zebra crates, and add missing docs

The only remaining module with missing docs is `zebra_test::command`

* Todo -> TODO

* Clarify what a transcript ErrorChecker does

Also change `Error` -> `BoxError`

* TransError -> ExpectedTranscriptError

* Output Descriptions -> Output descriptions
This commit is contained in:
teor 2021-06-04 08:48:40 +10:00 committed by GitHub
parent 9416b5d5cd
commit 2f0f379a9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 390 additions and 232 deletions

View File

@ -55,7 +55,7 @@
- Compute SigHash on data to be signed and _previous_ data to be signed
- Check joinsplit signature on data to be signed
- If fail, check on previous data to be signed : https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L971
- Check Spend/Output Descriptions
- Check Spend/Output descriptions
- Check Spends: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L998
- Check Outputs: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L1018
- Check final balances: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L1036

View File

@ -85,6 +85,12 @@
//! 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)]
#![forbid(unsafe_code)]
pub mod error;
pub mod future;
mod layer;

View File

@ -1,3 +1,9 @@
// Standard lints
#![warn(missing_docs)]
#![allow(clippy::try_err)]
#![deny(clippy::await_holding_lock)]
#![forbid(unsafe_code)]
use std::{
future::Future,
mem,

View File

@ -1,3 +1,9 @@
// 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};

View File

@ -10,9 +10,16 @@
//!
//! [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)]
#![forbid(unsafe_code)]
pub mod future;
mod service;
pub use self::service::Fallback;
/// A boxed type-erased `std::error::Error` that can be sent between threads.
pub type BoxedError = Box<dyn std::error::Error + Send + Sync + 'static>;

View File

@ -1,3 +1,9 @@
// 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;

View File

@ -1,3 +1,10 @@
// Standard lints
// Disabled due to warnings in criterion macros
//#![warn(missing_docs)]
#![allow(clippy::try_err)]
#![deny(clippy::await_holding_lock)]
#![forbid(unsafe_code)]
use std::io::Cursor;
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};

View File

@ -1,5 +1,4 @@
//! Blocks and block-related structures (heights, headers, etc.)
#![allow(clippy::unit_arg)]
mod commitment;
mod hash;

View File

@ -171,7 +171,7 @@ pub struct ChainHistoryBlockTxAuthCommitmentHash([u8; 32]);
/// all possible verification failures enumerates the consensus rules we
/// implement, and ensures that we don't reject blocks or transactions
/// for a non-enumerated reason.
#[allow(dead_code)]
#[allow(dead_code, missing_docs)]
#[derive(Error, Debug, PartialEq)]
pub enum CommitmentError {
#[error("invalid pre-Sapling reserved committment: expected all zeroes, actual: {actual:?}")]

View File

@ -84,6 +84,7 @@ pub struct Header {
/// TODO: Use this error as the source for zebra_consensus::error::BlockError::Time,
/// and make `BlockError::Time` add additional context.
/// See https://github.com/ZcashFoundation/zebra/issues/1021 for more details.
#[allow(missing_docs)]
#[derive(Error, Debug)]
pub enum BlockTimeError {
#[error("invalid time {0:?} in block header {1:?} {2:?}: block time is more than 2 hours in the future ({3:?}). Hint: check your machine's date, time, and time zone.")]
@ -126,7 +127,11 @@ impl Header {
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
pub struct CountedHeader {
/// The header for a block
pub header: Header,
/// The number of transactions that come after the header
///
/// TODO: should this always be zero? (#1924)
pub transaction_count: usize,
}

View File

@ -1,3 +1,5 @@
//! Tests for Zebra blocks
// XXX generate should be rewritten as strategies
#[cfg(any(test, feature = "bench"))]
pub mod generate;

View File

@ -1,4 +1,4 @@
//! Core Zcash data structures. 🦓
//! Core Zcash data structures.
//!
//! This crate provides definitions of core data structures for Zcash, such as
//! blocks, transactions, addresses, etc.
@ -6,14 +6,11 @@
#![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)]
// The actual lints we want to disable
#![allow(clippy::unnecessary_wraps)]
// Disable some broken or unwanted clippy nightly lints
// Build without warnings on nightly 2021-01-17 and later and stable 1.51 and later
#![allow(unknown_lints)]
// Disable old lint warnings on nightly until 1.51 is stable
#![allow(renamed_and_removed_lints)]
#![deny(clippy::await_holding_lock)]
#![forbid(unsafe_code)]
#[macro_use]
extern crate serde;

View File

@ -30,7 +30,7 @@ impl Arbitrary for TransmissionKey {
proptest! {
#[test]
#[allow(clone_on_copy, cmp_owned)]
#[allow(clippy::clone_on_copy, clippy::cmp_owned)]
fn generate_keys(spending_key in any::<SpendingKey>()) {
zebra_test::init();

View File

@ -1,3 +1,5 @@
//! RedPallas cryptographic primitives.
// -*- mode: rust; -*-
//
// This file is part of redjubjub.
@ -12,6 +14,7 @@ use group::GroupEncoding;
use halo2::pasta::pallas;
mod constants;
#[allow(missing_docs)]
mod error;
mod hash;
mod signature;

View File

@ -147,7 +147,7 @@ impl NoteCommitment {
}
/// A Homomorphic Pedersen commitment to the value of a note, used in Spend and
/// Output Descriptions.
/// Output descriptions.
///
/// https://zips.z.cash/protocol/protocol.pdf#concretehomomorphiccommit
#[derive(Clone, Copy, Deserialize, PartialEq, Serialize)]

View File

@ -1,3 +1,7 @@
//! Sapling _Output descriptions_, as described in [protocol specification §7.4][ps].
//!
//! [ps]: https://zips.z.cash/protocol/protocol.pdf#outputencoding
use std::io;
use crate::{

View File

@ -1,3 +1,5 @@
//! Arbitrary data generation for serialization proptests
use super::{read_zcash::canonical_ip_addr, DateTime32};
use chrono::{TimeZone, Utc, MAX_DATETIME, MIN_DATETIME};
use proptest::{arbitrary::any, prelude::*};

View File

@ -1,3 +1,5 @@
//! Arbitrary data generation for transaction proptests
use std::{convert::TryInto, sync::Arc};
use chrono::{TimeZone, Utc};

View File

@ -1,3 +1,5 @@
//! Signature hashes for Zcash transactions
use super::Transaction;
use crate::{
@ -29,9 +31,13 @@ const ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZcashSOutputHas
bitflags::bitflags! {
/// The different SigHash types, as defined in https://zips.z.cash/zip-0143
pub struct HashType: u32 {
/// Sign all the outputs
const ALL = 0b0000_0001;
/// Sign none of the outputs - anyone can spend
const NONE = 0b0000_0010;
/// Sign one of the outputs - anyone can spend the rest
const SINGLE = Self::ALL.bits | Self::NONE.bits;
/// Anyone can add inputs to this transaction
const ANYONECANPAY = 0b1000_0000;
}
}

View File

@ -132,6 +132,7 @@ impl fmt::Debug for ExpandedDifficulty {
pub struct Work(u128);
impl Work {
/// Return the inner `u128` value.
pub fn as_u128(self) -> u128 {
self.0
}

View File

@ -1,3 +1,10 @@
//! A Zebra wallet client
#![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)]
#![forbid(unsafe_code)]

View File

@ -18,39 +18,40 @@ use zebra_chain::{
transaction::{arbitrary::transaction_to_fake_v5, Transaction},
work::difficulty::{ExpandedDifficulty, INVALID_COMPACT_DIFFICULTY},
};
use zebra_test::transcript::{TransError, Transcript};
use zebra_test::transcript::{ExpectedTranscriptError, Transcript};
static VALID_BLOCK_TRANSCRIPT: Lazy<Vec<(Arc<Block>, Result<block::Hash, TransError>)>> =
Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap()
.into();
let hash = Ok(block.as_ref().into());
vec![(block, hash)]
});
static VALID_BLOCK_TRANSCRIPT: Lazy<
Vec<(Arc<Block>, Result<block::Hash, ExpectedTranscriptError>)>,
> = Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap()
.into();
let hash = Ok(block.as_ref().into());
vec![(block, hash)]
});
static INVALID_TIME_BLOCK_TRANSCRIPT: Lazy<Vec<(Arc<Block>, Result<block::Hash, TransError>)>> =
Lazy::new(|| {
let mut block: Block =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap();
static INVALID_TIME_BLOCK_TRANSCRIPT: Lazy<
Vec<(Arc<Block>, Result<block::Hash, ExpectedTranscriptError>)>,
> = Lazy::new(|| {
let mut block: Block =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..]).unwrap();
// Modify the block's time
// Changing the block header also invalidates the header hashes, but
// those checks should be performed later in validation, because they
// are more expensive.
let three_hours_in_the_future = Utc::now()
.checked_add_signed(chrono::Duration::hours(3))
.ok_or_else(|| eyre!("overflow when calculating 3 hours in the future"))
.unwrap();
block.header.time = three_hours_in_the_future;
// Modify the block's time
// Changing the block header also invalidates the header hashes, but
// those checks should be performed later in validation, because they
// are more expensive.
let three_hours_in_the_future = Utc::now()
.checked_add_signed(chrono::Duration::hours(3))
.ok_or_else(|| eyre!("overflow when calculating 3 hours in the future"))
.unwrap();
block.header.time = three_hours_in_the_future;
vec![(Arc::new(block), Err(TransError::Any))]
});
vec![(Arc::new(block), Err(ExpectedTranscriptError::Any))]
});
static INVALID_HEADER_SOLUTION_TRANSCRIPT: Lazy<
Vec<(Arc<Block>, Result<block::Hash, TransError>)>,
Vec<(Arc<Block>, Result<block::Hash, ExpectedTranscriptError>)>,
> = Lazy::new(|| {
let mut block: Block =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..]).unwrap();
@ -58,50 +59,49 @@ static INVALID_HEADER_SOLUTION_TRANSCRIPT: Lazy<
// Change nonce to something invalid
block.header.nonce = [0; 32];
vec![(Arc::new(block), Err(TransError::Any))]
vec![(Arc::new(block), Err(ExpectedTranscriptError::Any))]
});
static INVALID_COINBASE_TRANSCRIPT: Lazy<Vec<(Arc<Block>, Result<block::Hash, TransError>)>> =
Lazy::new(|| {
let header =
block::Header::zcash_deserialize(&zebra_test::vectors::DUMMY_HEADER[..]).unwrap();
static INVALID_COINBASE_TRANSCRIPT: Lazy<
Vec<(Arc<Block>, Result<block::Hash, ExpectedTranscriptError>)>,
> = Lazy::new(|| {
let header = block::Header::zcash_deserialize(&zebra_test::vectors::DUMMY_HEADER[..]).unwrap();
// Test 1: Empty transaction
let block1 = Block {
header,
transactions: Vec::new(),
};
// Test 1: Empty transaction
let block1 = Block {
header,
transactions: Vec::new(),
};
// Test 2: Transaction at first position is not coinbase
let mut transactions = Vec::new();
let tx = zebra_test::vectors::DUMMY_TX1
.zcash_deserialize_into()
.unwrap();
transactions.push(tx);
let block2 = Block {
header,
transactions,
};
// Test 2: Transaction at first position is not coinbase
let mut transactions = Vec::new();
let tx = zebra_test::vectors::DUMMY_TX1
.zcash_deserialize_into()
.unwrap();
transactions.push(tx);
let block2 = Block {
header,
transactions,
};
// Test 3: Invalid coinbase position
let mut block3 =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap();
assert_eq!(block3.transactions.len(), 1);
// Test 3: Invalid coinbase position
let mut block3 =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..]).unwrap();
assert_eq!(block3.transactions.len(), 1);
// Extract the coinbase transaction from the block
let coinbase_transaction = block3.transactions.get(0).unwrap().clone();
// Extract the coinbase transaction from the block
let coinbase_transaction = block3.transactions.get(0).unwrap().clone();
// Add another coinbase transaction to block
block3.transactions.push(coinbase_transaction);
assert_eq!(block3.transactions.len(), 2);
// Add another coinbase transaction to block
block3.transactions.push(coinbase_transaction);
assert_eq!(block3.transactions.len(), 2);
vec![
(Arc::new(block1), Err(TransError::Any)),
(Arc::new(block2), Err(TransError::Any)),
(Arc::new(block3), Err(TransError::Any)),
]
});
vec![
(Arc::new(block1), Err(ExpectedTranscriptError::Any)),
(Arc::new(block2), Err(ExpectedTranscriptError::Any)),
(Arc::new(block3), Err(ExpectedTranscriptError::Any)),
]
});
// TODO: enable this test after implementing contextual verification
// #[tokio::test]

View File

@ -1,3 +1,8 @@
//! Top-level semantic block verification for Zebra.
//!
//! Verifies blocks using the [`CheckpointVerifier`] or full [`BlockVerifier`],
//! depending on the config and block height.
#[cfg(test)]
mod tests;
@ -52,6 +57,7 @@ where
max_checkpoint_height: block::Height,
}
/// An error while semantically verifying a block.
#[derive(Debug, Display, Error)]
pub enum VerifyChainError {
/// block could not be checkpointed

View File

@ -12,7 +12,7 @@ use zebra_chain::{
serialization::ZcashDeserialize,
};
use zebra_state as zs;
use zebra_test::transcript::{TransError, Transcript};
use zebra_test::transcript::{ExpectedTranscriptError, Transcript};
use crate::Config;
@ -72,59 +72,63 @@ async fn verifiers_from_network(
(chain_verifier, state_service)
}
static BLOCK_VERIFY_TRANSCRIPT_GENESIS: Lazy<Vec<(Arc<Block>, Result<block::Hash, TransError>)>> =
Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap()
.into();
let hash = Ok(block.hash());
static BLOCK_VERIFY_TRANSCRIPT_GENESIS: Lazy<
Vec<(Arc<Block>, Result<block::Hash, ExpectedTranscriptError>)>,
> = Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap()
.into();
let hash = Ok(block.hash());
vec![(block, hash)]
});
vec![(block, hash)]
});
static BLOCK_VERIFY_TRANSCRIPT_GENESIS_FAIL: Lazy<
Vec<(Arc<Block>, Result<block::Hash, TransError>)>,
Vec<(Arc<Block>, Result<block::Hash, ExpectedTranscriptError>)>,
> = Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap()
.into();
vec![(block, Err(TransError::Any))]
vec![(block, Err(ExpectedTranscriptError::Any))]
});
static NO_COINBASE_TRANSCRIPT: Lazy<Vec<(Arc<Block>, Result<block::Hash, TransError>)>> =
Lazy::new(|| {
let block = block_no_transactions();
static NO_COINBASE_TRANSCRIPT: Lazy<
Vec<(Arc<Block>, Result<block::Hash, ExpectedTranscriptError>)>,
> = Lazy::new(|| {
let block = block_no_transactions();
vec![(Arc::new(block), Err(TransError::Any))]
});
vec![(Arc::new(block), Err(ExpectedTranscriptError::Any))]
});
static NO_COINBASE_STATE_TRANSCRIPT: Lazy<Vec<(zs::Request, Result<zs::Response, TransError>)>> =
Lazy::new(|| {
let block = block_no_transactions();
let hash = block.hash();
static NO_COINBASE_STATE_TRANSCRIPT: Lazy<
Vec<(zs::Request, Result<zs::Response, ExpectedTranscriptError>)>,
> = Lazy::new(|| {
let block = block_no_transactions();
let hash = block.hash();
vec![(
zs::Request::Block(hash.into()),
Ok(zs::Response::Block(None)),
)]
});
vec![(
zs::Request::Block(hash.into()),
Ok(zs::Response::Block(None)),
)]
});
static STATE_VERIFY_TRANSCRIPT_GENESIS: Lazy<Vec<(zs::Request, Result<zs::Response, TransError>)>> =
Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap()
.into();
let hash = block.hash();
static STATE_VERIFY_TRANSCRIPT_GENESIS: Lazy<
Vec<(zs::Request, Result<zs::Response, ExpectedTranscriptError>)>,
> = Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap()
.into();
let hash = block.hash();
vec![(
zs::Request::Block(hash.into()),
Ok(zs::Response::Block(Some(block))),
)]
});
vec![(
zs::Request::Block(hash.into()),
Ok(zs::Response::Block(Some(block))),
)]
});
#[tokio::test]
async fn verify_checkpoint_test() -> Result<(), Report> {

View File

@ -33,18 +33,12 @@
#![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")]
// Re-enable this after cleaning the API surface.
//#![deny(missing_docs)]
// Standard lints
// Warn on missing docs for all modules after cleaning the API surface
#![warn(missing_docs)]
#![allow(clippy::try_err)]
// Disable some broken or unwanted clippy nightly lints
// Build without warnings on nightly 2021-01-17 and later and stable 1.51 and later
#![allow(unknown_lints)]
// Disable old lint warnings on nightly until 1.51 is stable
#![allow(renamed_and_removed_lints)]
// Use the old lint name to build without warnings on stable until 1.51 is stable
#![allow(clippy::unknown_clippy_lints)]
// The actual lints we want to disable
#![allow(clippy::unnecessary_wraps)]
#![deny(clippy::await_holding_lock)]
#![forbid(unsafe_code)]
mod block;
mod checkpoint;
@ -56,6 +50,7 @@ mod script;
mod transaction;
pub mod chain;
#[allow(missing_docs)]
pub mod error;
pub use checkpoint::MAX_CHECKPOINT_BYTE_COUNT;

View File

@ -33,20 +33,11 @@
#![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")]
#![deny(missing_docs)]
// Standard lints
#![warn(missing_docs)]
#![allow(clippy::try_err)]
// Tracing causes false positives on this lint:
// https://github.com/tokio-rs/tracing/issues/553
#![allow(clippy::cognitive_complexity)]
// Disable some broken or unwanted clippy nightly lints
// Build without warnings on nightly 2021-01-17 and later and stable 1.51 and later
#![allow(unknown_lints)]
// Disable old lint warnings on nightly until 1.51 is stable
#![allow(renamed_and_removed_lints)]
// Use the old lint name to build without warnings on stable until 1.51 is stable
#![allow(clippy::unknown_clippy_lints)]
// The actual lints we want to disable
#![allow(clippy::unnecessary_wraps)]
#![deny(clippy::await_holding_lock)]
#![forbid(unsafe_code)]
#[macro_use]
extern crate pin_project;

View File

@ -1,3 +1,10 @@
//! A Zebra remote procedure call interface
#![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)]
#![forbid(unsafe_code)]

View File

@ -2,6 +2,11 @@
#![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)]
// we allow unsafe code to call zcash_script
use displaydoc::Display;
#[cfg(windows)]
@ -82,6 +87,7 @@ impl CachedFfiTransaction {
}
}
/// Returns the transparent inputs for this transaction.
pub fn inputs(&self) -> &[transparent::Input] {
self.transaction.inputs()
}

View File

@ -3,17 +3,11 @@
#![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)]
// Disable some broken or unwanted clippy nightly lints
// Build without warnings on nightly 2021-01-17 and later and stable 1.51 and later
#![allow(unknown_lints)]
// Disable old lint warnings on nightly until 1.51 is stable
#![allow(renamed_and_removed_lints)]
// Use the old lint name to build without warnings on stable until 1.51 is stable
#![allow(clippy::unknown_clippy_lints)]
// The actual lints we want to disable
#![allow(clippy::unnecessary_wraps)]
#![deny(clippy::await_holding_lock)]
#![forbid(unsafe_code)]
mod config;
pub mod constants;

View File

@ -1,51 +1,59 @@
// 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;
use tempdir::TempDir;
use zebra_chain::{block::Block, parameters::Network, serialization::ZcashDeserialize};
use zebra_test::transcript::{TransError, Transcript};
use zebra_test::transcript::{ExpectedTranscriptError, Transcript};
use zebra_state::*;
static COMMIT_FINALIZED_BLOCK_MAINNET: Lazy<Vec<(Request, Result<Response, TransError>)>> =
Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap()
.into();
let block2 = block.clone();
let hash = block.hash();
vec![
(
Request::CommitFinalizedBlock(block.into()),
Ok(Response::Committed(hash)),
),
(
Request::Block(hash.into()),
Ok(Response::Block(Some(block2))),
),
]
});
static COMMIT_FINALIZED_BLOCK_MAINNET: Lazy<
Vec<(Request, Result<Response, ExpectedTranscriptError>)>,
> = Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap()
.into();
let block2 = block.clone();
let hash = block.hash();
vec![
(
Request::CommitFinalizedBlock(block.into()),
Ok(Response::Committed(hash)),
),
(
Request::Block(hash.into()),
Ok(Response::Block(Some(block2))),
),
]
});
static COMMIT_FINALIZED_BLOCK_TESTNET: Lazy<Vec<(Request, Result<Response, TransError>)>> =
Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_TESTNET_GENESIS_BYTES[..])
.unwrap()
.into();
let block2 = block.clone();
let hash = block.hash();
vec![
(
Request::CommitFinalizedBlock(block.into()),
Ok(Response::Committed(hash)),
),
(
Request::Block(hash.into()),
Ok(Response::Block(Some(block2))),
),
]
});
static COMMIT_FINALIZED_BLOCK_TESTNET: Lazy<
Vec<(Request, Result<Response, ExpectedTranscriptError>)>,
> = Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_TESTNET_GENESIS_BYTES[..])
.unwrap()
.into();
let block2 = block.clone();
let hash = block.hash();
vec![
(
Request::CommitFinalizedBlock(block.into()),
Ok(Response::Committed(hash)),
),
(
Request::Block(hash.into()),
Ok(Response::Block(Some(block2))),
),
]
});
#[tokio::test]
async fn check_transcripts_mainnet() -> Result<(), Report> {

View File

@ -1,3 +1,5 @@
//! Launching test commands for Zebra integration and acceptance tests.
use color_eyre::{
eyre::{eyre, Context, Report, Result},
Help, SectionExt,
@ -24,6 +26,7 @@ pub fn test_cmd(command_path: &str, tempdir: &Path) -> Result<Command> {
Ok(cmd)
}
/// Wrappers for `Command` methods to integrate with [`zebra_test`].
pub trait CommandExt {
/// wrapper for `status` fn on `Command` that constructs informative error
/// reports

View File

@ -1,5 +1,12 @@
//! Miscellaneous test code for Zebra.
#![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)]
#![forbid(unsafe_code)]
// Each lazy_static variable uses additional recursion
#![recursion_limit = "256"]
@ -10,6 +17,7 @@ use tracing_subscriber::{fmt, prelude::*, EnvFilter};
use std::sync::Once;
#[allow(missing_docs)]
pub mod command;
pub mod prelude;
pub mod transcript;

View File

@ -1,3 +1,5 @@
//! Common [`zebra_test`] types, traits, and functions.
pub use crate::command::{test_cmd, CommandExt, TestChild};
pub use std::process::Stdio;

View File

@ -13,25 +13,34 @@ use std::{
};
use tower::{Service, ServiceExt};
type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>;
pub type ErrorChecker = fn(Option<Error>) -> Result<(), Error>;
/// An error-checking function: is the value an expected error?
///
/// If the checked error is the expected error, the function should return `Ok(())`.
/// Otherwise, it should just return the checked error, wrapped inside `Err`.
pub type ErrorChecker = fn(Option<BoxError>) -> Result<(), BoxError>;
/// An expected error in a transcript.
#[derive(Debug, Clone)]
pub enum TransError {
pub enum ExpectedTranscriptError {
/// Match any error
Any,
/// Use a validator function to check for matching errors
Exact(Arc<ErrorChecker>),
}
impl TransError {
impl ExpectedTranscriptError {
/// Convert the `verifier` function into an exact error checker
pub fn exact(verifier: ErrorChecker) -> Self {
TransError::Exact(verifier.into())
ExpectedTranscriptError::Exact(verifier.into())
}
fn check(&self, e: Error) -> Result<(), Report> {
/// Check the actual error `e` against this expected error.
fn check(&self, e: BoxError) -> Result<(), Report> {
match self {
TransError::Any => Ok(()),
TransError::Exact(checker) => checker(Some(e)),
ExpectedTranscriptError::Any => Ok(()),
ExpectedTranscriptError::Exact(checker) => checker(Some(e)),
}
.map_err(ErrorCheckerError)
.wrap_err("service returned an error but it didn't match the expected error")
@ -39,29 +48,32 @@ impl TransError {
fn mock(&self) -> Report {
match self {
TransError::Any => eyre!("mock error"),
TransError::Exact(checker) => checker(None).map_err(|e| eyre!(e)).expect_err(
"transcript should correctly produce the expected mock error when passed None",
),
ExpectedTranscriptError::Any => eyre!("mock error"),
ExpectedTranscriptError::Exact(checker) => {
checker(None).map_err(|e| eyre!(e)).expect_err(
"transcript should correctly produce the expected mock error when passed None",
)
}
}
}
}
#[derive(Debug, thiserror::Error)]
#[error("ErrorChecker Error: {0}")]
struct ErrorCheckerError(Error);
struct ErrorCheckerError(BoxError);
/// A transcript: a list of requests and expected results.
#[must_use]
pub struct Transcript<R, S, I>
where
I: Iterator<Item = (R, Result<S, TransError>)>,
I: Iterator<Item = (R, Result<S, ExpectedTranscriptError>)>,
{
messages: I,
}
impl<R, S, I> From<I> for Transcript<R, S, I::IntoIter>
where
I: IntoIterator<Item = (R, Result<S, TransError>)>,
I: IntoIterator<Item = (R, Result<S, ExpectedTranscriptError>)>,
{
fn from(messages: I) -> Self {
Self {
@ -72,14 +84,15 @@ where
impl<R, S, I> Transcript<R, S, I>
where
I: Iterator<Item = (R, Result<S, TransError>)>,
I: Iterator<Item = (R, Result<S, ExpectedTranscriptError>)>,
R: Debug,
S: Debug + Eq,
{
/// Check this transcript against the responses from the `to_check` service
pub async fn check<C>(mut self, mut to_check: C) -> Result<(), Report>
where
C: Service<R, Response = S>,
C::Error: Into<Error>,
C::Error: Into<BoxError>,
{
for (req, expected_rsp) in &mut self.messages {
// These unwraps could propagate errors with the correct
@ -146,7 +159,7 @@ where
impl<R, S, I> Service<R> for Transcript<R, S, I>
where
R: Debug + Eq,
I: Iterator<Item = (R, Result<S, TransError>)>,
I: Iterator<Item = (R, Result<S, ExpectedTranscriptError>)>,
{
type Response = S;
type Error = Report;

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,7 @@
//! Block test vectors
#![allow(missing_docs)]
use hex::FromHex;
use lazy_static::lazy_static;

View File

@ -1,4 +1,8 @@
// Standard lints
#![warn(missing_docs)]
#![allow(clippy::try_err)]
#![deny(clippy::await_holding_lock)]
#![forbid(unsafe_code)]
use std::{process::Command, time::Duration};

View File

@ -1,10 +1,14 @@
// 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::TransError;
use zebra_test::transcript::ExpectedTranscriptError;
use zebra_test::transcript::Transcript;
const TRANSCRIPT_DATA: [(&str, Result<&str, TransError>); 4] = [
const TRANSCRIPT_DATA: [(&str, Result<&str, ExpectedTranscriptError>); 4] = [
("req1", Ok("rsp1")),
("req2", Ok("rsp2")),
("req3", Ok("rsp3")),
@ -52,11 +56,11 @@ async fn self_check() {
#[error("Error")]
struct Error;
const TRANSCRIPT_DATA2: [(&str, Result<&str, TransError>); 4] = [
const TRANSCRIPT_DATA2: [(&str, Result<&str, ExpectedTranscriptError>); 4] = [
("req1", Ok("rsp1")),
("req2", Ok("rsp2")),
("req3", Ok("rsp3")),
("req4", Err(TransError::Any)),
("req4", Err(ExpectedTranscriptError::Any)),
];
#[tokio::test]

View File

@ -8,8 +8,11 @@
//! zebra-consensus accepts an ordered list of checkpoints, starting with the
//! genesis block. Checkpoint heights can be chosen arbitrarily.
#![deny(missing_docs)]
// 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;

View File

@ -1,3 +1,11 @@
//! Utilities for Zebra development, not for library or application users.
//!
//! Currently this consists only of the zebra-checkpoints binary.
#![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)]
#![forbid(unsafe_code)]

View File

@ -1,6 +1,9 @@
//! Main entry point for Zebrad
#![deny(missing_docs, trivial_casts, unused_qualifications)]
// Standard lints
#![warn(missing_docs)]
#![allow(clippy::try_err)]
#![deny(clippy::await_holding_lock)]
#![forbid(unsafe_code)]
use zebrad::application::APPLICATION;

View File

@ -17,7 +17,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/zebrad")]
//#![deny(warnings, missing_docs, trivial_casts, unused_qualifications)]
// Standard lints
#![warn(missing_docs)]
#![allow(clippy::try_err)]
#![deny(clippy::await_holding_lock)]
#![forbid(unsafe_code)]
// Tracing causes false positives on this lint:
// https://github.com/tokio-rs/tracing/issues/553

View File

@ -1,9 +1,14 @@
//! Integration with sentry.io for event reporting.
//!
//! Currently handles panic reports.
#[allow(unused_imports)]
use sentry::{
integrations::backtrace::current_stacktrace,
protocol::{Event, Exception, Mechanism},
};
/// Send a panic `msg` to the sentry service.
pub fn panic_event_from<T>(msg: T) -> Event<'static>
where
T: ToString,
@ -16,9 +21,9 @@ where
..Default::default()
}),
value: Some(msg.to_string()),
// Sentry does not handle panic = abort well yet, and when gibven this
// Sentry does not handle panic = abort well yet, and when given this
// stacktrace, it consists only of this line, making Sentry dedupe
// events together by their stacetrace fingerprint incorrectly.
// events together by their stacktrace fingerprint incorrectly.
//
// stacktrace: current_stacktrace(),
..Default::default()

View File

@ -12,10 +12,11 @@
//! - run zebrad on a custom cache path and port,
//! - run zcashd on a custom port.
#![warn(warnings, missing_docs, trivial_casts, unused_qualifications)]
#![forbid(unsafe_code)]
#![allow(dead_code)]
// Standard lints
#![warn(missing_docs)]
#![allow(clippy::try_err)]
#![deny(clippy::await_holding_lock)]
#![forbid(unsafe_code)]
use color_eyre::eyre::Result;
use eyre::WrapErr;
@ -747,8 +748,8 @@ fn sync_large_checkpoints_mainnet() -> Result<()> {
Ok(())
}
// Todo: We had a `sync_large_checkpoints_testnet` here but it was removed because
// the testnet is unreliable(#1222). Enable after we have more testnet instances(#1791).
// TODO: We had a `sync_large_checkpoints_testnet` here but it was removed because
// the testnet is unreliable (#1222). Enable after we have more testnet instances (#1791).
/// Sync `network` until `zebrad` reaches `height`, and ensure that
/// the output contains `stop_regex`. If `reuse_tempdir` is supplied,
@ -851,7 +852,8 @@ fn sync_past_canopy(network: Network) -> Result<()> {
// drives populated by the first two tests, snapshot those drives, and then use
// those to more quickly run the second two tests.
// Sync up to the canopy activation height on mainnet and stop.
/// Sync up to the canopy activation height on mainnet and stop.
#[allow(dead_code)]
#[cfg_attr(feature = "test_sync_to_canopy_mainnet", test)]
fn sync_to_canopy_mainnet() {
zebra_test::init();
@ -859,7 +861,8 @@ fn sync_to_canopy_mainnet() {
create_cached_database(network).unwrap();
}
// Sync to the canopy activation height testnet and stop.
/// Sync to the canopy activation height testnet and stop.
#[allow(dead_code)]
#[cfg_attr(feature = "test_sync_to_canopy_testnet", test)]
fn sync_to_canopy_testnet() {
zebra_test::init();
@ -872,6 +875,7 @@ fn sync_to_canopy_testnet() {
/// This assumes that the config'd state is already synced at or near Canopy
/// activation on mainnet. If the state has already synced past Canopy
/// activation by 1200 blocks, it will fail.
#[allow(dead_code)]
#[cfg_attr(feature = "test_sync_past_canopy_mainnet", test)]
fn sync_past_canopy_mainnet() {
zebra_test::init();
@ -884,6 +888,7 @@ fn sync_past_canopy_mainnet() {
/// This assumes that the config'd state is already synced at or near Canopy
/// activation on testnet. If the state has already synced past Canopy
/// activation by 1200 blocks, it will fail.
#[allow(dead_code)]
#[cfg_attr(feature = "test_sync_past_canopy_testnet", test)]
fn sync_past_canopy_testnet() {
zebra_test::init();
@ -1056,7 +1061,7 @@ async fn tracing_endpoint() -> Result<()> {
// Make sure tracing endpoint was started
output.stdout_contains(format!(r"Opened tracing endpoint at {}", endpoint).as_str())?;
// Todo: Match some trace level messages from output
// TODO: Match some trace level messages from output
// [Note on port conflict](#Note on port conflict)
output