extern crate alloc;
pub mod chain_state;
pub mod chain_state_builder;
pub mod chainparams;
pub mod chainstore;
pub mod consensus;
pub mod error;
pub mod partial_chain;
pub mod udata;
use alloc::sync::Arc;
use bitcoin::block::Header as BlockHeader;
use bitcoin::hashes::sha256;
use bitcoin::Block;
use bitcoin::BlockHash;
use bitcoin::OutPoint;
use bitcoin::Transaction;
use bitcoin::TxOut;
use rustreexo::accumulator::node_hash::NodeHash;
use rustreexo::accumulator::proof::Proof;
use rustreexo::accumulator::stump::Stump;
use self::partial_chain::PartialChainState;
use crate::prelude::*;
use crate::BestChain;
use crate::BlockConsumer;
use crate::BlockchainError;
use crate::DatabaseError;
use crate::DiskBlockHeader;
use crate::UtreexoBlock;
pub trait BlockchainInterface {
type Error: core2::error::Error + Send + Sync + 'static;
fn get_block_hash(&self, height: u32) -> Result<bitcoin::BlockHash, Self::Error>;
fn get_tx(&self, txid: &bitcoin::Txid) -> Result<Option<bitcoin::Transaction>, Self::Error>;
fn get_height(&self) -> Result<u32, Self::Error>;
fn broadcast(&self, tx: &bitcoin::Transaction) -> Result<(), Self::Error>;
fn estimate_fee(&self, target: usize) -> Result<f64, Self::Error>;
fn get_block(&self, hash: &BlockHash) -> Result<Block, Self::Error>;
fn get_best_block(&self) -> Result<(u32, BlockHash), Self::Error>;
fn get_block_header(&self, hash: &BlockHash) -> Result<BlockHeader, Self::Error>;
fn subscribe(&self, tx: Arc<dyn BlockConsumer>);
fn is_in_idb(&self) -> bool;
fn get_unbroadcasted(&self) -> Vec<Transaction>;
fn is_coinbase_mature(&self, height: u32, block: BlockHash) -> Result<bool, Self::Error>;
fn get_block_locator(&self) -> Result<Vec<BlockHash>, Self::Error>;
fn get_block_locator_for_tip(&self, tip: BlockHash) -> Result<Vec<BlockHash>, BlockchainError>;
fn get_validation_index(&self) -> Result<u32, Self::Error>;
fn rescan(&self, start_height: u32) -> Result<(), Self::Error>;
fn get_rescan_index(&self) -> Option<u32>;
fn get_block_height(&self, hash: &BlockHash) -> Result<Option<u32>, Self::Error>;
fn update_acc(
&self,
acc: Stump,
block: UtreexoBlock,
height: u32,
proof: Proof,
del_hashes: Vec<sha256::Hash>,
) -> Result<Stump, Self::Error>;
fn get_chain_tips(&self) -> Result<Vec<BlockHash>, Self::Error>;
fn validate_block(
&self,
block: &Block,
proof: Proof,
inputs: HashMap<OutPoint, TxOut>,
del_hashes: Vec<sha256::Hash>,
acc: Stump,
) -> Result<(), Self::Error>;
fn get_fork_point(&self, block: BlockHash) -> Result<BlockHash, Self::Error>;
}
pub trait UpdatableChainstate {
fn connect_block(
&self,
block: &Block,
proof: Proof,
inputs: HashMap<OutPoint, TxOut>,
del_hashes: Vec<sha256::Hash>,
) -> Result<u32, BlockchainError>;
fn switch_chain(&self, new_tip: BlockHash) -> Result<(), BlockchainError>;
fn accept_header(&self, header: BlockHeader) -> Result<(), BlockchainError>;
fn handle_transaction(&self) -> Result<(), BlockchainError>;
fn flush(&self) -> Result<(), BlockchainError>;
fn toggle_ibd(&self, is_ibd: bool);
fn invalidate_block(&self, block: BlockHash) -> Result<(), BlockchainError>;
fn mark_block_as_valid(&self, block: BlockHash) -> Result<(), BlockchainError>;
fn process_rescan_block(&self, block: &Block) -> Result<(), BlockchainError>;
fn get_root_hashes(&self) -> Vec<NodeHash>;
fn get_partial_chain(
&self,
initial_height: u32,
final_height: u32,
acc: Stump,
) -> Result<PartialChainState, BlockchainError>;
fn mark_chain_as_assumed(&self, acc: Stump, tip: BlockHash) -> Result<bool, BlockchainError>;
}
pub trait ChainStore {
type Error: DatabaseError;
fn save_roots(&self, roots: Vec<u8>) -> Result<(), Self::Error>;
fn load_roots(&self) -> Result<Option<Vec<u8>>, Self::Error>;
fn load_height(&self) -> Result<Option<BestChain>, Self::Error>;
fn save_height(&self, height: &BestChain) -> Result<(), Self::Error>;
fn get_header(&self, block_hash: &BlockHash) -> Result<Option<DiskBlockHeader>, Self::Error>;
fn save_header(&self, header: &DiskBlockHeader) -> Result<(), Self::Error>;
fn get_block_hash(&self, height: u32) -> Result<Option<BlockHash>, Self::Error>;
fn flush(&self) -> Result<(), Self::Error>;
fn update_block_index(&self, height: u32, hash: BlockHash) -> Result<(), Self::Error>;
}
#[derive(Debug, Clone)]
pub enum Notification {
NewBlock((Block, u32)),
}
impl<T: UpdatableChainstate> UpdatableChainstate for Arc<T> {
fn flush(&self) -> Result<(), BlockchainError> {
T::flush(self)
}
fn toggle_ibd(&self, is_ibd: bool) {
T::toggle_ibd(self, is_ibd)
}
fn connect_block(
&self,
block: &Block,
proof: Proof,
inputs: HashMap<OutPoint, TxOut>,
del_hashes: Vec<sha256::Hash>,
) -> Result<u32, BlockchainError> {
T::connect_block(self, block, proof, inputs, del_hashes)
}
fn accept_header(&self, header: BlockHeader) -> Result<(), BlockchainError> {
T::accept_header(self, header)
}
fn get_root_hashes(&self) -> Vec<NodeHash> {
T::get_root_hashes(self)
}
fn invalidate_block(&self, block: BlockHash) -> Result<(), BlockchainError> {
T::invalidate_block(self, block)
}
fn get_partial_chain(
&self,
initial_height: u32,
final_height: u32,
acc: Stump,
) -> Result<PartialChainState, BlockchainError> {
T::get_partial_chain(self, initial_height, final_height, acc)
}
fn handle_transaction(&self) -> Result<(), BlockchainError> {
T::handle_transaction(self)
}
fn switch_chain(&self, new_tip: BlockHash) -> Result<(), BlockchainError> {
T::switch_chain(self, new_tip)
}
fn process_rescan_block(&self, block: &Block) -> Result<(), BlockchainError> {
T::process_rescan_block(self, block)
}
fn mark_block_as_valid(&self, block: BlockHash) -> Result<(), BlockchainError> {
T::mark_block_as_valid(self, block)
}
fn mark_chain_as_assumed(&self, acc: Stump, tip: BlockHash) -> Result<bool, BlockchainError> {
T::mark_chain_as_assumed(self, acc, tip)
}
}
impl<T: BlockchainInterface> BlockchainInterface for Arc<T> {
type Error = <T as BlockchainInterface>::Error;
fn get_tx(&self, txid: &bitcoin::Txid) -> Result<Option<bitcoin::Transaction>, Self::Error> {
T::get_tx(self, txid)
}
fn rescan(&self, start_height: u32) -> Result<(), Self::Error> {
T::rescan(self, start_height)
}
fn broadcast(&self, tx: &bitcoin::Transaction) -> Result<(), Self::Error> {
T::broadcast(self, tx)
}
fn get_block(&self, hash: &BlockHash) -> Result<Block, Self::Error> {
T::get_block(self, hash)
}
fn subscribe(&self, tx: Arc<dyn BlockConsumer>) {
T::subscribe(self, tx)
}
fn is_in_idb(&self) -> bool {
T::is_in_idb(self)
}
fn get_height(&self) -> Result<u32, Self::Error> {
T::get_height(self)
}
fn estimate_fee(&self, target: usize) -> Result<f64, Self::Error> {
T::estimate_fee(self, target)
}
fn get_block_hash(&self, height: u32) -> Result<bitcoin::BlockHash, Self::Error> {
T::get_block_hash(self, height)
}
fn get_best_block(&self) -> Result<(u32, BlockHash), Self::Error> {
T::get_best_block(self)
}
fn get_block_header(&self, hash: &BlockHash) -> Result<BlockHeader, Self::Error> {
T::get_block_header(self, hash)
}
fn get_rescan_index(&self) -> Option<u32> {
T::get_rescan_index(self)
}
fn get_block_height(&self, hash: &BlockHash) -> Result<Option<u32>, Self::Error> {
T::get_block_height(self, hash)
}
fn get_unbroadcasted(&self) -> Vec<Transaction> {
T::get_unbroadcasted(self)
}
fn get_block_locator(&self) -> Result<Vec<BlockHash>, Self::Error> {
T::get_block_locator(self)
}
fn is_coinbase_mature(&self, height: u32, block: BlockHash) -> Result<bool, Self::Error> {
T::is_coinbase_mature(self, height, block)
}
fn get_validation_index(&self) -> Result<u32, Self::Error> {
T::get_validation_index(self)
}
fn get_block_locator_for_tip(&self, tip: BlockHash) -> Result<Vec<BlockHash>, BlockchainError> {
T::get_block_locator_for_tip(self, tip)
}
fn update_acc(
&self,
acc: Stump,
block: UtreexoBlock,
height: u32,
proof: Proof,
del_hashes: Vec<sha256::Hash>,
) -> Result<Stump, Self::Error> {
T::update_acc(self, acc, block, height, proof, del_hashes)
}
fn get_chain_tips(&self) -> Result<Vec<BlockHash>, Self::Error> {
T::get_chain_tips(self)
}
fn validate_block(
&self,
block: &Block,
proof: Proof,
inputs: HashMap<OutPoint, TxOut>,
del_hashes: Vec<sha256::Hash>,
acc: Stump,
) -> Result<(), Self::Error> {
T::validate_block(self, block, proof, inputs, del_hashes, acc)
}
fn get_fork_point(&self, block: BlockHash) -> Result<BlockHash, Self::Error> {
T::get_fork_point(self, block)
}
}