diff --git a/crates/chain/src/chain_data.rs b/crates/chain/src/chain_data.rs index 550854298..537f0bf7e 100644 --- a/crates/chain/src/chain_data.rs +++ b/crates/chain/src/chain_data.rs @@ -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 { diff --git a/crates/chain/src/tx_data_traits.rs b/crates/chain/src/tx_data_traits.rs index 274bae36e..c957a3e57 100644 --- a/crates/chain/src/tx_data_traits.rs +++ b/crates/chain/src/tx_data_traits.rs @@ -76,12 +76,19 @@ pub trait Anchor: core::fmt::Debug + Clone + Eq + PartialOrd + Ord + core::hash: } } -impl Anchor for &'static A { +impl<'a, A: Anchor> Anchor for &'a A { fn anchor_block(&self) -> BlockId { ::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`.