Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions crates/wallet/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use alloc::boxed::Box;
use chain::{ChainPosition, ConfirmationBlockTime};
use core::convert::AsRef;
use core::fmt;

use bitcoin::transaction::{OutPoint, Sequence, TxOut};
use bitcoin::{psbt, Weight};
Expand All @@ -37,6 +38,15 @@ impl KeychainKind {
}
}

impl fmt::Display for KeychainKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
KeychainKind::External => write!(f, "External"),
KeychainKind::Internal => write!(f, "Internal"),
}
}
}

impl AsRef<[u8]> for KeychainKind {
fn as_ref(&self) -> &[u8] {
match self {
Expand Down
6 changes: 3 additions & 3 deletions crates/wallet/src/wallet/error.rs
Comment thread
luisschwab marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ impl fmt::Display for CreateTxError {
Self::Descriptor(e) => e.fmt(f),
Self::Policy(e) => e.fmt(f),
CreateTxError::SpendingPolicyRequired(keychain_kind) => {
write!(f, "Spending policy required: {:?}", keychain_kind)
write!(f, "Spending policy required: {}", keychain_kind)
}
CreateTxError::Version0 => {
write!(f, "Invalid version `0`")
Expand All @@ -127,12 +127,12 @@ impl fmt::Display for CreateTxError {
requested,
required,
} => {
write!(f, "TxBuilder requested timelock of `{:?}`, but at least `{:?}` is required to spend from this script", required, requested)
write!(f, "TxBuilder requested timelock of `{}`, but at least `{}` is required to spend from this script", required, requested)
}
CreateTxError::RbfSequenceCsv { sequence, csv } => {
write!(
f,
"Cannot enable RBF with nSequence `{:?}` given a required OP_CSV of `{:?}`",
"Cannot enable RBF with nSequence `{}` given a required OP_CSV of `{}`",
sequence, csv
)
}
Expand Down
42 changes: 40 additions & 2 deletions crates/wallet/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,9 @@ impl fmt::Display for LoadError {
LoadError::MissingNetwork => write!(f, "loaded data is missing network type"),
LoadError::MissingGenesis => write!(f, "loaded data is missing genesis hash"),
LoadError::MissingDescriptor(k) => {
write!(f, "loaded data is missing descriptor for keychain {k:?}")
write!(f, "loaded data is missing descriptor for {k} keychain")
}
LoadError::Mismatch(mismatch) => write!(f, "data mismatch: {mismatch:?}"),
LoadError::Mismatch(e) => write!(f, "{e}"),
}
}
}
Expand Down Expand Up @@ -232,6 +232,44 @@ pub enum LoadMismatch {
},
}

impl fmt::Display for LoadMismatch {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
LoadMismatch::Network { loaded, expected } => {
write!(
f,
"Network mismatch: loaded {}, expected {}",
loaded, expected
)
}
LoadMismatch::Genesis { loaded, expected } => {
write!(
f,
"Genesis hash mismatch: loaded {}, expected {}",
loaded, expected
)
}
LoadMismatch::Descriptor {
keychain,
loaded,
expected,
} => {
write!(
f,
"Descriptor mismatch for {} keychain: loaded {}, expected {}",
keychain,
loaded
.as_ref()
.map_or("None".to_string(), |d| d.to_string()),
expected
.as_ref()
.map_or("None".to_string(), |d| d.to_string())
)
}
}
}
}

impl From<LoadMismatch> for LoadError {
fn from(mismatch: LoadMismatch) -> Self {
Self::Mismatch(mismatch)
Expand Down
46 changes: 37 additions & 9 deletions crates/wallet/src/wallet/persisted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ use core::{
pin::Pin,
};

use alloc::boxed::Box;
use alloc::{
boxed::Box,
string::{String, ToString},
};
use chain::Merge;

use crate::{descriptor::DescriptorError, ChangeSet, CreateParams, LoadParams, Wallet};
use crate::{
descriptor::{calc_checksum, DescriptorError},
ChangeSet, CreateParams, LoadParams, Wallet,
};

/// Trait that persists [`PersistedWallet`].
///
Expand Down Expand Up @@ -363,16 +369,38 @@ pub enum CreateWithPersistError<E> {
impl<E: fmt::Display> fmt::Display for CreateWithPersistError<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Persist(err) => fmt::Display::fmt(err, f),
Self::DataAlreadyExists(changeset) => write!(
f,
"Cannot create wallet in persister which already contains wallet data: {:?}",
changeset
),
Self::Descriptor(err) => fmt::Display::fmt(&err, f),
Self::Persist(err) => write!(f, "Persistence error: {}", err),
Self::DataAlreadyExists(changeset) => {
write!(f, "{}", changeset_info(changeset))
}
Self::Descriptor(err) => {
write!(f, "{err}")
}
}
}
}

/// Helper function to write basic fingerprinting information about a changeset
fn changeset_info(changeset: &ChangeSet) -> String {
let network = match &changeset.network {
Some(network) => network.to_string(),
None => "None".to_string(),
};
let external_checksum = match &changeset.descriptor {
Some(descriptor) => calc_checksum(&descriptor.to_string()).unwrap(),
None => "[no external descriptor in the changeset]".to_string(),
};
let internal_checksum = match &changeset.change_descriptor {
Some(descriptor) => calc_checksum(&descriptor.to_string()).unwrap(),
None => "[no internal descriptor in the changeset]".to_string(),
};

format!(
"Cannot create wallet in a persister which already contains wallet data: \
Network: {}, External Descriptor Checksum: {}, Internal Descriptor Checksum: {}",
network, external_checksum, internal_checksum
)
}

#[cfg(feature = "std")]
impl<E: fmt::Debug + fmt::Display> std::error::Error for CreateWithPersistError<E> {}
Loading