feat(chain): add AnchorFromBlockPosition trait

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.
This commit is contained in:
志宇 2023-10-04 16:54:28 +08:00
parent f795a43cc7
commit b3db5ca9df
No known key found for this signature in database
GPG Key ID: F6345C9837C2BDE8
2 changed files with 35 additions and 2 deletions

View File

@ -1,6 +1,6 @@
use bitcoin::{hashes::Hash, BlockHash, OutPoint, TxOut, Txid}; 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. /// 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 { impl Default for BlockId {
fn default() -> Self { fn default() -> Self {
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 /// An [`Anchor`] implementation that also records the exact confirmation time and height of the
/// transaction. /// transaction.
/// ///
@ -196,6 +211,17 @@ impl Anchor for ConfirmationTimeAnchor {
self.confirmation_height 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 /// A `TxOut` with as much data as we can retrieve about it
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct FullTxOut<A> { pub struct FullTxOut<A> {

View 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 { fn anchor_block(&self) -> BlockId {
<A as Anchor>::anchor_block(self) <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. /// Trait that makes an object appendable.
pub trait Append { pub trait Append {
/// Append another object of the same type onto `self`. /// Append another object of the same type onto `self`.