Skip to content

Commit d608592

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 34aa59f commit d608592

File tree

9 files changed

+56
-54
lines changed

9 files changed

+56
-54
lines changed

bdk-ffi/src/bitcoin.rs

Lines changed: 10 additions & 10 deletions
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

Lines changed: 8 additions & 0 deletions
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

Lines changed: 7 additions & 5 deletions
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};
@@ -131,12 +131,12 @@ impl ElectrumClient {
131131
}
132132

133133
/// Broadcasts a transaction to the network.
134-
pub fn transaction_broadcast(&self, tx: &Transaction) -> Result<String, ElectrumError> {
134+
pub fn transaction_broadcast(&self, tx: &Transaction) -> Result<Arc<Txid>, ElectrumError> {
135135
let bdk_transaction: BdkTransaction = tx.into();
136136
self.0
137137
.transaction_broadcast(&bdk_transaction)
138138
.map_err(ElectrumError::from)
139-
.map(|txid| txid.to_string())
139+
.map(|txid| Arc::new(Txid(txid)))
140140
}
141141

142142
/// Returns the capabilities of the server.
@@ -177,7 +177,7 @@ pub struct ServerFeaturesRes {
177177
/// Server version reported.
178178
pub server_version: String,
179179
/// Hash of the genesis block.
180-
pub genesis_hash: String,
180+
pub genesis_hash: Arc<BlockHash>,
181181
/// Minimum supported version of the protocol.
182182
pub protocol_min: String,
183183
/// Maximum supported version of the protocol.
@@ -190,9 +190,11 @@ pub struct ServerFeaturesRes {
190190

191191
impl From<BdkServerFeaturesRes> for ServerFeaturesRes {
192192
fn from(value: BdkServerFeaturesRes) -> ServerFeaturesRes {
193+
let hash_str = value.genesis_hash.to_hex_string(Case::Lower);
194+
let blockhash = hash_str.parse::<bdk_core::bitcoin::BlockHash>().unwrap();
193195
ServerFeaturesRes {
194196
server_version: value.server_version,
195-
genesis_hash: value.genesis_hash.to_hex_string(Case::Lower),
197+
genesis_hash: Arc::new(BlockHash(blockhash)),
196198
protocol_min: value.protocol_min,
197199
protocol_max: value.protocol_max,
198200
hash_function: value.hash_function,

bdk-ffi/src/esplora.rs

Lines changed: 10 additions & 13 deletions
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

Lines changed: 7 additions & 9 deletions
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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::bitcoin::{Address, Amount, BlockHash, 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;
@@ -52,7 +52,7 @@ pub enum ChainPosition {
5252
/// A child transaction that has been confirmed. Due to incomplete information,
5353
/// it is only known that this transaction is confirmed at a chain height less than
5454
/// or equal to this child TXID.
55-
transitively: Option<String>,
55+
transitively: Option<Arc<Txid>>,
5656
},
5757
/// The transaction was last seen in the mempool at this timestamp.
5858
Unconfirmed { timestamp: Option<u64> },
@@ -74,7 +74,7 @@ impl From<BdkChainPosition<BdkConfirmationBlockTime>> for ChainPosition {
7474
block_id,
7575
confirmation_time: anchor.confirmation_time,
7676
},
77-
transitively: transitively.map(|t| t.to_string()),
77+
transitively: transitively.map(|t| Arc::new(Txid(t))),
7878
}
7979
}
8080
BdkChainPosition::Unconfirmed { last_seen } => ChainPosition::Unconfirmed {
@@ -213,7 +213,7 @@ impl From<BdkLocalOutput> for LocalOutput {
213213
fn from(local_utxo: BdkLocalOutput) -> Self {
214214
LocalOutput {
215215
outpoint: OutPoint {
216-
txid: local_utxo.outpoint.txid.to_string(),
216+
txid: Arc::new(Txid(local_utxo.outpoint.txid)),
217217
vout: local_utxo.outpoint.vout,
218218
},
219219
txout: TxOut {
@@ -668,7 +668,7 @@ pub struct TxStatus {
668668
/// Height of the block this transaction was included.
669669
pub block_height: Option<u32>,
670670
/// Hash of the block.
671-
pub block_hash: Option<String>,
671+
pub block_hash: Option<Arc<BlockHash>>,
672672
/// The time shown in the block, not necessarily the same time as when the block was found.
673673
pub block_time: Option<u64>,
674674
}
@@ -678,7 +678,7 @@ impl From<BdkTxStatus> for TxStatus {
678678
TxStatus {
679679
confirmed: status.confirmed,
680680
block_height: status.block_height,
681-
block_hash: status.block_hash.map(|h| h.to_string()),
681+
block_hash: status.block_hash.map(|h| Arc::new(BlockHash(h))),
682682
block_time: status.block_time,
683683
}
684684
}
@@ -688,7 +688,7 @@ impl From<BdkTxStatus> for TxStatus {
688688
#[derive(Debug, uniffi::Record)]
689689
pub struct Tx {
690690
/// The transaction identifier.
691-
pub txid: String,
691+
pub txid: Arc<Txid>,
692692
/// The transaction version, of which 0, 1, 2 are standard.
693693
pub version: i32,
694694
/// The block height or time restriction on the transaction.
@@ -706,7 +706,7 @@ pub struct Tx {
706706
impl From<BdkTx> for Tx {
707707
fn from(tx: BdkTx) -> Self {
708708
Self {
709-
txid: tx.txid.to_string(),
709+
txid: Arc::new(Txid(tx.txid)),
710710
version: tx.version,
711711
locktime: tx.locktime,
712712
size: tx.size as u64,

bdk-ffi/src/wallet.rs

Lines changed: 4 additions & 7 deletions
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,
@@ -11,13 +11,12 @@ use crate::types::{
1111
Update,
1212
};
1313

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

1919
use std::borrow::BorrowMut;
20-
use std::str::FromStr;
2120
use std::sync::{Arc, Mutex, MutexGuard};
2221

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

344341
/// 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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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)