use crate::{
coinbase::MinerData,
header::Header,
tx::{Transaction, TransactionId},
BlueWorkType,
};
use kaspa_hashes::Hash;
use kaspa_utils::mem_size::MemSizeEstimator;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct MutableBlock {
pub header: Header,
pub transactions: Vec<Transaction>,
}
impl MutableBlock {
pub fn new(header: Header, txs: Vec<Transaction>) -> Self {
Self { header, transactions: txs }
}
pub fn from_header(header: Header) -> Self {
Self::new(header, vec![])
}
pub fn to_immutable(self) -> Block {
Block::new(self.header, self.transactions)
}
}
#[derive(Debug, Clone)]
pub struct Block {
pub header: Arc<Header>,
pub transactions: Arc<Vec<Transaction>>,
}
impl Block {
pub fn new(header: Header, txs: Vec<Transaction>) -> Self {
Self { header: Arc::new(header), transactions: Arc::new(txs) }
}
pub fn from_arcs(header: Arc<Header>, transactions: Arc<Vec<Transaction>>) -> Self {
Self { header, transactions }
}
pub fn from_header_arc(header: Arc<Header>) -> Self {
Self { header, transactions: Arc::new(Vec::new()) }
}
pub fn from_header(header: Header) -> Self {
Self { header: Arc::new(header), transactions: Arc::new(Vec::new()) }
}
pub fn is_header_only(&self) -> bool {
self.transactions.is_empty()
}
pub fn hash(&self) -> Hash {
self.header.hash
}
pub fn from_precomputed_hash(hash: Hash, parents: Vec<Hash>) -> Block {
Block::from_header(Header::from_precomputed_hash(hash, parents))
}
pub fn asses_for_cache(&self) -> Option<()> {
(self.estimate_mem_bytes() < 1_000_000).then_some(())
}
}
impl MemSizeEstimator for Block {
fn estimate_mem_bytes(&self) -> usize {
size_of::<Self>()
+ self.header.estimate_mem_bytes()
+ size_of::<Vec<Transaction>>()
+ self.transactions.iter().map(Transaction::estimate_mem_bytes).sum::<usize>()
}
}
pub trait TemplateTransactionSelector {
fn select_transactions(&mut self) -> Vec<Transaction>;
fn reject_selection(&mut self, tx_id: TransactionId);
fn is_successful(&self) -> bool;
}
#[derive(Clone, Copy, Debug)]
pub enum TemplateBuildMode {
Standard,
Infallible,
}
#[derive(Debug, Clone)]
pub struct BlockTemplate {
pub block: MutableBlock,
pub miner_data: MinerData,
pub coinbase_has_red_reward: bool,
pub selected_parent_timestamp: u64,
pub selected_parent_daa_score: u64,
pub selected_parent_hash: Hash,
pub calculated_fees: Vec<u64>,
}
impl BlockTemplate {
pub fn new(
block: MutableBlock,
miner_data: MinerData,
coinbase_has_red_reward: bool,
selected_parent_timestamp: u64,
selected_parent_daa_score: u64,
selected_parent_hash: Hash,
calculated_fees: Vec<u64>,
) -> Self {
Self {
block,
miner_data,
coinbase_has_red_reward,
selected_parent_timestamp,
selected_parent_daa_score,
selected_parent_hash,
calculated_fees,
}
}
pub fn to_virtual_state_approx_id(&self) -> VirtualStateApproxId {
VirtualStateApproxId::new(self.block.header.daa_score, self.block.header.blue_work, self.selected_parent_hash)
}
}
#[derive(PartialEq)]
pub struct VirtualStateApproxId {
daa_score: u64,
blue_work: BlueWorkType,
sink: Hash,
}
impl VirtualStateApproxId {
pub fn new(daa_score: u64, blue_work: BlueWorkType, sink: Hash) -> Self {
Self { daa_score, blue_work, sink }
}
}