Skip to content

Commit

Permalink
Merge #1069: Implement Anchor for BlockId
Browse files Browse the repository at this point in the history
18e8da3 docs: Add doctest for Anchor implementation on BlockId (Vladimir Fomene)
480c273 feat: Implement Anchor for BlockId (Vladimir Fomene)

Pull request description:

  ### Description

  This PR fixes #1062.
  It implements the `Anchor` trait on `BlockId`.

  ### Checklists

  #### All Submissions:

  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
  * [x] I ran `cargo fmt` and `cargo clippy` before committing

  #### New Features:

  * [x] I've added tests for the new feature
  * [x] I've added docs for the new feature

ACKs for top commit:
  evanlinjin:
    ACK 18e8da3

Tree-SHA512: af9da8b4e9c7f2a110340efa4e4c86d9b96ea1275f0a66f08e26a47fcacd89e318a32c845e2a4302f3332eeb4c6a976c3771b1d9881adf4feda90d6ba1a2dd9d
  • Loading branch information
evanlinjin committed Aug 28, 2023
2 parents 8f978f8 + 18e8da3 commit e5fb1ec
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
13 changes: 13 additions & 0 deletions crates/chain/src/chain_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ impl From<ChainPosition<ConfirmationTimeAnchor>> for ConfirmationTime {
}

/// A reference to a block in the canonical chain.
///
/// `BlockId` implements [`Anchor`]. When a transaction is anchored to `BlockId`, the confirmation
/// block and anchor block are the same block.
#[derive(Debug, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, core::hash::Hash)]
#[cfg_attr(
feature = "serde",
Expand All @@ -100,6 +103,12 @@ pub struct BlockId {
pub hash: BlockHash,
}

impl Anchor for BlockId {
fn anchor_block(&self) -> Self {
*self
}
}

impl Default for BlockId {
fn default() -> Self {
Self {
Expand Down Expand Up @@ -131,6 +140,8 @@ impl From<(&u32, &BlockHash)> for BlockId {
}

/// An [`Anchor`] implementation that also records the exact confirmation height of the transaction.
///
/// Refer to [`Anchor`] for more details.
#[derive(Debug, Default, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, core::hash::Hash)]
#[cfg_attr(
feature = "serde",
Expand Down Expand Up @@ -159,6 +170,8 @@ impl Anchor for ConfirmationHeightAnchor {

/// An [`Anchor`] implementation that also records the exact confirmation time and height of the
/// transaction.
///
/// Refer to [`Anchor`] for more details.
#[derive(Debug, Default, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, core::hash::Hash)]
#[cfg_attr(
feature = "serde",
Expand Down
52 changes: 52 additions & 0 deletions crates/chain/src/tx_data_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,58 @@ impl ForEachTxOut for Transaction {
/// assume that transaction A is also confirmed in the best chain. This does not necessarily mean
/// that transaction A is confirmed in block B. It could also mean transaction A is confirmed in a
/// parent block of B.
///
/// ```
/// # use bdk_chain::local_chain::LocalChain;
/// # use bdk_chain::tx_graph::TxGraph;
/// # use bdk_chain::BlockId;
/// # use bdk_chain::ConfirmationHeightAnchor;
/// # use bdk_chain::example_utils::*;
/// # use bitcoin::hashes::Hash;
///
/// // Initialize the local chain with two blocks.
/// let chain = LocalChain::from_blocks(
/// [
/// (1, Hash::hash("first".as_bytes())),
/// (2, Hash::hash("second".as_bytes())),
/// ]
/// .into_iter()
/// .collect(),
/// );
///
/// // Transaction to be inserted into `TxGraph`s with different anchor types.
/// let tx = tx_from_hex(RAW_TX_1);
///
/// // Insert `tx` into a `TxGraph` that uses `BlockId` as the anchor type.
/// // When a transaction is anchored with `BlockId`, the anchor block and the confirmation block of
/// // the transaction is the same block.
/// let mut graph_a = TxGraph::<BlockId>::default();
/// let _ = graph_a.insert_tx(tx.clone());
/// graph_a.insert_anchor(
/// tx.txid(),
/// BlockId {
/// height: 1,
/// hash: Hash::hash("first".as_bytes()),
/// },
/// );
///
/// // Insert `tx` into a `TxGraph` that uses `ConfirmationHeightAnchor` as the anchor type.
/// // When a transaction is anchored with `ConfirmationHeightAnchor`, the anchor block and
/// // confirmation block can be different. However, the confirmation block cannot be higher than
/// // the anchor block and both blocks must be in the same chain for the anchor to be valid.
/// let mut graph_b = TxGraph::<ConfirmationHeightAnchor>::default();
/// let _ = graph_b.insert_tx(tx.clone());
/// graph_b.insert_anchor(
/// tx.txid(),
/// ConfirmationHeightAnchor {
/// anchor_block: BlockId {
/// height: 2,
/// hash: Hash::hash("second".as_bytes()),
/// },
/// confirmation_height: 1,
/// },
/// );
/// ```
pub trait Anchor: core::fmt::Debug + Clone + Eq + PartialOrd + Ord + core::hash::Hash {
/// Returns the [`BlockId`] that the associated blockchain data is "anchored" in.
fn anchor_block(&self) -> BlockId;
Expand Down

0 comments on commit e5fb1ec

Please sign in to comment.