Skip to content

Commit 6f7626a

Browse files
committed
feat!: introduce bdk_core
This is an initial version with `chain_data` types ported over. Types ported over include `BlockId`, `ConfirmationBlockTime`. The impls for `Anchor` and `AnchorFromBlockPosition` of these types are moved to where the traits are defined.
1 parent ccb8c79 commit 6f7626a

File tree

14 files changed

+217
-144
lines changed

14 files changed

+217
-144
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ resolver = "2"
33
members = [
44
"crates/wallet",
55
"crates/chain",
6+
"crates/core",
67
"crates/file_store",
78
"crates/electrum",
89
"crates/esplora",

crates/chain/Cargo.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@ readme = "README.md"
1414

1515
[dependencies]
1616
bitcoin = { version = "0.32.0", default-features = false }
17+
bdk_core = { path = "../core", version = "0.1", default-features = false }
1718
serde = { version = "1", optional = true, features = ["derive", "rc"] }
18-
19-
# Use hashbrown as a feature flag to have HashSet and HashMap from it.
20-
hashbrown = { version = "0.9.1", optional = true, features = ["serde"] }
2119
miniscript = { version = "12.0.0", optional = true, default-features = false }
2220

2321
# Feature dependencies
@@ -30,6 +28,7 @@ proptest = "1.2.0"
3028

3129
[features]
3230
default = ["std", "miniscript"]
33-
std = ["bitcoin/std", "miniscript?/std"]
34-
serde = ["dep:serde", "bitcoin/serde", "miniscript?/serde"]
31+
std = ["bitcoin/std", "miniscript?/std", "bdk_core/std"]
32+
serde = ["dep:serde", "bitcoin/serde", "miniscript?/serde", "bdk_core/serde"]
33+
hashbrown = ["bdk_core/hashbrown"]
3534
rusqlite = ["std", "dep:rusqlite", "serde", "serde_json"]

crates/chain/src/chain_data.rs

Lines changed: 5 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use bitcoin::{hashes::Hash, BlockHash, OutPoint, TxOut, Txid};
1+
use crate::ConfirmationBlockTime;
2+
use bitcoin::{OutPoint, TxOut, Txid};
23

3-
use crate::{Anchor, AnchorFromBlockPosition, COINBASE_MATURITY};
4+
use crate::{Anchor, COINBASE_MATURITY};
45

56
/// Represents the observed position of some chain data.
67
///
@@ -82,92 +83,6 @@ impl From<ChainPosition<ConfirmationBlockTime>> for ConfirmationTime {
8283
}
8384
}
8485

