Skip to main content

bitcoin_rs_consensus/
rust_path.rs

1use bitcoin::{BlockHash, Network, OutPoint, TxOut};
2use bitcoin_rs_primitives::{Block, Tx};
3use bitcoin_rs_script::VerifyFlags;
4
5use crate::{ConsensusError, verify_block_rules, verify_transaction};
6
7/// Minimal UTXO lookup contract used by the portable validator.
8pub trait UtxoView {
9    /// Looks up a previous output by outpoint.
10    fn lookup(&self, outpoint: &OutPoint) -> Option<TxOut>;
11}
12
13impl<T> UtxoView for &T
14where
15    T: UtxoView + ?Sized,
16{
17    fn lookup(&self, outpoint: &OutPoint) -> Option<TxOut> {
18        (*self).lookup(outpoint)
19    }
20}
21
22impl UtxoView for std::collections::BTreeMap<OutPoint, TxOut> {
23    fn lookup(&self, outpoint: &OutPoint) -> Option<TxOut> {
24        self.get(outpoint).cloned()
25    }
26}
27
28/// Previous-tip state needed for contextual block connection.
29#[derive(Clone, Debug, PartialEq, Eq)]
30pub struct TipState {
31    /// Previous block height, or `None` before genesis.
32    pub height: Option<u32>,
33    /// Previous block hash, when known.
34    pub block_hash: Option<BlockHash>,
35    /// Median-time-past of the previous tip.
36    pub median_time_past: u32,
37}
38
39impl TipState {
40    /// Returns the height of the next block being connected.
41    #[must_use]
42    pub const fn next_height(&self) -> u32 {
43        match self.height {
44            Some(height) => height.saturating_add(1),
45            None => 0,
46        }
47    }
48}
49
50/// State produced after connecting a block through the portable path.
51#[derive(Clone, Debug, PartialEq, Eq)]
52pub struct BlockState {
53    /// Connected block height.
54    pub height: u32,
55    /// Connected block hash.
56    pub block_hash: BlockHash,
57    /// Total transaction count in the block.
58    pub tx_count: usize,
59}
60
61/// Portable Rust consensus validator.
62#[derive(Clone, Debug)]
63pub struct RustValidator {
64    network: Network,
65}
66
67impl RustValidator {
68    /// Creates a validator for a Bitcoin network.
69    #[must_use]
70    pub const fn new(network: Network) -> Self {
71        Self { network }
72    }
73
74    /// Returns the network this validator was configured for.
75    #[must_use]
76    pub const fn network(&self) -> Network {
77        self.network
78    }
79
80    /// Verifies one transaction against a supplied UTXO view.
81    pub fn verify_tx(
82        &self,
83        tx: &Tx,
84        prevouts: &impl UtxoView,
85        height: u32,
86        flags: VerifyFlags,
87    ) -> Result<(), ConsensusError> {
88        let _ = self.network;
89        verify_transaction(tx, prevouts, height, flags)
90    }
91
92    /// Connects block-level rules. Per-input UTXO updates land with Task 5.
93    pub fn connect_block(
94        &self,
95        block: &Block,
96        prev_tip: &TipState,
97    ) -> Result<BlockState, ConsensusError> {
98        let _ = self.network;
99        verify_block_rules(block, prev_tip)?;
100        Ok(BlockState {
101            height: prev_tip.next_height(),
102            block_hash: block.0.block_hash(),
103            tx_count: block.0.txdata.len(),
104        })
105    }
106}