From 4f27b6bac36469070d2e034e94e44e3b3953d6d3 Mon Sep 17 00:00:00 2001 From: Hazel OHearn Date: Thu, 1 Dec 2022 16:51:04 -0400 Subject: [PATCH] Add concrete error types for add_spend and add_output --- CHANGELOG.md | 5 +++++ src/builder.rs | 29 +++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ebdf382..b9f19532 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,9 +26,14 @@ and this project adheres to Rust's notion of - impls of `Eq` for: - `orchard::zip32::ChildIndex` - `orchard::value::ValueSum` +- `orchard::builder::Builder:` + - `SpendError` + - `OutputsDisabled` ### Changed - Migrated to `zcash_note_encryption 0.2`. +- `orchard::builder::Builder::{add_spend, add_output}` now use + concrete error types instead of `&'static str`s. ## [0.2.0] - 2022-06-24 ### Added diff --git a/src/builder.rs b/src/builder.rs index 9cbc2a5f..90c4af75 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -43,6 +43,20 @@ pub enum Error { DuplicateSignature, } +/// An error type for adding a spend to the builder. +#[derive(Debug)] +pub enum SpendError { + /// Spends aren't enabled for this builder. + SpendsDisabled, + /// The anchor provided to this builder doesn't match the merkle path used to add a spend. + AnchorMismatch, + /// The full viewing key provided didn't match the note provided + FvkMismatch, +} + +/// The only error that can occur here is if outputs are disabled for this builder. +pub type OutputsDisabled = (); + impl From for Error { fn from(e: halo2_proofs::plonk::Error) -> Self { Error::Proof(e) @@ -243,23 +257,22 @@ impl Builder { fvk: FullViewingKey, note: Note, merkle_path: MerklePath, - ) -> Result<(), &'static str> { + ) -> Result<(), SpendError> { if !self.flags.spends_enabled() { - return Err("Spends are not enabled for this builder"); + return Err(SpendError::SpendsDisabled); } // Consistency check: all anchors must be equal. let cm = note.commitment(); - let path_root: Anchor = - >::from(merkle_path.root(cm.into())).ok_or("Derived the bottom anchor")?; + let path_root = merkle_path.root(cm.into()); if path_root != self.anchor { - return Err("All anchors must be equal."); + return Err(SpendError::AnchorMismatch); } // Check if note is internal or external. let scope = fvk .scope_for_address(¬e.recipient()) - .ok_or("FullViewingKey does not correspond to the given note")?; + .ok_or(SpendError::FvkMismatch)?; self.spends.push(SpendInfo { dummy_sk: None, @@ -279,9 +292,9 @@ impl Builder { recipient: Address, value: NoteValue, memo: Option<[u8; 512]>, - ) -> Result<(), &'static str> { + ) -> Result<(), OutputsDisabled> { if !self.flags.outputs_enabled() { - return Err("Outputs are not enabled for this builder"); + return Err(()); } self.recipients.push(RecipientInfo {