feat: add transaction related errors

This commit is contained in:
thunderbiscuit 2024-04-04 12:47:00 -04:00
parent 84f2497aeb
commit ab2e97e782
No known key found for this signature in database
GPG Key ID: 88253696EB836462
6 changed files with 77 additions and 6 deletions

9
bdk-ffi/Cargo.lock generated
View File

@ -161,6 +161,7 @@ dependencies = [
"bdk",
"bdk_esplora",
"bdk_file_store",
"bitcoin-internals 0.2.0",
"thiserror",
"uniffi",
]
@ -244,6 +245,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f9997f8650dd818369931b5672a18dbef95324d0513aa99aae758de8ce86e5b"
[[package]]
name = "bitcoin-internals"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb"
[[package]]
name = "bitcoin-private"
version = "0.1.0"
@ -393,7 +400,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cb1f7f2489cce83bc3bd92784f9ba5271eeb6e729b975895fc541f78cbfcdca"
dependencies = [
"bitcoin",
"bitcoin-internals",
"bitcoin-internals 0.1.0",
"log",
"serde",
"ureq",

View File

@ -24,6 +24,7 @@ bdk_esplora = { version = "0.10.0", default-features = false, features = ["std",
bdk_file_store = { version = "0.8.0" }
uniffi = { version = "=0.26.1" }
bitcoin-internals = { version = "0.2.0", features = ["alloc"] }
thiserror = "1.0.58"
[build-dependencies]

View File

@ -71,6 +71,17 @@ interface AddressError {
OtherAddressError();
};
[Error]
interface TransactionError {
Io();
OversizedVectorAllocation();
InvalidChecksum(string expected, string actual);
NonMinimalVarInt();
ParseFailed();
UnsupportedSegwitFlag(u8 flag);
OtherTransactionError();
};
// ------------------------------------------------------------------------
// bdk crate - types module
// ------------------------------------------------------------------------
@ -394,7 +405,7 @@ interface Address {
};
interface Transaction {
[Throws=Alpha3Error]
[Throws=TransactionError]
constructor(sequence<u8> transaction_bytes);
string txid();

View File

@ -1,4 +1,5 @@
use crate::error::Alpha3Error;
use crate::error::{Alpha3Error, TransactionError};
use crate::error::AddressError;
use bdk::bitcoin::address::{NetworkChecked, NetworkUnchecked};
use bdk::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf;
@ -116,10 +117,9 @@ pub struct Transaction {
}
impl Transaction {
pub fn new(transaction_bytes: Vec<u8>) -> Result<Self, Alpha3Error> {
pub fn new(transaction_bytes: Vec<u8>) -> Result<Self, TransactionError> {
let mut decoder = Cursor::new(transaction_bytes);
let tx: BdkTransaction =
BdkTransaction::consensus_decode(&mut decoder).map_err(|_| Alpha3Error::Generic)?;
let tx: BdkTransaction = BdkTransaction::consensus_decode(&mut decoder)?;
Ok(Transaction { inner: tx })
}

View File

@ -10,6 +10,7 @@ use bdk::wallet::tx_builder::{AddUtxoError, AllowShrinkingError};
use bdk::wallet::{NewError, NewOrLoadError};
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)]
@ -167,6 +168,32 @@ pub enum AddressError {
OtherAddressError,
}
// Mapping https://docs.rs/bitcoin/latest/src/bitcoin/consensus/encode.rs.html#40-63
#[derive(Debug, thiserror::Error)]
pub enum TransactionError {
#[error("IO error")]
Io,
#[error("allocation of oversized vector")]
OversizedVectorAllocation,
#[error("invalid checksum: expected={expected} actual={actual}")]
InvalidChecksum { expected: String, actual: String },
#[error("non-minimal varint")]
NonMinimalVarInt,
#[error("parse failed")]
ParseFailed,
#[error("unsupported segwit version: {flag}")]
UnsupportedSegwitFlag { flag: u8 },
// This is required because the bdk::bitcoin::consensus::encode::Error is non-exhaustive
#[error("other transaction error")]
OtherTransactionError,
}
impl From<BdkFileError> for WalletCreationError {
fn from(error: BdkFileError) -> Self {
match error {
@ -344,6 +371,30 @@ impl From<bdk::bitcoin::address::Error> for AddressError {
}
}
impl From<bdk::bitcoin::consensus::encode::Error> for TransactionError {
fn from(error: bdk::bitcoin::consensus::encode::Error) -> Self {
match error {
bdk::bitcoin::consensus::encode::Error::Io(_) => TransactionError::Io,
bdk::bitcoin::consensus::encode::Error::OversizedVectorAllocation { .. } => {
TransactionError::OversizedVectorAllocation
}
bdk::bitcoin::consensus::encode::Error::InvalidChecksum { expected, actual } => {
let expected = DisplayHex::to_lower_hex_string(&expected);
let actual = DisplayHex::to_lower_hex_string(&actual);
TransactionError::InvalidChecksum { expected, actual }
}
bdk::bitcoin::consensus::encode::Error::NonMinimalVarInt => {
TransactionError::NonMinimalVarInt
}
bdk::bitcoin::consensus::encode::Error::ParseFailed(_) => TransactionError::ParseFailed,
bdk::bitcoin::consensus::encode::Error::UnsupportedSegwitFlag(flag) => {
TransactionError::UnsupportedSegwitFlag { flag }
}
_ => TransactionError::OtherTransactionError,
}
}
}
#[cfg(test)]
mod test {
use crate::error::{EsploraError, PersistenceError, WalletCreationError};

View File

@ -19,6 +19,7 @@ use crate::error::CalculateFeeError;
use crate::error::EsploraError;
use crate::error::FeeRateError;
use crate::error::PersistenceError;
use crate::error::TransactionError;
use crate::error::WalletCreationError;
use crate::esplora::EsploraClient;
use crate::keys::DerivationPath;