From 97a104fd5f4ee30b465244ecbf618d92cfbebd4f Mon Sep 17 00:00:00 2001 From: thunderbiscuit Date: Fri, 5 Apr 2024 10:53:54 -0400 Subject: [PATCH] feat: add descriptor related errors --- bdk-ffi/src/bdk.udl | 18 ++++++- bdk-ffi/src/bitcoin.rs | 4 +- bdk-ffi/src/descriptor.rs | 10 ++-- bdk-ffi/src/error.rs | 102 +++++++++++++++++++++++++++++++------- bdk-ffi/src/esplora.rs | 2 +- bdk-ffi/src/lib.rs | 1 + bdk-ffi/src/types.rs | 3 +- 7 files changed, 110 insertions(+), 30 deletions(-) diff --git a/bdk-ffi/src/bdk.udl b/bdk-ffi/src/bdk.udl index e723fa8..3c9211d 100644 --- a/bdk-ffi/src/bdk.udl +++ b/bdk-ffi/src/bdk.udl @@ -88,6 +88,22 @@ interface PsbtParseError { Base64Encoding(string e); }; +[Error] +interface DescriptorError { + InvalidHdKeyPath(); + InvalidDescriptorChecksum(); + HardenedDerivationXpub(); + MultiPath(); + Key(string e); + Policy(string e); + InvalidDescriptorCharacter(string char); + Bip32(string e); + Base58(string e); + Pk(string e); + Miniscript(string e); + Hex(string e); +}; + // ------------------------------------------------------------------------ // bdk crate - types module // ------------------------------------------------------------------------ @@ -309,7 +325,7 @@ interface DescriptorPublicKey { }; interface Descriptor { - [Throws=Alpha3Error] + [Throws=DescriptorError] constructor(string descriptor, Network network); [Name=new_bip44] diff --git a/bdk-ffi/src/bitcoin.rs b/bdk-ffi/src/bitcoin.rs index 8faae9d..00facf2 100644 --- a/bdk-ffi/src/bitcoin.rs +++ b/bdk-ffi/src/bitcoin.rs @@ -1,5 +1,4 @@ -use crate::error::{PsbtParseError, TransactionError}; -use crate::error::AddressError; +use crate::error::{AddressError, PsbtParseError, TransactionError}; use bdk::bitcoin::address::{NetworkChecked, NetworkUnchecked}; use bdk::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf; @@ -198,7 +197,6 @@ impl PartiallySignedTransaction { pub(crate) fn new(psbt_base64: String) -> Result { let psbt: BdkPartiallySignedTransaction = BdkPartiallySignedTransaction::from_str(&psbt_base64)?; - // .map_err(|_| Alpha3Error::Generic)?; Ok(PartiallySignedTransaction { inner: Mutex::new(psbt), diff --git a/bdk-ffi/src/descriptor.rs b/bdk-ffi/src/descriptor.rs index 4097beb..ac5a25b 100644 --- a/bdk-ffi/src/descriptor.rs +++ b/bdk-ffi/src/descriptor.rs @@ -1,4 +1,4 @@ -use crate::error::Alpha3Error; +use crate::error::DescriptorError; use crate::keys::DescriptorPublicKey; use crate::keys::DescriptorSecretKey; @@ -23,7 +23,7 @@ pub struct Descriptor { } impl Descriptor { - pub(crate) fn new(descriptor: String, network: Network) -> Result { + pub(crate) fn new(descriptor: String, network: Network) -> Result { let secp = Secp256k1::new(); let (extended_descriptor, key_map) = descriptor.into_wallet_descriptor(&secp, network)?; Ok(Self { @@ -276,8 +276,6 @@ mod test { use crate::*; use assert_matches::assert_matches; - use crate::Alpha3Error; - fn get_descriptor_secret_key() -> DescriptorSecretKey { let mnemonic = Mnemonic::from_string("chaos fabric time speed sponsor all flat solution wisdom trophy crack object robot pave observe combine where aware bench orient secret primary cable detect".to_string()).unwrap(); DescriptorSecretKey::new(Network::Testnet, &mnemonic, None) @@ -392,8 +390,8 @@ mod test { fn test_descriptor_from_string() { let descriptor1 = Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Testnet); let descriptor2 = Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Bitcoin); - // Creating a Descriptor using an extended key that doesn't match the network provided will throw and InvalidNetwork Error + // Creating a Descriptor using an extended key that doesn't match the network provided will throw a DescriptorError::Key with inner InvalidNetwork error assert!(descriptor1.is_ok()); - assert_matches!(descriptor2.unwrap_err(), Alpha3Error::Generic) + assert_matches!(descriptor2.unwrap_err(), DescriptorError::Key { .. }); } } diff --git a/bdk-ffi/src/error.rs b/bdk-ffi/src/error.rs index 7d22e8d..18aba8c 100644 --- a/bdk-ffi/src/error.rs +++ b/bdk-ffi/src/error.rs @@ -1,17 +1,17 @@ use crate::bitcoin::OutPoint; -use bdk::chain::tx_graph::CalculateFeeError as BdkCalculateFeeError; -use bdk_esplora::esplora_client::{Error as BdkEsploraError}; - use bdk::bitcoin::psbt::PsbtParseError as BdkPsbtParseError; use bdk::bitcoin::Network; -use bdk::descriptor::DescriptorError; +use bdk::chain::tx_graph::CalculateFeeError as BdkCalculateFeeError; +use bdk::descriptor::DescriptorError as BdkDescriptorError; use bdk::wallet::error::{BuildFeeBumpError, CreateTxError}; use bdk::wallet::tx_builder::{AddUtxoError, AllowShrinkingError}; use bdk::wallet::{NewError, NewOrLoadError}; +use bdk_esplora::esplora_client::Error as BdkEsploraError; use bdk_file_store::FileError as BdkFileError; use bdk_file_store::IterError; use bitcoin_internals::hex::display::DisplayHex; + use std::convert::Infallible; #[derive(Debug, thiserror::Error)] @@ -204,6 +204,70 @@ pub enum PsbtParseError { Base64Encoding { e: String }, } +#[derive(Debug, thiserror::Error)] +pub enum DescriptorError { + #[error("invalid hd key path")] + InvalidHdKeyPath, + + #[error("the provided descriptor doesn't match its checksum")] + InvalidDescriptorChecksum, + + #[error("the descriptor contains hardened derivation steps on public extended keys")] + HardenedDerivationXpub, + + #[error("the descriptor contains multipath keys, which are not supported yet")] + MultiPath, + + #[error("key error: {e}")] + Key { e: String }, + + #[error("policy error: {e}")] + Policy { e: String }, + + #[error("invalid descriptor character: {char}")] + InvalidDescriptorCharacter { char: String }, + + #[error("BIP32 error: {e}")] + Bip32 { e: String }, + + #[error("Base58 error: {e}")] + Base58 { e: String }, + + #[error("Key-related error: {e}")] + Pk { e: String }, + + #[error("Miniscript error: {e}")] + Miniscript { e: String }, + + #[error("Hex decoding error: {e}")] + Hex { e: String }, +} + +impl From for DescriptorError { + fn from(error: BdkDescriptorError) -> Self { + match error { + BdkDescriptorError::InvalidHdKeyPath => DescriptorError::InvalidHdKeyPath, + BdkDescriptorError::InvalidDescriptorChecksum => { + DescriptorError::InvalidDescriptorChecksum + } + BdkDescriptorError::HardenedDerivationXpub => DescriptorError::HardenedDerivationXpub, + BdkDescriptorError::MultiPath => DescriptorError::MultiPath, + BdkDescriptorError::Key(e) => DescriptorError::Key { e: e.to_string() }, + BdkDescriptorError::Policy(e) => DescriptorError::Policy { e: e.to_string() }, + BdkDescriptorError::InvalidDescriptorCharacter(char) => { + DescriptorError::InvalidDescriptorCharacter { + char: char.to_string(), + } + } + BdkDescriptorError::Bip32(e) => DescriptorError::Bip32 { e: e.to_string() }, + BdkDescriptorError::Base58(e) => DescriptorError::Base58 { e: e.to_string() }, + BdkDescriptorError::Pk(e) => DescriptorError::Pk { e: e.to_string() }, + BdkDescriptorError::Miniscript(e) => DescriptorError::Miniscript { e: e.to_string() }, + BdkDescriptorError::Hex(e) => DescriptorError::Hex { e: e.to_string() }, + } + } +} + impl From for PsbtParseError { fn from(error: BdkPsbtParseError) -> Self { match error { @@ -254,11 +318,11 @@ impl From for PersistenceError { } } -impl From for Alpha3Error { - fn from(_: DescriptorError) -> Self { - Alpha3Error::Generic - } -} +// impl From for Alpha3Error { +// fn from(_: DescriptorError) -> Self { +// Alpha3Error::Generic +// } +// } impl From for Alpha3Error { fn from(_: AllowShrinkingError) -> Self { @@ -364,10 +428,14 @@ impl From for AddressError { AddressError::MalformedWitnessVersion } bdk::bitcoin::address::Error::InvalidWitnessProgramLength(length) => { - AddressError::InvalidWitnessProgramLength { length: length as u64 } + AddressError::InvalidWitnessProgramLength { + length: length as u64, + } } bdk::bitcoin::address::Error::InvalidSegwitV0ProgramLength(length) => { - AddressError::InvalidSegwitV0ProgramLength { length: length as u64 } + AddressError::InvalidSegwitV0ProgramLength { + length: length as u64, + } } bdk::bitcoin::address::Error::UncompressedPubkey => AddressError::UncompressedPubkey, bdk::bitcoin::address::Error::ExcessiveScriptSize => AddressError::ExcessiveScriptSize, @@ -379,13 +447,11 @@ impl From for AddressError { required, found, address, - } => { - AddressError::NetworkValidation { - required, - found, - address: format!("{:?}", address), - } - } + } => AddressError::NetworkValidation { + required, + found, + address: format!("{:?}", address), + }, _ => AddressError::OtherAddressError, } } diff --git a/bdk-ffi/src/esplora.rs b/bdk-ffi/src/esplora.rs index 6fcde42..67e2e63 100644 --- a/bdk-ffi/src/esplora.rs +++ b/bdk-ffi/src/esplora.rs @@ -1,12 +1,12 @@ use crate::error::{Alpha3Error, EsploraError}; use crate::wallet::{Update, Wallet}; +use crate::bitcoin::Transaction; use bdk::bitcoin::Transaction as BdkTransaction; use bdk::wallet::Update as BdkUpdate; use bdk_esplora::esplora_client::{BlockingClient, Builder}; use bdk_esplora::EsploraExt; -use crate::bitcoin::Transaction; use std::sync::Arc; pub struct EsploraClient(BlockingClient); diff --git a/bdk-ffi/src/lib.rs b/bdk-ffi/src/lib.rs index 30a0ea9..369e422 100644 --- a/bdk-ffi/src/lib.rs +++ b/bdk-ffi/src/lib.rs @@ -16,6 +16,7 @@ use crate::descriptor::Descriptor; use crate::error::AddressError; use crate::error::Alpha3Error; use crate::error::CalculateFeeError; +use crate::error::DescriptorError; use crate::error::EsploraError; use crate::error::FeeRateError; use crate::error::PersistenceError; diff --git a/bdk-ffi/src/types.rs b/bdk-ffi/src/types.rs index ca68668..cccdede 100644 --- a/bdk-ffi/src/types.rs +++ b/bdk-ffi/src/types.rs @@ -1,6 +1,7 @@ -use crate::bitcoin::{Address, OutPoint, Script, Transaction, TxOut}; use crate::error::FeeRateError; +use crate::bitcoin::{Address, OutPoint, Script, Transaction, TxOut}; + use bdk::bitcoin::FeeRate as BdkFeeRate; use bdk::bitcoin::Transaction as BdkTransaction; use bdk::chain::tx_graph::CanonicalTx as BdkCanonicalTx;