[chain_redesign] BlockId should not implement Anchor
If `BlockId` implements `Anchor`, the meaning is ambiguous. We cannot tell whether it means the tx is anchors at the block, or whether it also means the tx is confirmed at that block. Instead, `ConfirmationHeightAnchor` and `ConfirmationTimeAnchor` structs are introduced as non-ambiguous `Anchor` implementations. Additionally, `TxGraph::relevant_heights` is removed because it is also ambiguous. What heights are deemed relevant? A simpler and more flexible method `TxGraph::all_anchors` is introduced instead.
This commit is contained in:
@@ -160,12 +160,6 @@ impl Default for BlockId {
|
||||
}
|
||||
}
|
||||
|
||||
impl Anchor for BlockId {
|
||||
fn anchor_block(&self) -> BlockId {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(u32, BlockHash)> for BlockId {
|
||||
fn from((height, hash): (u32, BlockHash)) -> Self {
|
||||
Self { height, hash }
|
||||
@@ -187,6 +181,58 @@ impl From<(&u32, &BlockHash)> for BlockId {
|
||||
}
|
||||
}
|
||||
|
||||
/// An [`Anchor`] implementation that also records the exact confirmation height of the transaction.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, core::hash::Hash)]
|
||||
#[cfg_attr(
|
||||
feature = "serde",
|
||||
derive(serde::Deserialize, serde::Serialize),
|
||||
serde(crate = "serde_crate")
|
||||
)]
|
||||
pub struct ConfirmationHeightAnchor {
|
||||
/// The anchor block.
|
||||
pub anchor_block: BlockId,
|
||||
|
||||
/// The exact confirmation height of the transaction.
|
||||
///
|
||||
/// It is assumed that this value is never larger than the height of the anchor block.
|
||||
pub confirmation_height: u32,
|
||||
}
|
||||
|
||||
impl Anchor for ConfirmationHeightAnchor {
|
||||
fn anchor_block(&self) -> BlockId {
|
||||
self.anchor_block
|
||||
}
|
||||
|
||||
fn confirmation_height_upper_bound(&self) -> u32 {
|
||||
self.confirmation_height
|
||||
}
|
||||
}
|
||||
|
||||
/// An [`Anchor`] implementation that also records the exact confirmation time and height of the
|
||||
/// transaction.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, core::hash::Hash)]
|
||||
#[cfg_attr(
|
||||
feature = "serde",
|
||||
derive(serde::Deserialize, serde::Serialize),
|
||||
serde(crate = "serde_crate")
|
||||
)]
|
||||
pub struct ConfirmationTimeAnchor {
|
||||
/// The anchor block.
|
||||
pub anchor_block: BlockId,
|
||||
|
||||
pub confirmation_height: u32,
|
||||
pub confirmation_time: u64,
|
||||
}
|
||||
|
||||
impl Anchor for ConfirmationTimeAnchor {
|
||||
fn anchor_block(&self) -> BlockId {
|
||||
self.anchor_block
|
||||
}
|
||||
|
||||
fn confirmation_height_upper_bound(&self) -> u32 {
|
||||
self.confirmation_height
|
||||
}
|
||||
}
|
||||
/// A `TxOut` with as much data as we can retrieve about it
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct FullTxOut<P> {
|
||||
|
||||
@@ -349,6 +349,11 @@ impl<A> TxGraph<A> {
|
||||
.filter(move |(_, conflicting_txid)| *conflicting_txid != txid)
|
||||
}
|
||||
|
||||
/// Get all transaction anchors known by [`TxGraph`].
|
||||
pub fn all_anchors(&self) -> &BTreeSet<(A, Txid)> {
|
||||
&self.anchors
|
||||
}
|
||||
|
||||
/// Whether the graph has any transactions or outputs in it.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.txs.is_empty()
|
||||
@@ -592,21 +597,6 @@ impl<A: Clone + Ord> TxGraph<A> {
|
||||
}
|
||||
|
||||
impl<A: Anchor> TxGraph<A> {
|
||||
/// Get all heights that are relevant to the graph.
|
||||
pub fn relevant_heights(&self) -> impl Iterator<Item = u32> + '_ {
|
||||
let mut last_height = Option::<u32>::None;
|
||||
self.anchors
|
||||
.iter()
|
||||
.map(|(a, _)| a.anchor_block().height)
|
||||
.filter(move |&height| {
|
||||
let is_unique = Some(height) != last_height;
|
||||
if is_unique {
|
||||
last_height = Some(height);
|
||||
}
|
||||
is_unique
|
||||
})
|
||||
}
|
||||
|
||||
/// Get the position of the transaction in `chain` with tip `chain_tip`.
|
||||
///
|
||||
/// If the given transaction of `txid` does not exist in the chain of `chain_tip`, `None` is
|
||||
|
||||
Reference in New Issue
Block a user