Skip to content

Commit

Permalink
feat: add specific errors for wallet persistence
Browse files Browse the repository at this point in the history
  • Loading branch information
thunderbiscuit committed Feb 16, 2024
1 parent 68a9eb6 commit 43c1ca6
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 10 deletions.
14 changes: 13 additions & 1 deletion bdk-ffi/src/bdk.udl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ interface CalculateFeeError {
NegativeFee(i64 fee);
};

[Error]
interface WalletCreationError {
Io(string e);
InvalidMagicBytes(sequence<u8> got, sequence<u8> expected);
Descriptor();
Write();
Load();
NotInitialized();
LoadedGenesisDoesNotMatch();
LoadedNetworkDoesNotMatch(Network expected, Network? got);
};

// ------------------------------------------------------------------------
// bdk crate - types module
// ------------------------------------------------------------------------
Expand Down Expand Up @@ -86,7 +98,7 @@ enum ChangeSpendPolicy {
};

interface Wallet {
[Throws=Alpha3Error]
[Throws=WalletCreationError]
constructor(Descriptor descriptor, Descriptor? change_descriptor, string persistence_backend_path, Network network);

AddressInfo get_address(AddressIndex address_index);
Expand Down
84 changes: 77 additions & 7 deletions bdk-ffi/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ use bdk::chain::tx_graph::CalculateFeeError as BdkCalculateFeeError;

use std::fmt;

use bdk::bitcoin::Network;
use bdk::descriptor::DescriptorError;
use bdk::wallet::error::{BuildFeeBumpError, CreateTxError};
use bdk::wallet::tx_builder::{AddUtxoError, AllowShrinkingError};
use bdk::wallet::{NewError, NewOrLoadError};
use bdk_file_store::{FileError, IterError};
use bdk_file_store::FileError as BdkFileError;
use bdk_file_store::IterError;
use std::convert::Infallible;

#[derive(Debug)]
Expand All @@ -26,15 +28,83 @@ impl fmt::Display for Alpha3Error {

impl std::error::Error for Alpha3Error {}

impl From<FileError> for Alpha3Error {
fn from(_: FileError) -> Self {
Alpha3Error::Generic
#[derive(Debug)]
pub enum WalletCreationError {
// Errors coming from the FileError enum
Io {
e: String,
},
InvalidMagicBytes {
got: Vec<u8>,
expected: Vec<u8>,
},

// Errors coming from the NewOrLoadError enum
Descriptor,
Write,
Load,
NotInitialized,
LoadedGenesisDoesNotMatch,
LoadedNetworkDoesNotMatch {
expected: Network,
got: Option<Network>,
},
}

impl fmt::Display for WalletCreationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Io { e } => write!(f, "io error trying to read file: {}", e),
Self::InvalidMagicBytes { got, expected } => write!(
f,
"file has invalid magic bytes: expected={:?} got={:?}",
expected, got,
),
Self::Descriptor => write!(f, "error with descriptor"),
Self::Write => write!(f, "failed to write to persistence"),
Self::Load => write!(f, "failed to load from persistence"),
Self::NotInitialized => {
write!(f, "wallet is not initialized, persistence backend is empty")
}
Self::LoadedGenesisDoesNotMatch => {
write!(f, "loaded genesis hash does not match the expected one")
}
Self::LoadedNetworkDoesNotMatch { expected, got } => {
write!(f, "loaded network type is not {}, got {:?}", expected, got)
}
}
}
}

impl From<NewOrLoadError<std::io::Error, IterError>> for Alpha3Error {
fn from(_: NewOrLoadError<std::io::Error, IterError>) -> Self {
Alpha3Error::Generic
impl std::error::Error for WalletCreationError {}

impl From<BdkFileError> for WalletCreationError {
fn from(error: BdkFileError) -> Self {
match error {
BdkFileError::Io(_) => WalletCreationError::Io {
e: "io error trying to read file".to_string(),
},
BdkFileError::InvalidMagicBytes { got, expected } => {
WalletCreationError::InvalidMagicBytes { got, expected }
}
}
}
}

impl From<NewOrLoadError<std::io::Error, IterError>> for WalletCreationError {
fn from(error: NewOrLoadError<std::io::Error, IterError>) -> Self {
match error {
NewOrLoadError::Descriptor(_) => WalletCreationError::Descriptor,
NewOrLoadError::Write(_) => WalletCreationError::Write,
NewOrLoadError::Load(_) => WalletCreationError::Load,
NewOrLoadError::NotInitialized => WalletCreationError::NotInitialized,
NewOrLoadError::LoadedGenesisDoesNotMatch { .. } => {
WalletCreationError::LoadedGenesisDoesNotMatch
}
NewOrLoadError::LoadedNetworkDoesNotMatch { expected, got } => {
WalletCreationError::LoadedNetworkDoesNotMatch { expected, got }
}
}
}
}

Expand Down
1 change: 1 addition & 0 deletions bdk-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use crate::wallet::TxBuilder;
use crate::wallet::Update;
use crate::wallet::Wallet;

use crate::error::WalletCreationError;
use bdk::bitcoin::Network;
use bdk::keys::bip39::WordCount;
use bdk::wallet::tx_builder::ChangeSpendPolicy;
Expand Down
4 changes: 2 additions & 2 deletions bdk-ffi/src/wallet.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::bitcoin::{OutPoint, PartiallySignedTransaction, Transaction};
use crate::descriptor::Descriptor;
use crate::error::{Alpha3Error, CalculateFeeError};
use crate::error::{Alpha3Error, CalculateFeeError, WalletCreationError};
use crate::types::ScriptAmount;
use crate::types::{Balance, FeeRate};
use crate::Script;
Expand Down Expand Up @@ -32,7 +32,7 @@ impl Wallet {
change_descriptor: Option<Arc<Descriptor>>,
persistence_backend_path: String,
network: Network,
) -> Result<Self, Alpha3Error> {
) -> Result<Self, WalletCreationError> {
let descriptor = descriptor.as_string_private();
let change_descriptor = change_descriptor.map(|d| d.as_string_private());
let db = Store::<ChangeSet>::open_or_create_new(MAGIC_BYTES, persistence_backend_path)?;
Expand Down

0 comments on commit 43c1ca6

Please sign in to comment.