feat: add specific errors for wallet persistence

This commit is contained in:
thunderbiscuit 2024-02-14 15:38:50 -05:00
parent 68a9eb693d
commit 43c1ca66b8
No known key found for this signature in database
GPG Key ID: 88253696EB836462
4 changed files with 93 additions and 10 deletions

View File

@ -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
// ------------------------------------------------------------------------
@ -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);

View File

@ -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)]
@ -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 }
}
}
}
}

View File

@ -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;

View File

@ -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;
@ -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)?;