85-
/// A reference to a block in the canonical chain.
86-
///
87-
/// `BlockId` implements [`Anchor`]. When a transaction is anchored to `BlockId`, the confirmation
88-
/// block and anchor block are the same block.
89-
#[derive(Debug, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, core::hash::Hash)]
90-
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
91-
pub struct BlockId {
92-
/// The height of the block.
93-
pub height: u32,
94-
/// The hash of the block.
95-
pub hash: BlockHash,
96-
}
97-
98-
impl Anchor for BlockId {
99-
fn anchor_block(&self) -> Self {
100-
*self
101-
}
102-
}
103-
104-
impl AnchorFromBlockPosition for BlockId {
105-
fn from_block_position(_block: &bitcoin::Block, block_id: BlockId, _tx_pos: usize) -> Self {
106-
block_id
107-
}
108-
}
109-
110-
impl Default for BlockId {
111-
fn default() -> Self {
112-
Self {
113-
height: Default::default(),
114-
hash: BlockHash::all_zeros(),
115-
}
116-
}
117-
}
118-
119-
impl From<(u32, BlockHash)> for BlockId {
120-
fn from((height, hash): (u32, BlockHash)) -> Self {
121-
Self { height, hash }
122-
}
123-
}
124-
125-
impl From<BlockId> for (u32, BlockHash) {
126-
fn from(block_id: BlockId) -> Self {
127-
(block_id.height, block_id.hash)
128-
}
129-
}
130-
131-
impl From<(&u32, &BlockHash)> for BlockId {
132-
fn from((height, hash): (&u32, &BlockHash)) -> Self {
133-
Self {
134-
height: *height,
135-
hash: *hash,
136-
}
137-
}
138-
}
139-
140-
/// An [`Anchor`] implementation that also records the exact confirmation time of the transaction.
141-
///
142-
/// Refer to [`Anchor`] for more details.
143-
#[derive(Debug, Default, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, core::hash::Hash)]
144-
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
145-
pub struct ConfirmationBlockTime {
146-
/// The anchor block.
147-
pub block_id: BlockId,
148-
/// The confirmation time of the transaction being anchored.
149-
pub confirmation_time: u64,
150-
}
151-
152-
impl Anchor for ConfirmationBlockTime {
153-
fn anchor_block(&self) -> BlockId {
154-
self.block_id
155-
}
156-
157-
fn confirmation_height_upper_bound(&self) -> u32 {
158-
self.block_id.height
159-
}
160-
}
161-
162-
impl AnchorFromBlockPosition for ConfirmationBlockTime {
163-
fn from_block_position(block: &bitcoin::Block, block_id: BlockId, _tx_pos: usize) -> Self {
164-
Self {
165-
block_id,
166-
confirmation_time: block.header.time as _,
167-
}
168-
}
169-
}
170-
17186
/// A `TxOut` with as much data as we can retrieve about it
17287
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
17388
pub struct FullTxOut<A> {
@@ -244,6 +159,8 @@ impl<A: Anchor> FullTxOut<A> {
244159

245160
#[cfg(test)]
246161
mod test {
162+
use crate::BlockId;
163+
247164
use super::*;
248165

249166
#[test]

crates/chain/src/example_utils.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
#![allow(unused)]
2+
use crate::BlockId;
23
use alloc::vec::Vec;
34
use bitcoin::{
45
consensus,
56
hashes::{hex::FromHex, Hash},
67
Transaction,
78
};
89

9-
use crate::BlockId;
10-
1110
pub const RAW_TX_1: &str = "0200000000010116d6174da7183d70d0a7d4dc314d517a7d135db79ad63515028b293a76f4f9d10000000000feffffff023a21fc8350060000160014531c405e1881ef192294b8813631e258bf98ea7a1027000000000000225120a60869f0dbcf1dc659c9cecbaf8050135ea9e8cdc487053f1dc6880949dc684c024730440220591b1a172a122da49ba79a3e79f98aaa03fd7a372f9760da18890b6a327e6010022013e82319231da6c99abf8123d7c07e13cf9bd8d76e113e18dc452e5024db156d012102318a2d558b2936c52e320decd6d92a88d7f530be91b6fe0af5caf41661e77da3ef2e0100";
1211
pub const RAW_TX_2: &str = "02000000000101a688607020cfae91a61e7c516b5ef1264d5d77f17200c3866826c6c808ebf1620000000000feffffff021027000000000000225120a60869f0dbcf1dc659c9cecbaf8050135ea9e8cdc487053f1dc6880949dc684c20fd48ff530600001600146886c525e41d4522042bd0b159dfbade2504a6bb024730440220740ff7e665cd20565d4296b549df8d26b941be3f1e3af89a0b60e50c0dbeb69a02206213ab7030cf6edc6c90d4ccf33010644261e029950a688dc0b1a9ebe6ddcc5a012102f2ac6b396a97853cb6cd62242c8ae4842024742074475023532a51e9c53194253e760100";
1312
pub const RAW_TX_3: &str = "0200000000010135d67ee47b557e68b8c6223958f597381965ed719f1207ee2b9e20432a24a5dc0100000000feffffff021027000000000000225120a82f29944d65b86ae6b5e5cc75e294ead6c59391a1edc5e016e3498c67fc7bbb62215a5055060000160014070df7671dea67a50c4799a744b5c9be8f4bac690247304402207ebf8d29f71fd03e7e6977b3ea78ca5fcc5c49a42ae822348fc401862fdd766c02201d7e4ff0684ecb008b6142f36ead1b0b4d615524c4f58c261113d361f4427e25012103e6a75e2fab85e5ecad641afc4ffba7222f998649d9f18cac92f0fcc8618883b3ee760100";

crates/chain/src/lib.rs

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ pub use indexer::spk_txout;
3838
pub use indexer::Indexer;
3939
pub mod local_chain;
4040
mod tx_data_traits;
41-
pub mod tx_graph;
4241
pub use tx_data_traits::*;
42+
pub mod tx_graph;
4343
pub use tx_graph::TxGraph;
4444
mod chain_oracle;
4545
pub use chain_oracle::*;
@@ -63,6 +63,9 @@ pub use spk_iter::*;
6363
pub mod rusqlite_impl;
6464
pub mod spk_client;
6565

66+
pub extern crate bdk_core;
67+
pub use bdk_core::*;
68+
6669
#[allow(unused_imports)]
6770
#[macro_use]
6871
extern crate alloc;
@@ -75,37 +78,6 @@ pub extern crate serde;
7578
#[macro_use]
7679
extern crate std;
7780

78-
#[cfg(all(not(feature = "std"), feature = "hashbrown"))]
79-
extern crate hashbrown;
80-
81-
// When no-std use `alloc`'s Hash collections. This is activated by default
82-
#[cfg(all(not(feature = "std"), not(feature = "hashbrown")))]
83-
#[doc(hidden)]
84-
pub mod collections {
85-
#![allow(dead_code)]
86-
pub type HashSet<K> = alloc::collections::BTreeSet<K>;
87-
pub type HashMap<K, V> = alloc::collections::BTreeMap<K, V>;
88-
pub use alloc::collections::{btree_map as hash_map, *};
89-
}
90-
91-
// When we have std, use `std`'s all collections
92-
#[cfg(all(feature = "std", not(feature = "hashbrown")))]
93-
#[doc(hidden)]
94-
pub mod collections {
95-
pub use std::collections::{hash_map, *};
96-
}
97-
98-
// With this special feature `hashbrown`, use `hashbrown`'s hash collections, and else from `alloc`.
99-
#[cfg(feature = "hashbrown")]
100-
#[doc(hidden)]
101-
pub mod collections {
102-
#![allow(dead_code)]
103-
pub type HashSet<K> = hashbrown::HashSet<K>;
104-
pub type HashMap<K, V> = hashbrown::HashMap<K, V>;
105-
pub use alloc::collections::*;
106-
pub use hashbrown::hash_map;
107-
}
108-
10981
/// How many confirmations are needed f or a coinbase output to be spent.
11082
pub const COINBASE_MATURITY: u32 = 100;
11183

@@ -137,3 +109,27 @@ impl<T> core::ops::Deref for Impl<T> {
137109
&self.0
138110
}
139111
}
112+
113+
/// A wrapper that we use to impl remote traits for types in our crate or dependency crates that impl [`Anchor`].
114+
pub struct AnchorImpl<T>(pub T);
115+
116+
impl<T> AnchorImpl<T> {
117+
/// Returns the inner `T`.
118+
pub fn into_inner(self) -> T {
119+
self.0
120+
}
121+
}
122+
123+
impl<T> From<T> for AnchorImpl<T> {
124+
fn from(value: T) -> Self {
125+
Self(value)
126+
}
127+
}
128+
129+
impl<T> core::ops::Deref for AnchorImpl<T> {
130+
type Target = T;
131+
132+
fn deref(&self) -> &Self::Target {
133+
&self.0
134+
}
135+
}

crates/chain/src/rusqlite_impl.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,15 +157,15 @@ impl ToSql for Impl<bitcoin::Amount> {
157157
}
158158
}
159159

160-
impl<A: Anchor + serde::de::DeserializeOwned> FromSql for Impl<A> {
160+
impl<A: Anchor + serde::de::DeserializeOwned> FromSql for AnchorImpl<A> {
161161
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
162162
serde_json::from_str(value.as_str()?)
163-
.map(Impl)
163+
.map(AnchorImpl)
164164
.map_err(from_sql_error)
165165
}
166166
}
167167

168-
impl<A: Anchor + serde::Serialize> ToSql for Impl<A> {
168+
impl<A: Anchor + serde::Serialize> ToSql for AnchorImpl<A> {
169169
fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
170170
serde_json::to_string(&self.0)
171171
.map(Into::into)
@@ -319,12 +319,12 @@ where
319319
))?;
320320
let row_iter = statement.query_map([], |row| {
321321
Ok((
322-
row.get::<_, Impl<A>>("json(anchor)")?,
322+
row.get::<_, AnchorImpl<A>>("json(anchor)")?,
323323
row.get::<_, Impl<bitcoin::Txid>>("txid")?,
324324
))
325325
})?;
326326
for row in row_iter {
327-
let (Impl(anchor), Impl(txid)) = row?;
327+
let (AnchorImpl(anchor), Impl(txid)) = row?;
328328
changeset.anchors.insert((anchor, txid));
329329
}
330330

@@ -381,7 +381,7 @@ where
381381
":txid": Impl(*txid),
382382
":block_height": anchor_block.height,
383383
":block_hash": Impl(anchor_block.hash),
384-
":anchor": Impl(anchor.clone()),
384+
":anchor": AnchorImpl(anchor.clone()),
385385
})?;
386386
}
387387

