]> Untitled Git - bdk/commitdiff
feat(chain): add `AnchorFromBlockPosition` trait
author志宇 <hello@evanlinjin.me>
Wed, 4 Oct 2023 08:54:28 +0000 (16:54 +0800)
committer志宇 <hello@evanlinjin.me>
Mon, 9 Oct 2023 14:14:03 +0000 (22:14 +0800)
This is useful for block-by-block chain sources. We can determine the
tx's anchor based on the block, block height and tx position in the
block.

crates/chain/src/chain_data.rs
crates/chain/src/tx_data_traits.rs

index 5508542989575d8a4abeadb23aa4e9f8a9481317..537f0bf7e9ee899ec372206c6d742e65d6b678c7 100644 (file)
@@ -1,6 +1,6 @@
 use bitcoin::{hashes::Hash, BlockHash, OutPoint, TxOut, Txid};
 
-use crate::{Anchor, COINBASE_MATURITY};
+use crate::{Anchor, AnchorFromBlockPosition, COINBASE_MATURITY};
 
 /// Represents the observed position of some chain data.
 ///
@@ -109,6 +109,12 @@ impl Anchor for BlockId {
     }
 }
 
+impl AnchorFromBlockPosition for BlockId {
+    fn from_block_position(_block: &bitcoin::Block, block_id: BlockId, _tx_pos: usize) -> Self {
+        block_id
+    }
+}
+
 impl Default for BlockId {
     fn default() -> Self {
         Self {
@@ -168,6 +174,15 @@ impl Anchor for ConfirmationHeightAnchor {
     }
 }
 
+impl AnchorFromBlockPosition for ConfirmationHeightAnchor {
+    fn from_block_position(_block: &bitcoin::Block, block_id: BlockId, _tx_pos: usize) -> Self {
+        Self {
+            anchor_block: block_id,
+            confirmation_height: block_id.height,
+        }
+    }
+}
+
 /// An [`Anchor`] implementation that also records the exact confirmation time and height of the
 /// transaction.
 ///
@@ -196,6 +211,17 @@ impl Anchor for ConfirmationTimeAnchor {
         self.confirmation_height
     }
 }
+
+impl AnchorFromBlockPosition for ConfirmationTimeAnchor {
+    fn from_block_position(block: &bitcoin::Block, block_id: BlockId, _tx_pos: usize) -> Self {
+        Self {
+            anchor_block: block_id,
+            confirmation_height: block_id.height,
+            confirmation_time: block.header.time as _,
+        }
+    }
+}
+
 /// A `TxOut` with as much data as we can retrieve about it
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
 pub struct FullTxOut<A> {
index 274bae36e8dca5db9fd05246d03d8dcd4cf31bd0..c957a3e57e07668382afdf19c96b69f395f33bf3 100644 (file)
@@ -76,12 +76,19 @@ pub trait Anchor: core::fmt::Debug + Clone + Eq + PartialOrd + Ord + core::hash:
     }
 }
 
-impl<A: Anchor> Anchor for &'static A {
+impl<'a, A: Anchor> Anchor for &'a A {
     fn anchor_block(&self) -> BlockId {
         <A as Anchor>::anchor_block(self)
     }
 }
 
+/// An [`Anchor`] that can be constructed from a given block, block height and transaction position
+/// within the block.
+pub trait AnchorFromBlockPosition: Anchor {
+    /// Construct the anchor from a given `block`, block height and `tx_pos` within the block.
+    fn from_block_position(block: &bitcoin::Block, block_id: BlockId, tx_pos: usize) -> Self;
+}
+
 /// Trait that makes an object appendable.
 pub trait Append {
     /// Append another object of the same type onto `self`.