From 55c5ebd0e1d273df7b4a54025a5ce2c0167f52f5 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Mon, 2 Dec 2024 20:54:47 -0300 Subject: [PATCH 1/2] add: add consensus validation reason to error messages --- zebra-consensus/src/error.rs | 24 ++++++++++++---------- zebrad/src/components/mempool/downloads.rs | 6 +++--- zebrad/src/components/mempool/storage.rs | 2 +- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/zebra-consensus/src/error.rs b/zebra-consensus/src/error.rs index 8fe14c62d52..b0c867fc148 100644 --- a/zebra-consensus/src/error.rs +++ b/zebra-consensus/src/error.rs @@ -121,7 +121,7 @@ pub enum TransactionError { transaction_hash: zebra_chain::transaction::Hash, }, - #[error("coinbase transaction failed subsidy validation")] + #[error("coinbase transaction failed subsidy validation: {0}")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] Subsidy(#[from] SubsidyError), @@ -140,7 +140,7 @@ pub enum TransactionError { #[error("if there are no Spends or Outputs, the value balance MUST be 0.")] BadBalance, - #[error("could not verify a transparent script")] + #[error("could not verify a transparent script: {0}")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] Script(#[from] zebra_script::Error), @@ -149,29 +149,29 @@ pub enum TransactionError { // TODO: the underlying error is bellman::VerificationError, but it does not implement // Arbitrary as required here. - #[error("spend proof MUST be valid given a primary input formed from the other fields except spendAuthSig")] + #[error("spend proof MUST be valid given a primary input formed from the other fields except spendAuthSig: {0}")] Groth16(String), // TODO: the underlying error is io::Error, but it does not implement Clone as required here. - #[error("Groth16 proof is malformed")] + #[error("Groth16 proof is malformed: {0}")] MalformedGroth16(String), #[error( - "Sprout joinSplitSig MUST represent a valid signature under joinSplitPubKey of dataToBeSigned" + "Sprout joinSplitSig MUST represent a valid signature under joinSplitPubKey of dataToBeSigned: {0}" )] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] Ed25519(#[from] zebra_chain::primitives::ed25519::Error), - #[error("Sapling bindingSig MUST represent a valid signature under the transaction binding validating key bvk of SigHash")] + #[error("Sapling bindingSig MUST represent a valid signature under the transaction binding validating key bvk of SigHash: {0}")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] RedJubjub(zebra_chain::primitives::redjubjub::Error), - #[error("Orchard bindingSig MUST represent a valid signature under the transaction binding validating key bvk of SigHash")] + #[error("Orchard bindingSig MUST represent a valid signature under the transaction binding validating key bvk of SigHash: {0}")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] RedPallas(zebra_chain::primitives::reddsa::Error), // temporary error type until #1186 is fixed - #[error("Downcast from BoxError to redjubjub::Error failed")] + #[error("Downcast from BoxError to redjubjub::Error failed: {0}")] InternalDowncastError(String), #[error("either vpub_old or vpub_new must be zero")] @@ -201,12 +201,12 @@ pub enum TransactionError { #[error("could not find a mempool transaction input UTXO in the best chain")] TransparentInputNotFound, - #[error("could not validate nullifiers and anchors on best chain")] + #[error("could not validate nullifiers and anchors on best chain: {0}")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] // This error variant is at least 128 bytes ValidateContextError(Box), - #[error("could not validate mempool transaction lock time on best chain")] + #[error("could not validate mempool transaction lock time on best chain: {0}")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] // TODO: turn this into a typed error ValidateMempoolLockTimeError(String), @@ -236,7 +236,9 @@ pub enum TransactionError { min_spend_height: block::Height, }, - #[error("failed to verify ZIP-317 transaction rules, transaction was not inserted to mempool")] + #[error( + "failed to verify ZIP-317 transaction rules, transaction was not inserted to mempool: {0}" + )] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] Zip317(#[from] zebra_chain::transaction::zip317::Error), } diff --git a/zebrad/src/components/mempool/downloads.rs b/zebrad/src/components/mempool/downloads.rs index 45fd44a7c05..c9658d0c91e 100644 --- a/zebrad/src/components/mempool/downloads.rs +++ b/zebrad/src/components/mempool/downloads.rs @@ -112,16 +112,16 @@ pub enum TransactionDownloadVerifyError { #[error("transaction is already in state")] InState, - #[error("error in state service")] + #[error("error in state service: {0}")] StateError(#[source] CloneError), - #[error("error downloading transaction")] + #[error("error downloading transaction: {0}")] DownloadFailed(#[source] CloneError), #[error("transaction download / verification was cancelled")] Cancelled, - #[error("transaction did not pass consensus validation")] + #[error("transaction did not pass consensus validation: {0}")] Invalid(#[from] zebra_consensus::error::TransactionError), } diff --git a/zebrad/src/components/mempool/storage.rs b/zebrad/src/components/mempool/storage.rs index ce6f09cf1d6..be7cbc9593f 100644 --- a/zebrad/src/components/mempool/storage.rs +++ b/zebrad/src/components/mempool/storage.rs @@ -55,7 +55,7 @@ pub(crate) const MAX_EVICTION_MEMORY_ENTRIES: usize = 40_000; #[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] #[allow(dead_code)] pub enum ExactTipRejectionError { - #[error("transaction did not pass consensus validation")] + #[error("transaction did not pass consensus validation: {0}")] FailedVerification(#[from] zebra_consensus::error::TransactionError), } From a15a2e8280908984263408690f245e3132a51e20 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Wed, 4 Dec 2024 11:28:31 -0300 Subject: [PATCH 2/2] add additional instances --- zebra-chain/src/history_tree.rs | 2 +- zebra-consensus/src/block.rs | 8 ++++---- zebra-consensus/src/checkpoint.rs | 4 ++-- zebra-network/src/peer/error.rs | 4 ++-- zebra-state/src/error.rs | 6 +++--- zebrad/src/components/mempool/error.rs | 8 +++++--- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/zebra-chain/src/history_tree.rs b/zebra-chain/src/history_tree.rs index 91fa3a17628..d84f92321af 100644 --- a/zebra-chain/src/history_tree.rs +++ b/zebra-chain/src/history_tree.rs @@ -30,7 +30,7 @@ pub enum HistoryTreeError { #[non_exhaustive] InnerError { inner: zcash_history::Error }, - #[error("I/O error")] + #[error("I/O error: {0}")] IOError(#[from] io::Error), } diff --git a/zebra-consensus/src/block.rs b/zebra-consensus/src/block.rs index 611aea2ceba..247079c401a 100644 --- a/zebra-consensus/src/block.rs +++ b/zebra-consensus/src/block.rs @@ -74,19 +74,19 @@ pub enum VerifyBlockError { #[error(transparent)] Time(zebra_chain::block::BlockTimeError), - #[error("unable to commit block after semantic verification")] + #[error("unable to commit block after semantic verification: {0}")] // TODO: make this into a concrete type, and add it to is_duplicate_request() (#2908) Commit(#[source] BoxError), #[cfg(feature = "getblocktemplate-rpcs")] - #[error("unable to validate block proposal: failed semantic verification (proof of work is not checked for proposals)")] + #[error("unable to validate block proposal: failed semantic verification (proof of work is not checked for proposals): {0}")] // TODO: make this into a concrete type (see #5732) ValidateProposal(#[source] BoxError), - #[error("invalid transaction")] + #[error("invalid transaction: {0}")] Transaction(#[from] TransactionError), - #[error("invalid block subsidy")] + #[error("invalid block subsidy: {0}")] Subsidy(#[from] SubsidyError), } diff --git a/zebra-consensus/src/checkpoint.rs b/zebra-consensus/src/checkpoint.rs index 039ea6e33e3..36b3a76d57f 100644 --- a/zebra-consensus/src/checkpoint.rs +++ b/zebra-consensus/src/checkpoint.rs @@ -992,9 +992,9 @@ pub enum VerifyCheckpointError { CheckpointList(BoxError), #[error(transparent)] VerifyBlock(VerifyBlockError), - #[error("invalid block subsidy")] + #[error("invalid block subsidy: {0}")] SubsidyError(#[from] SubsidyError), - #[error("invalid amount")] + #[error("invalid amount: {0}")] AmountError(#[from] amount::Error), #[error("too many queued blocks at this height")] QueuedLimit, diff --git a/zebra-network/src/peer/error.rs b/zebra-network/src/peer/error.rs index c40c34b1d1d..d85e0e143ba 100644 --- a/zebra-network/src/peer/error.rs +++ b/zebra-network/src/peer/error.rs @@ -251,10 +251,10 @@ pub enum HandshakeError { #[error("Peer closed connection")] ConnectionClosed, /// An error occurred while performing an IO operation. - #[error("Underlying IO error")] + #[error("Underlying IO error: {0}")] Io(#[from] std::io::Error), /// A serialization error occurred while reading or writing a message. - #[error("Serialization error")] + #[error("Serialization error: {0}")] Serialization(#[from] SerializationError), /// The remote peer offered a version older than our minimum version. #[error("Peer offered obsolete version: {0:?}")] diff --git a/zebra-state/src/error.rs b/zebra-state/src/error.rs index cf495311efb..632591f4cb3 100644 --- a/zebra-state/src/error.rs +++ b/zebra-state/src/error.rs @@ -220,13 +220,13 @@ pub enum ValidateContextError { height: Option, }, - #[error("error updating a note commitment tree")] + #[error("error updating a note commitment tree: {0}")] NoteCommitmentTreeError(#[from] zebra_chain::parallel::tree::NoteCommitmentTreeError), - #[error("error building the history tree")] + #[error("error building the history tree: {0}")] HistoryTreeError(#[from] Arc), - #[error("block contains an invalid commitment")] + #[error("block contains an invalid commitment: {0}")] InvalidBlockCommitment(#[from] block::CommitmentError), #[error( diff --git a/zebrad/src/components/mempool/error.rs b/zebrad/src/components/mempool/error.rs index c70ca56cbc6..d27c78b6da3 100644 --- a/zebrad/src/components/mempool/error.rs +++ b/zebrad/src/components/mempool/error.rs @@ -23,7 +23,9 @@ pub enum MempoolError { /// /// Note that the mempool caches this error. See [`super::storage::Storage`] /// for more details. - #[error("the transaction will be rejected from the mempool until the next chain tip block")] + #[error( + "the transaction will be rejected from the mempool until the next chain tip block: {0}" + )] StorageExactTip(#[from] ExactTipRejectionError), /// Transaction rejected based on its effects (spends, outputs, transaction @@ -33,7 +35,7 @@ pub enum MempoolError { /// /// Note that the mempool caches this error. See [`super::storage::Storage`] /// for more details. - #[error("any transaction with the same effects will be rejected from the mempool until the next chain tip block")] + #[error("any transaction with the same effects will be rejected from the mempool until the next chain tip block: {0}")] StorageEffectsTip(#[from] SameEffectsTipRejectionError), /// Transaction rejected based on its effects (spends, outputs, transaction @@ -44,7 +46,7 @@ pub enum MempoolError { /// /// Note that the mempool caches this error. See [`super::storage::Storage`] /// for more details. - #[error("any transaction with the same effects will be rejected from the mempool until a chain reset")] + #[error("any transaction with the same effects will be rejected from the mempool until a chain reset: {0}")] StorageEffectsChain(#[from] SameEffectsChainRejectionError), /// Transaction rejected because the mempool already contains another