crates/chain/src/spk_client.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ use crate::{
33
alloc::{boxed::Box, collections::VecDeque, vec::Vec},
44
collections::BTreeMap,
55
local_chain::CheckPoint,
6-
ConfirmationBlockTime, Indexed,
6+
Indexed,
77
};
8+
use bdk_core::ConfirmationBlockTime;
89
use bitcoin::{OutPoint, Script, ScriptBuf, Txid};
910

1011
type InspectSync<I> = dyn FnMut(SyncItem<I>, SyncProgress) + Send + 'static;

crates/chain/src/tx_data_traits.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
use crate::collections::BTreeMap;
2-
use crate::collections::BTreeSet;
3-
use crate::BlockId;
1+
use crate::collections::{BTreeMap, BTreeSet};
2+
use crate::{BlockId, ConfirmationBlockTime};
43
use alloc::vec::Vec;
54

65
/// Trait that "anchors" blockchain data to a specific block of height and hash.
@@ -85,13 +84,44 @@ impl<'a, A: Anchor> Anchor for &'a A {
8584
}
8685
}
8786

87+
impl Anchor for BlockId {
88+
fn anchor_block(&self) -> Self {
89+
*self
90+
}
91+
}
92+
93+
impl Anchor for ConfirmationBlockTime {
94+
fn anchor_block(&self) -> BlockId {
95+
self.block_id
96+
}
97+
98+
fn confirmation_height_upper_bound(&self) -> u32 {
99+
self.block_id.height
100+
}
101+
}
102+
88103
/// An [`Anchor`] that can be constructed from a given block, block height and transaction position
89104
/// within the block.
90105
pub trait AnchorFromBlockPosition: Anchor {
91106
/// Construct the anchor from a given `block`, block height and `tx_pos` within the block.
92107
fn from_block_position(block: &bitcoin::Block, block_id: BlockId, tx_pos: usize) -> Self;
93108
}
94109

