diff --git a/crates/chain/src/chain_data.rs b/crates/chain/src/chain_data.rs index d8ce8cda..33381ab7 100644 --- a/crates/chain/src/chain_data.rs +++ b/crates/chain/src/chain_data.rs @@ -12,9 +12,6 @@ use crate::{ pub enum ObservedAs { /// The chain data is seen as confirmed, and in anchored by `A`. Confirmed(A), - /// The chain data is assumed to be confirmed, because a transaction that spends it is anchored - /// by `A`. - ConfirmedImplicit(A), /// The chain data is seen in mempool at this given timestamp. Unconfirmed(u64), } @@ -23,7 +20,6 @@ impl ObservedAs<&A> { pub fn cloned(self) -> ObservedAs { match self { ObservedAs::Confirmed(a) => ObservedAs::Confirmed(a.clone()), - ObservedAs::ConfirmedImplicit(a) => ObservedAs::ConfirmedImplicit(a.clone()), ObservedAs::Unconfirmed(last_seen) => ObservedAs::Unconfirmed(last_seen), } } @@ -259,9 +255,6 @@ impl FullTxOut> { let tx_height = match &self.chain_position { ObservedAs::Confirmed(anchor) => anchor.confirmation_height(), - // although we do not know the exact confirm height, the returned height here is the - // "upper bound" so only false-negatives are possible - ObservedAs::ConfirmedImplicit(anchor) => anchor.confirmation_height(), ObservedAs::Unconfirmed(_) => { debug_assert!(false, "coinbase tx can never be unconfirmed"); return false; @@ -291,9 +284,6 @@ impl FullTxOut> { let confirmation_height = match &self.chain_position { ObservedAs::Confirmed(anchor) => anchor.confirmation_height(), - // although we do not know the exact confirm height, the returned height here is the - // "upper bound" so only false-negatives are possible - ObservedAs::ConfirmedImplicit(anchor) => anchor.confirmation_height(), ObservedAs::Unconfirmed(_) => return false, }; if confirmation_height > tip { diff --git a/crates/chain/src/indexed_tx_graph.rs b/crates/chain/src/indexed_tx_graph.rs index 00137c41..fd5aa6d9 100644 --- a/crates/chain/src/indexed_tx_graph.rs +++ b/crates/chain/src/indexed_tx_graph.rs @@ -251,7 +251,7 @@ impl IndexedTxGraph { let txout = res?; match &txout.chain_position { - ObservedAs::Confirmed(_) | ObservedAs::ConfirmedImplicit(_) => { + ObservedAs::Confirmed(_) => { if txout.is_on_coinbase { if txout.is_observed_as_mature(tip) { confirmed += txout.txout.value; diff --git a/crates/chain/src/local_chain.rs b/crates/chain/src/local_chain.rs index e3385e1b..9ba64b28 100644 --- a/crates/chain/src/local_chain.rs +++ b/crates/chain/src/local_chain.rs @@ -1,21 +1,23 @@ -use core::{convert::Infallible, ops::Deref}; +use core::convert::Infallible; use alloc::collections::{BTreeMap, BTreeSet}; use bitcoin::BlockHash; use crate::{Append, BlockId, ChainOracle}; +/// This is a local implementation of [`ChainOracle`]. +/// +/// TODO: We need a cache/snapshot thing for chain oracle. +/// * Minimize calls to remotes. +/// * Can we cache it forever? Should we drop stuff? +/// * Assume anything deeper than (i.e. 10) blocks won't be reorged. +/// * Is this a cache on txs or block? or both? +/// TODO: Parents of children are confirmed if children are confirmed. #[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct LocalChain { blocks: BTreeMap, } -// [TODO] We need a cache/snapshot thing for chain oracle. -// * Minimize calls to remotes. -// * Can we cache it forever? Should we drop stuff? -// * Assume anything deeper than (i.e. 10) blocks won't be reorged. -// * Is this a cache on txs or block? or both? -// [TODO] Parents of children are confirmed if children are confirmed. impl ChainOracle for LocalChain { type Error = Infallible; @@ -114,12 +116,12 @@ impl LocalChain { changeset.insert(*height, *new_hash); } } - Ok(ChangeSet(changeset)) + Ok(changeset) } /// Applies the given `changeset`. pub fn apply_changeset(&mut self, mut changeset: ChangeSet) { - self.blocks.append(&mut changeset.0) + self.blocks.append(&mut changeset) } /// Updates [`LocalChain`] with an update [`LocalChain`]. @@ -135,7 +137,7 @@ impl LocalChain { } pub fn initial_changeset(&self) -> ChangeSet { - ChangeSet(self.blocks.clone()) + self.blocks.clone() } pub fn heights(&self) -> BTreeSet { @@ -146,25 +148,11 @@ impl LocalChain { /// This is the return value of [`determine_changeset`] and represents changes to [`LocalChain`]. /// /// [`determine_changeset`]: LocalChain::determine_changeset -#[derive(Debug, Default, Clone, PartialEq)] -#[cfg_attr( - feature = "serde", - derive(serde::Deserialize, serde::Serialize), - serde(crate = "serde_crate") -)] -pub struct ChangeSet(pub(crate) BTreeMap); - -impl Deref for ChangeSet { - type Target = BTreeMap; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} +type ChangeSet = BTreeMap; impl Append for ChangeSet { fn append(&mut self, mut other: Self) { - BTreeMap::append(&mut self.0, &mut other.0) + BTreeMap::append(self, &mut other) } } diff --git a/crates/chain/src/tx_graph.rs b/crates/chain/src/tx_graph.rs index 7c32606a..5d06bbda 100644 --- a/crates/chain/src/tx_graph.rs +++ b/crates/chain/src/tx_graph.rs @@ -644,24 +644,6 @@ impl TxGraph { } } - // If we cannot determine whether tx is in best chain, we can check whether a spending tx is - // confirmed and in best chain, and if so, it is guaranteed that this tx is in the best - // chain. - // - // [TODO] This logic is incomplete as we do not check spends of spends. - let spending_anchors = self - .spends - .range(OutPoint::new(txid, u32::MIN)..=OutPoint::new(txid, u32::MAX)) - .flat_map(|(_, spending_txids)| spending_txids) - .filter_map(|spending_txid| self.txs.get(spending_txid)) - .flat_map(|(_, spending_anchors, _)| spending_anchors); - for spending_anchor in spending_anchors { - match chain.is_block_in_chain(spending_anchor.anchor_block(), chain_tip)? { - Some(true) => return Ok(Some(ObservedAs::ConfirmedImplicit(spending_anchor))), - _ => continue, - } - } - // The tx is not anchored to a block which is in the best chain, let's check whether we can // ignore it by checking conflicts! let tx = match tx_node {