Skip to content

Commit 0d80e13

Browse files
committed
refactor: use Txid, BlockHash, DescriptorId, TxMerkleNode where applicable
Explicitly leaving out `BlockId` to avoid merge conflicts. The refactor here is moslty uneventful, however it removes a handful of `unwrap` when parsing transaction IDs.
1 parent ed7064f commit 0d80e13

File tree

9 files changed

+55
-55
lines changed

9 files changed

+55
-55
lines changed

bdk-ffi/src/bitcoin.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ use std::sync::{Arc, Mutex};
4040
#[derive(Debug, Clone, Eq, PartialEq, uniffi:: Record)]
4141
pub struct OutPoint {
4242
/// The transaction.
43-
pub txid: String,
43+
pub txid: Arc<Txid>,
4444
/// The index of the output in the transaction.
4545
pub vout: u32,
4646
}
4747

4848
impl From<&BdkOutPoint> for OutPoint {
4949
fn from(outpoint: &BdkOutPoint) -> Self {
5050
OutPoint {
51-
txid: outpoint.txid.to_string(),
51+
txid: Arc::new(Txid(outpoint.txid)),
5252
vout: outpoint.vout,
5353
}
5454
}
@@ -57,7 +57,7 @@ impl From<&BdkOutPoint> for OutPoint {
5757
impl From<OutPoint> for BdkOutPoint {
5858
fn from(outpoint: OutPoint) -> Self {
5959
BdkOutPoint {
60-
txid: BitcoinTxid::from_str(&outpoint.txid).unwrap(),
60+
txid: BitcoinTxid::from_raw_hash(outpoint.txid.0.to_raw_hash()),
6161
vout: outpoint.vout,
6262
}
6363
}
@@ -169,9 +169,9 @@ pub struct Header {
169169
/// Block version, now repurposed for soft fork signalling.
170170
pub version: i32,
171171
/// Reference to the previous block in the chain.
172-
pub prev_blockhash: String,
172+
pub prev_blockhash: Arc<BlockHash>,
173173
/// The root hash of the merkle tree of transactions in the block.
174-
pub merkle_root: String,
174+
pub merkle_root: Arc<TxMerkleNode>,
175175
/// The timestamp of the block, as claimed by the miner.
176176
pub time: u32,
177177
/// The target value below which the blockhash must lie.
@@ -184,8 +184,8 @@ impl From<BdkHeader> for Header {
184184
fn from(bdk_header: BdkHeader) -> Self {
185185
Header {
186186
version: bdk_header.version.to_consensus(),
187-
prev_blockhash: bdk_header.prev_blockhash.to_string(),
188-
merkle_root: bdk_header.merkle_root.to_string(),
187+
prev_blockhash: Arc::new(BlockHash(bdk_header.prev_blockhash)),
188+
merkle_root: Arc::new(TxMerkleNode(bdk_header.merkle_root.to_raw_hash())),
189189
time: bdk_header.time,
190190
bits: bdk_header.bits.to_consensus(),
191191
nonce: bdk_header.nonce,
@@ -304,8 +304,8 @@ impl Transaction {
304304

305305
/// Computes the Txid.
306306
/// Hashes the transaction excluding the segwit data (i.e. the marker, flag bytes, and the witness fields themselves).
307-
pub fn compute_txid(&self) -> String {
308-
self.0.compute_txid().to_string()
307+
pub fn compute_txid(&self) -> Arc<Txid> {
308+
Arc::new(Txid(self.0.compute_txid()))
309309
}
310310

311311
/// Returns the weight of this transaction, as defined by BIP-141.
@@ -549,7 +549,7 @@ impl From<&BdkTxIn> for TxIn {
549549
fn from(tx_in: &BdkTxIn) -> Self {
550550
TxIn {
551551
previous_output: OutPoint {
552-
txid: tx_in.previous_output.txid.to_string(),
552+
txid: Arc::new(Txid(tx_in.previous_output.txid)),
553553
vout: tx_in.previous_output.vout,
554554
},
555555
script_sig: Arc::new(Script(tx_in.script_sig.clone())),

bdk-ffi/src/descriptor.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
use crate::bitcoin::DescriptorId;
12
use crate::error::DescriptorError;
23
use crate::keys::DescriptorPublicKey;
34
use crate::keys::DescriptorSecretKey;
45

56
use bdk_wallet::bitcoin::bip32::Fingerprint;
67
use bdk_wallet::bitcoin::key::Secp256k1;
78
use bdk_wallet::bitcoin::Network;
9+
use bdk_wallet::chain::DescriptorExt;
810
use bdk_wallet::descriptor::{ExtendedDescriptor, IntoWalletDescriptor};
911
use bdk_wallet::keys::DescriptorPublicKey as BdkDescriptorPublicKey;
1012
use bdk_wallet::keys::{DescriptorSecretKey as BdkDescriptorSecretKey, KeyMap};
@@ -296,6 +298,12 @@ impl Descriptor {
296298
self.extended_descriptor.is_multipath()
297299
}
298300

301+
/// A unique identifier for the descriptor.
302+
pub fn descriptor_id(&self) -> Arc<DescriptorId> {
303+
let d_id = self.extended_descriptor.descriptor_id();
304+
Arc::new(DescriptorId(d_id.0))
305+
}
306+
299307
/// Return descriptors for all valid paths.
300308
pub fn to_single_descriptors(&self) -> Result<Vec<Arc<Descriptor>>, MiniscriptError> {
301309
self.extended_descriptor

bdk-ffi/src/electrum.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::bitcoin::{Header, Transaction};
1+
use crate::bitcoin::{BlockHash, Header, Transaction, Txid};
22
use crate::error::ElectrumError;
33
use crate::types::Update;
44
use crate::types::{FullScanRequest, SyncRequest};
@@ -14,7 +14,6 @@ use bdk_wallet::bitcoin::Transaction as BdkTransaction;
1414
use bdk_wallet::KeychainKind;
1515
use bdk_wallet::Update as BdkUpdate;
1616

17-
use bdk_core::bitcoin::hex::{Case, DisplayHex};
1817
use bdk_electrum::electrum_client::ElectrumApi;
1918
use std::collections::BTreeMap;
2019
use std::sync::Arc;
@@ -131,12 +130,12 @@ impl ElectrumClient {
131130
}
132131

133132
/// Broadcasts a transaction to the network.
134-
pub fn transaction_broadcast(&self, tx: &Transaction) -> Result<String, ElectrumError> {
133+
pub fn transaction_broadcast(&self, tx: &Transaction) -> Result<Arc<Txid>, ElectrumError> {
135134
let bdk_transaction: BdkTransaction = tx.into();
136135
self.0
137136
.transaction_broadcast(&bdk_transaction)
138137
.map_err(ElectrumError::from)
139-
.map(|txid| txid.to_string())
138+
.map(|txid| Arc::new(Txid(txid)))
140139
}
141140

142141
/// Returns the capabilities of the server.
@@ -177,7 +176,7 @@ pub struct ServerFeaturesRes {
177176
/// Server version reported.
178177
pub server_version: String,
179178
/// Hash of the genesis block.
180-
pub genesis_hash: String,
179+
pub genesis_hash: Arc<BlockHash>,
181180
/// Minimum supported version of the protocol.
182181
pub protocol_min: String,
183182
/// Maximum supported version of the protocol.
@@ -190,9 +189,10 @@ pub struct ServerFeaturesRes {
190189

191190
impl From<BdkServerFeaturesRes> for ServerFeaturesRes {
192191
fn from(value: BdkServerFeaturesRes) -> ServerFeaturesRes {
192+
let blockhash = BlockHash::from_bytes(value.genesis_hash.to_vec()).unwrap();
193193
ServerFeaturesRes {
194194
server_version: value.server_version,
195-
genesis_hash: value.genesis_hash.to_hex_string(Case::Lower),
195+
genesis_hash: Arc::new(blockhash),
196196
protocol_min: value.protocol_min,
197197
protocol_max: value.protocol_max,
198198
hash_function: value.hash_function,

bdk-ffi/src/esplora.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
use crate::bitcoin::BlockHash;
12
use crate::bitcoin::Transaction;
3+
use crate::bitcoin::Txid;
24
use crate::error::EsploraError;
35
use crate::types::Tx;
46
use crate::types::TxStatus;
@@ -8,7 +10,6 @@ use crate::types::{FullScanRequest, SyncRequest};
810
use bdk_esplora::esplora_client::{BlockingClient, Builder};
911
use bdk_esplora::EsploraExt;
1012
use bdk_wallet::bitcoin::Transaction as BdkTransaction;
11-
use bdk_wallet::bitcoin::Txid;
1213
use bdk_wallet::chain::spk_client::FullScanRequest as BdkFullScanRequest;
1314
use bdk_wallet::chain::spk_client::FullScanResponse as BdkFullScanResponse;
1415
use bdk_wallet::chain::spk_client::SyncRequest as BdkSyncRequest;
@@ -17,7 +18,6 @@ use bdk_wallet::KeychainKind;
1718
use bdk_wallet::Update as BdkUpdate;
1819

1920
use std::collections::{BTreeMap, HashMap};
20-
use std::str::FromStr;
2121
use std::sync::Arc;
2222

2323
/// Wrapper around an esplora_client::BlockingClient which includes an internal in-memory transaction
@@ -110,9 +110,8 @@ impl EsploraClient {
110110
}
111111

112112
/// Get a [`Transaction`] option given its [`Txid`].
113-
pub fn get_tx(&self, txid: String) -> Result<Option<Arc<Transaction>>, EsploraError> {
114-
let txid = Txid::from_str(&txid)?;
115-
let tx_opt = self.0.get_tx(&txid)?;
113+
pub fn get_tx(&self, txid: Arc<Txid>) -> Result<Option<Arc<Transaction>>, EsploraError> {
114+
let tx_opt = self.0.get_tx(&txid.0)?;
116115
Ok(tx_opt.map(|inner| Arc::new(Transaction::from(inner))))
117116
}
118117

@@ -128,27 +127,25 @@ impl EsploraClient {
128127
}
129128

130129
/// Get the [`BlockHash`] of a specific block height.
131-
pub fn get_block_hash(&self, block_height: u32) -> Result<String, EsploraError> {
130+
pub fn get_block_hash(&self, block_height: u32) -> Result<Arc<BlockHash>, EsploraError> {
132131
self.0
133132
.get_block_hash(block_height)
134-
.map(|hash| hash.to_string())
133+
.map(|hash| Arc::new(BlockHash(hash)))
135134
.map_err(EsploraError::from)
136135
}
137136

138137
/// Get the status of a [`Transaction`] given its [`Txid`].
139-
pub fn get_tx_status(&self, txid: String) -> Result<TxStatus, EsploraError> {
140-
let txid = Txid::from_str(&txid)?;
138+
pub fn get_tx_status(&self, txid: Arc<Txid>) -> Result<TxStatus, EsploraError> {
141139
self.0
142-
.get_tx_status(&txid)
140+
.get_tx_status(&txid.0)
143141
.map(TxStatus::from)
144142
.map_err(EsploraError::from)
145143
}
146144

147145
/// Get transaction info given its [`Txid`].
148-
pub fn get_tx_info(&self, txid: String) -> Result<Option<Tx>, EsploraError> {
149-
let txid = Txid::from_str(&txid)?;
146+
pub fn get_tx_info(&self, txid: Arc<Txid>) -> Result<Option<Tx>, EsploraError> {
150147
self.0
151-
.get_tx_info(&txid)
148+
.get_tx_info(&txid.0)
152149
.map(|tx| tx.map(Tx::from))
153150
.map_err(EsploraError::from)
154151
}

bdk-ffi/src/tx_builder.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::bitcoin::{Amount, FeeRate, OutPoint, Psbt, Script};
1+
use crate::bitcoin::{Amount, FeeRate, OutPoint, Psbt, Script, Txid};
22
use crate::error::CreateTxError;
33
use crate::types::{LockTime, ScriptAmount};
44
use crate::wallet::Wallet;
@@ -8,13 +8,12 @@ use bdk_wallet::bitcoin::amount::Amount as BdkAmount;
88
use bdk_wallet::bitcoin::script::PushBytesBuf;
99
use bdk_wallet::bitcoin::Psbt as BdkPsbt;
1010
use bdk_wallet::bitcoin::ScriptBuf as BdkScriptBuf;
11-
use bdk_wallet::bitcoin::{OutPoint as BdkOutPoint, Sequence, Txid};
11+
use bdk_wallet::bitcoin::{OutPoint as BdkOutPoint, Sequence};
1212
use bdk_wallet::KeychainKind;
1313

1414
use std::collections::BTreeMap;
1515
use std::collections::HashMap;
1616
use std::convert::{TryFrom, TryInto};
17-
use std::str::FromStr;
1817
use std::sync::Arc;
1918

2019
type ChangeSpendPolicy = bdk_wallet::ChangeSpendPolicy;
@@ -413,7 +412,7 @@ impl TxBuilder {
413412
/// until finally calling `finish` to consume the builder and generate the transaction.
414413
#[derive(Clone, uniffi::Object)]
415414
pub struct BumpFeeTxBuilder {
416-
txid: String,
415+
txid: Arc<Txid>,
417416
fee_rate: Arc<FeeRate>,
418417
sequence: Option<u32>,
419418
current_height: Option<u32>,
@@ -425,7 +424,7 @@ pub struct BumpFeeTxBuilder {
425424
#[uniffi::export]
426425
impl BumpFeeTxBuilder {
427426
#[uniffi::constructor]
428-
pub fn new(txid: String, fee_rate: Arc<FeeRate>) -> Self {
427+
pub fn new(txid: Arc<Txid>, fee_rate: Arc<FeeRate>) -> Self {
429428
BumpFeeTxBuilder {
430429
txid,
431430
fee_rate,
@@ -506,11 +505,10 @@ impl BumpFeeTxBuilder {
506505
/// WARNING: To avoid change address reuse you must persist the changes resulting from one or more calls to this
507506
/// method before closing the wallet. See `Wallet::reveal_next_address`.
508507
pub fn finish(&self, wallet: &Arc<Wallet>) -> Result<Arc<Psbt>, CreateTxError> {
509-
let txid = Txid::from_str(self.txid.as_str()).map_err(|_| CreateTxError::UnknownUtxo {
510-
outpoint: self.txid.clone(),
511-
})?;
512508
let mut wallet = wallet.get_wallet();
513-
let mut tx_builder = wallet.build_fee_bump(txid).map_err(CreateTxError::from)?;
509+
let mut tx_builder = wallet
510+
.build_fee_bump(self.txid.0)
511+
.map_err(CreateTxError::from)?;
514512
tx_builder.fee_rate(self.fee_rate.0);
515513
if let Some(sequence) = self.sequence {
516514
tx_builder.set_exact_sequence(Sequence(sequence));

bdk-ffi/src/types.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::bitcoin::{Address, Amount, OutPoint, Script, Transaction, TxOut};
1+
use crate::bitcoin::{Address, Amount, BlockHash, OutPoint, Script, Transaction, TxOut, Txid};
22
use crate::error::{CreateTxError, RequestBuilderError};
33

44
use bdk_core::bitcoin::absolute::LockTime as BdkLockTime;
@@ -51,7 +51,7 @@ pub enum ChainPosition {
5151
/// A child transaction that has been confirmed. Due to incomplete information,
5252
/// it is only known that this transaction is confirmed at a chain height less than
5353
/// or equal to this child TXID.
54-
transitively: Option<String>,
54+
transitively: Option<Arc<Txid>>,
5555
},
5656
/// The transaction was last seen in the mempool at this timestamp.
5757
Unconfirmed { timestamp: Option<u64> },
@@ -73,7 +73,7 @@ impl From<BdkChainPosition<BdkConfirmationBlockTime>> for ChainPosition {
7373
block_id,
7474
confirmation_time: anchor.confirmation_time,
7575
},
76-
transitively: transitively.map(|t| t.to_string()),
76+
transitively: transitively.map(|t| Arc::new(Txid(t))),
7777
}
7878
}
7979
BdkChainPosition::Unconfirmed { last_seen } => ChainPosition::Unconfirmed {
@@ -203,7 +203,7 @@ impl From<BdkLocalOutput> for LocalOutput {
203203
fn from(local_utxo: BdkLocalOutput) -> Self {
204204
LocalOutput {
205205
outpoint: OutPoint {
206-
txid: local_utxo.outpoint.txid.to_string(),
206+
txid: Arc::new(Txid(local_utxo.outpoint.txid)),
207207
vout: local_utxo.outpoint.vout,
208208
},
209209
txout: TxOut {
@@ -658,7 +658,7 @@ pub struct TxStatus {
658658
/// Height of the block this transaction was included.
659659
pub block_height: Option<u32>,
660660
/// Hash of the block.
661-
pub block_hash: Option<String>,
661+
pub block_hash: Option<Arc<BlockHash>>,
662662
/// The time shown in the block, not necessarily the same time as when the block was found.
663663
pub block_time: Option<u64>,
664664
}
@@ -668,7 +668,7 @@ impl From<BdkTxStatus> for TxStatus {
668668
TxStatus {
669669
confirmed: status.confirmed,
670670
block_height: status.block_height,
671-
block_hash: status.block_hash.map(|h| h.to_string()),
671+
block_hash: status.block_hash.map(|h| Arc::new(BlockHash(h))),
672672
block_time: status.block_time,
673673
}
674674
}
@@ -678,7 +678,7 @@ impl From<BdkTxStatus> for TxStatus {
678678
#[derive(Debug, uniffi::Record)]
679679
pub struct Tx {
680680
/// The transaction identifier.
681-
pub txid: String,
681+
pub txid: Arc<Txid>,
682682
/// The transaction version, of which 0, 1, 2 are standard.
683683
pub version: i32,
684684
/// The block height or time restriction on the transaction.
@@ -696,7 +696,7 @@ pub struct Tx {
696696
impl From<BdkTx> for Tx {
697697
fn from(tx: BdkTx) -> Self {
698698
Self {
699-
txid: tx.txid.to_string(),
699+
txid: Arc::new(Txid(tx.txid)),
700700
version: tx.version,
701701
locktime: tx.locktime,
702702
size: tx.size as u64,

bdk-ffi/src/wallet.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::bitcoin::{Amount, FeeRate, OutPoint, Psbt, Script, Transaction};
1+
use crate::bitcoin::{Amount, FeeRate, OutPoint, Psbt, Script, Transaction, Txid};
22
use crate::descriptor::Descriptor;
33
use crate::error::{
44
CalculateFeeError, CannotConnectError, CreateWithPersistError, DescriptorError,
@@ -10,13 +10,12 @@ use crate::types::{
1010
Policy, SentAndReceivedValues, SignOptions, SyncRequestBuilder, UnconfirmedTx, Update,
1111
};
1212

13-
use bdk_wallet::bitcoin::{Network, Txid};
13+
use bdk_wallet::bitcoin::Network;
1414
use bdk_wallet::rusqlite::Connection as BdkConnection;
1515
use bdk_wallet::signer::SignOptions as BdkSignOptions;
1616
use bdk_wallet::{KeychainKind, PersistedWallet, Wallet as BdkWallet};
1717

1818
use std::borrow::BorrowMut;
19-
use std::str::FromStr;
2019
use std::sync::{Arc, Mutex, MutexGuard};
2120

2221
/// A Bitcoin wallet.
@@ -334,10 +333,8 @@ impl Wallet {
334333
/// confirmed or unconfirmed. If the transaction is confirmed, the anchor which proves the
335334
/// confirmation is provided. If the transaction is unconfirmed, the unix timestamp of when
336335
/// the transaction was last seen in the mempool is provided.
337-
pub fn get_tx(&self, txid: String) -> Result<Option<CanonicalTx>, TxidParseError> {
338-
let txid =
339-
Txid::from_str(txid.as_str()).map_err(|_| TxidParseError::InvalidTxid { txid })?;
340-
Ok(self.get_wallet().get_tx(txid).map(|tx| tx.into()))
336+
pub fn get_tx(&self, txid: Arc<Txid>) -> Result<Option<CanonicalTx>, TxidParseError> {
337+
Ok(self.get_wallet().get_tx(txid.0).map(|tx| tx.into()))
341338
}
342339

343340
/// Calculates the fee of a given transaction. Returns [`Amount::ZERO`] if `tx` is a coinbase transaction.

bdk-jvm/lib/src/test/kotlin/org/bitcoindevkit/LiveElectrumClientTest.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class LiveElectrumClientTest {
4848

4949
assertEquals(
5050
expected = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943",
51-
actual = features.genesisHash
51+
actual = features.genesisHash.toString()
5252
)
5353
}
5454

bdk-swift/Tests/BitcoinDevKitTests/LiveElectrumClientTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ final class LiveElectrumClientTests: XCTestCase {
5454
print("Server Features:\n\(features)")
5555

5656
XCTAssertEqual(
57-
features.genesisHash,
57+
features.genesisHash.description,
5858
"000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
5959
)
6060
}

0 commit comments

Comments
 (0)