110+
impl AnchorFromBlockPosition for BlockId {
111+
fn from_block_position(_block: &bitcoin::Block, block_id: BlockId, _tx_pos: usize) -> Self {
112+
block_id
113+
}
114+
}
115+
116+
impl AnchorFromBlockPosition for ConfirmationBlockTime {
117+
fn from_block_position(block: &bitcoin::Block, block_id: BlockId, _tx_pos: usize) -> Self {
118+
Self {
119+
block_id,
120+
confirmation_time: block.header.time as _,
121+
}
122+
}
123+
}
124+
95125
/// Trait that makes an object mergeable.
96126
pub trait Merge: Default {
97127
/// Merge another object of the same type onto `self`.

crates/chain/src/tx_graph.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@
9292
//! [`try_get_chain_position`]: TxGraph::try_get_chain_position
9393
//! [`insert_txout`]: TxGraph::insert_txout
9494
95-
use crate::{
96-
collections::*, Anchor, Balance, BlockId, ChainOracle, ChainPosition, FullTxOut, Merge,
97-
};
95+
use crate::collections::*;
96+
use crate::BlockId;
97+
use crate::{Anchor, Balance, ChainOracle, ChainPosition, FullTxOut, Merge};
9898
use alloc::collections::vec_deque::VecDeque;
9999
use alloc::sync::Arc;
100100
use alloc::vec::Vec;

crates/chain/tests/test_tx_graph.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
#[macro_use]
44
mod common;
5-
use bdk_chain::tx_graph::{self, CalculateFeeError};
5+
use bdk_chain::{collections::*, BlockId, ConfirmationBlockTime};
66
use bdk_chain::{
7-
collections::*,
87
local_chain::LocalChain,
8+
tx_graph::{self, CalculateFeeError},
99
tx_graph::{ChangeSet, TxGraph},
10-
Anchor, BlockId, ChainOracle, ChainPosition, ConfirmationBlockTime, Merge,
10+
Anchor, ChainOracle, ChainPosition, Merge,
1111
};
1212
use bitcoin::{
1313
absolute, hashes::Hash, transaction, Amount, BlockHash, OutPoint, ScriptBuf, SignedAmount,

0 commit comments

Comments
 (0)