2023-04-20 18:07:26 +08:00
|
|
|
use crate::collections::BTreeMap;
|
|
|
|
use crate::collections::BTreeSet;
|
2023-03-24 09:23:36 +08:00
|
|
|
use crate::BlockId;
|
2023-04-21 13:29:44 +08:00
|
|
|
use bitcoin::{Block, OutPoint, Transaction, TxOut};
|
2023-03-01 11:09:08 +01:00
|
|
|
|
|
|
|
/// Trait to do something with every txout contained in a structure.
|
|
|
|
///
|
2023-03-10 23:23:29 +05:30
|
|
|
/// We would prefer to just work with things that can give us an `Iterator<Item=(OutPoint, &TxOut)>`
|
|
|
|
/// here, but rust's type system makes it extremely hard to do this (without trait objects).
|
2023-03-01 11:09:08 +01:00
|
|
|
pub trait ForEachTxOut {
|
2023-03-10 23:23:29 +05:30
|
|
|
/// The provided closure `f` will be called with each `outpoint/txout` pair.
|
2023-03-01 11:09:08 +01:00
|
|
|
fn for_each_txout(&self, f: impl FnMut((OutPoint, &TxOut)));
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ForEachTxOut for Block {
|
|
|
|
fn for_each_txout(&self, mut f: impl FnMut((OutPoint, &TxOut))) {
|
|
|
|
for tx in self.txdata.iter() {
|
|
|
|
tx.for_each_txout(&mut f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-08 11:39:25 +13:00
|
|
|
impl ForEachTxOut for Transaction {
|
2023-03-01 11:09:08 +01:00
|
|
|
fn for_each_txout(&self, mut f: impl FnMut((OutPoint, &TxOut))) {
|
2023-03-08 11:39:25 +13:00
|
|
|
let txid = self.txid();
|
|
|
|
for (i, txout) in self.output.iter().enumerate() {
|
2023-03-01 11:09:08 +01:00
|
|
|
f((
|
|
|
|
OutPoint {
|
|
|
|
txid,
|
|
|
|
vout: i as u32,
|
|
|
|
},
|
|
|
|
txout,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-03-24 09:23:36 +08:00
|
|
|
|
2023-04-07 09:23:00 +08:00
|
|
|
/// Trait that "anchors" blockchain data to a specific block of height and hash.
|
2023-03-24 09:23:36 +08:00
|
|
|
///
|
2023-04-07 09:23:00 +08:00
|
|
|
/// I.e. If transaction A is anchored in block B, then if block B is in the best chain, we can
|
|
|
|
/// 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.
|
2023-04-21 13:29:44 +08:00
|
|
|
pub trait Anchor: core::fmt::Debug + Clone + Eq + PartialOrd + Ord + core::hash::Hash {
|
2023-03-24 09:23:36 +08:00
|
|
|
/// Returns the [`BlockId`] that the associated blockchain data is "anchored" in.
|
|
|
|
fn anchor_block(&self) -> BlockId;
|
|
|
|
|
2023-04-21 13:29:44 +08:00
|
|
|
/// Get the upper bound of the chain data's confirmation height.
|
|
|
|
///
|
|
|
|
/// The default definition gives a pessimistic answer. This can be overridden by the `Anchor`
|
|
|
|
/// implementation for a more accurate value.
|
|
|
|
fn confirmation_height_upper_bound(&self) -> u32 {
|
|
|
|
self.anchor_block().height
|
2023-03-24 15:47:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-21 13:29:44 +08:00
|
|
|
impl<A: Anchor> Anchor for &'static A {
|
2023-03-24 09:23:36 +08:00
|
|
|
fn anchor_block(&self) -> BlockId {
|
2023-04-21 13:29:44 +08:00
|
|
|
<A as Anchor>::anchor_block(self)
|
2023-03-24 09:23:36 +08:00
|
|
|
}
|
|
|
|
}
|
2023-03-24 15:47:39 +08:00
|
|
|
|
2023-04-05 17:29:20 +08:00
|
|
|
/// Trait that makes an object appendable.
|
|
|
|
pub trait Append {
|
|
|
|
/// Append another object of the same type onto `self`.
|
|
|
|
fn append(&mut self, other: Self);
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Append for () {
|
|
|
|
fn append(&mut self, _other: Self) {}
|
|
|
|
}
|
2023-04-20 18:07:26 +08:00
|
|
|
|
|
|
|
impl<K: Ord, V> Append for BTreeMap<K, V> {
|
|
|
|
fn append(&mut self, mut other: Self) {
|
|
|
|
BTreeMap::append(self, &mut other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Ord> Append for BTreeSet<T> {
|
|
|
|
fn append(&mut self, mut other: Self) {
|
|
|
|
BTreeSet::append(self, &mut other)
|
|
|
|
}
|
|
|
|
}
|