kaspa_consensus_core/
block.rs1use crate::{
2 coinbase::MinerData,
3 header::Header,
4 tx::{Transaction, TransactionId},
5 BlueWorkType,
6};
7use kaspa_hashes::Hash;
8use kaspa_utils::mem_size::MemSizeEstimator;
9use std::sync::Arc;
10
11#[derive(Debug, Clone)]
13pub struct MutableBlock {
14 pub header: Header,
15 pub transactions: Vec<Transaction>,
16}
17
18impl MutableBlock {
19 pub fn new(header: Header, txs: Vec<Transaction>) -> Self {
20 Self { header, transactions: txs }
21 }
22
23 pub fn from_header(header: Header) -> Self {
24 Self::new(header, vec![])
25 }
26
27 pub fn to_immutable(self) -> Block {
28 Block::new(self.header, self.transactions)
29 }
30}
31
32#[derive(Debug, Clone)]
36pub struct Block {
37 pub header: Arc<Header>,
38 pub transactions: Arc<Vec<Transaction>>,
39}
40
41impl Block {
42 pub fn new(header: Header, txs: Vec<Transaction>) -> Self {
43 Self { header: Arc::new(header), transactions: Arc::new(txs) }
44 }
45
46 pub fn from_arcs(header: Arc<Header>, transactions: Arc<Vec<Transaction>>) -> Self {
47 Self { header, transactions }
48 }
49
50 pub fn from_header_arc(header: Arc<Header>) -> Self {
51 Self { header, transactions: Arc::new(Vec::new()) }
52 }
53
54 pub fn from_header(header: Header) -> Self {
55 Self { header: Arc::new(header), transactions: Arc::new(Vec::new()) }
56 }
57
58 pub fn is_header_only(&self) -> bool {
59 self.transactions.is_empty()
60 }
61
62 pub fn hash(&self) -> Hash {
63 self.header.hash
64 }
65
66 pub fn from_precomputed_hash(hash: Hash, parents: Vec<Hash>) -> Block {
68 Block::from_header(Header::from_precomputed_hash(hash, parents))
69 }
70
71 pub fn asses_for_cache(&self) -> Option<()> {
72 (self.estimate_mem_bytes() < 1_000_000).then_some(())
73 }
74}
75
76impl MemSizeEstimator for Block {
77 fn estimate_mem_bytes(&self) -> usize {
78 size_of::<Self>()
80 + self.header.estimate_mem_bytes()
81 + size_of::<Vec<Transaction>>()
82 + self.transactions.iter().map(Transaction::estimate_mem_bytes).sum::<usize>()
83 }
84}
85
86pub trait TemplateTransactionSelector {
88 fn select_transactions(&mut self) -> Vec<Transaction>;
92
93 fn reject_selection(&mut self, tx_id: TransactionId);
97
98 fn is_successful(&self) -> bool;
100}
101
102#[derive(Clone, Copy, Debug)]
104pub enum TemplateBuildMode {
105 Standard,
109
110 Infallible,
112}
113
114#[derive(Debug, Clone)]
116pub struct BlockTemplate {
117 pub block: MutableBlock,
118 pub miner_data: MinerData,
119 pub coinbase_has_red_reward: bool,
120 pub selected_parent_timestamp: u64,
121 pub selected_parent_daa_score: u64,
122 pub selected_parent_hash: Hash,
123 pub calculated_fees: Vec<u64>,
125}
126
127impl BlockTemplate {
128 pub fn new(
129 block: MutableBlock,
130 miner_data: MinerData,
131 coinbase_has_red_reward: bool,
132 selected_parent_timestamp: u64,
133 selected_parent_daa_score: u64,
134 selected_parent_hash: Hash,
135 calculated_fees: Vec<u64>,
136 ) -> Self {
137 Self {
138 block,
139 miner_data,
140 coinbase_has_red_reward,
141 selected_parent_timestamp,
142 selected_parent_daa_score,
143 selected_parent_hash,
144 calculated_fees,
145 }
146 }
147
148 pub fn to_virtual_state_approx_id(&self) -> VirtualStateApproxId {
149 VirtualStateApproxId::new(self.block.header.daa_score, self.block.header.blue_work, self.selected_parent_hash)
150 }
151}
152
153#[derive(PartialEq)]
157pub struct VirtualStateApproxId {
158 daa_score: u64,
159 blue_work: BlueWorkType,
160 sink: Hash,
161}
162
163impl VirtualStateApproxId {
164 pub fn new(daa_score: u64, blue_work: BlueWorkType, sink: Hash) -> Self {
165 Self { daa_score, blue_work, sink }
166 }
167}