use bitcoin::{BlockHash, Network, OutPoint, TxOut};
use bitcoin_rs_primitives::{Block, Tx};
use bitcoin_rs_script::VerifyFlags;
use crate::{ConsensusError, verify_block_rules, verify_transaction};
pub trait UtxoView {
fn lookup(&self, outpoint: &OutPoint) -> Option<TxOut>;
}
impl<T> UtxoView for &T
where
T: UtxoView + ?Sized,
{
fn lookup(&self, outpoint: &OutPoint) -> Option<TxOut> {
(*self).lookup(outpoint)
}
}
impl UtxoView for std::collections::BTreeMap<OutPoint, TxOut> {
fn lookup(&self, outpoint: &OutPoint) -> Option<TxOut> {
self.get(outpoint).cloned()
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TipState {
pub height: Option<u32>,
pub block_hash: Option<BlockHash>,
pub median_time_past: u32,
}
impl TipState {
#[must_use]
pub const fn next_height(&self) -> u32 {
match self.height {
Some(height) => height.saturating_add(1),
None => 0,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BlockState {
pub height: u32,
pub block_hash: BlockHash,
pub tx_count: usize,
}
#[derive(Clone, Debug)]
pub struct RustValidator {
network: Network,
}
impl RustValidator {
#[must_use]
pub const fn new(network: Network) -> Self {
Self { network }
}
#[must_use]
pub const fn network(&self) -> Network {
self.network
}
pub fn verify_tx(
&self,
tx: &Tx,
prevouts: &impl UtxoView,
height: u32,
flags: VerifyFlags,
) -> Result<(), ConsensusError> {
let _ = self.network;
verify_transaction(tx, prevouts, height, flags)
}
pub fn connect_block(
&self,
block: &Block,
prev_tip: &TipState,
) -> Result<BlockState, ConsensusError> {
let _ = self.network;
verify_block_rules(block, prev_tip)?;
Ok(BlockState {
height: prev_tip.next_height(),
block_hash: block.0.block_hash(),
tx_count: block.0.txdata.len(),
})
}
}