1use bincode::{Decode, Encode, error::EncodeError};
2use num_bigint::BigUint;
3use rand::Rng;
4use serde::{Deserialize, Serialize};
5use thiserror::Error;
6
7use crate::{
8 core::{difficulty::calculate_block_difficulty, transaction::Transaction},
9 crypto::{Hash, address_inclusion_filter::{AddressInclusionFilter, AddressInclusionFilterError}, merkle_tree::MerkleTree},
10};
11
12pub const MAX_TRANSACTIONS_PER_BLOCK: usize = 500;
13
14#[derive(Error, Debug, Serialize, Deserialize, Clone, Encode, Decode)]
15pub enum BlockError {
16 #[error("Block is missing required metadata")]
17 IncompleteBlock,
18
19 #[error("Encoding error")]
20 EncodeError,
21
22 #[error("Block hash is invalid")]
23 InvalidBlockHash,
24
25 #[error("Block difficulties don't match real difficulties")]
26 DifficultyMismatch,
27
28 #[error("Block pow difficulty is not up to target")]
29 BlockPowDifficultyIncorrect,
30
31 #[error("Transaction is incomplete")]
32 IncompleteTransaction,
33
34 #[error("Merkle root tree is invalid")]
35 InvalidMerkleTreeRoot,
36
37 #[error("Address inclusion filter error: {0}")]
38 AddressInclusionFilter(#[from] AddressInclusionFilterError),
39
40 #[error("Address inclusion filter is incorrect")]
41 IncorrectAddressInclusionFilter,
42}
43
44#[derive(Encode, Decode, Serialize, Deserialize, Clone, Debug)]
47pub struct Block {
48 pub transactions: Vec<Transaction>,
49 pub timestamp: u64,
50 pub nonce: u64,
51 pub meta: BlockMetadata,
52}
53
54impl Block {
55 pub fn new_block_now(
57 transactions: Vec<Transaction>,
58 block_pow_difficulty: &[u8; 32],
59 tx_pow_difficulty: &[u8; 32],
60 previous_block: Hash,
61 merkle_tree_root: &[u8; 32],
62 address_inclusion_filter: AddressInclusionFilter,
63 ) -> Self {
64 Block {
65 transactions,
66 timestamp: chrono::Utc::now().timestamp() as u64,
67 nonce: 0,
68 meta: BlockMetadata {
69 block_pow_difficulty: *block_pow_difficulty,
70 tx_pow_difficulty: *tx_pow_difficulty,
71 previous_block,
72 hash: None,
73 merkle_tree_root: *merkle_tree_root,
74 address_inclusion_filter,
75 },
76 }
77 }
78
79 pub fn get_hashing_buf(&self) -> Result<Vec<u8>, EncodeError> {
82 let mut hash_less_block = self.clone();
83 hash_less_block.meta.hash = None; for transaction in &mut hash_less_block.transactions {
87 transaction.inputs = vec![];
88 transaction.outputs = vec![];
89 }
90 bincode::encode_to_vec(hash_less_block, bincode::config::standard())
91 }
92
93 #[deprecated]
96 pub fn compute_pow(&mut self) -> Result<(), EncodeError> {
97 let tx_difficulty_big_int = BigUint::from_bytes_be(&calculate_block_difficulty(
98 &self.meta.block_pow_difficulty,
99 self.transactions.len(),
100 ));
101 let mut rng: rand::prelude::ThreadRng = rand::rng();
102 loop {
103 self.nonce = rng.random();
104 let hashing_buf = self.get_hashing_buf()?;
105 if BigUint::from_bytes_be(&*Hash::new(&hashing_buf)) <= tx_difficulty_big_int {
106 self.meta.hash = Some(Hash::new(&hashing_buf));
107 return Ok(());
108 }
109 }
110 }
111
112 pub fn check_meta(&self) -> Result<(), BlockError> {
114 self.check_completeness()?;
115 self.validate_block_hash()?;
116 self.validate_address_inclusion_filter()?;
117 self.validate_merkle_tree()?;
118 Ok(())
119 }
120
121 pub fn check_completeness(&self) -> Result<(), BlockError> {
123 self.meta
124 .hash
125 .ok_or(BlockError::IncompleteBlock)
126 .map(|_| ())?;
127 Ok(())
128 }
129
130 pub fn validate_block_hash(&self) -> Result<(), BlockError> {
132 self.check_completeness()?;
133 if !self
134 .meta
135 .hash
136 .ok_or(BlockError::IncompleteBlock)?
137 .compare_with_data(
138 &self
139 .get_hashing_buf()
140 .map_err(|_| BlockError::EncodeError)?,
141 )
142 {
143 return Err(BlockError::InvalidBlockHash);
144 }
145 Ok(())
146 }
147
148 pub fn validate_difficulties(
150 &self,
151 real_block_pow_difficulty: &[u8; 32],
152 real_tx_pow_difficulty: &[u8; 32],
153 ) -> Result<(), BlockError> {
154 if self.meta.block_pow_difficulty != *real_block_pow_difficulty
155 || self.meta.tx_pow_difficulty != *real_tx_pow_difficulty
156 {
157 return Err(BlockError::DifficultyMismatch);
158 }
159 if BigUint::from_bytes_be(&*self.meta.hash.unwrap())
160 > BigUint::from_bytes_be(&calculate_block_difficulty(
161 real_block_pow_difficulty,
162 self.transactions.len(),
163 ))
164 {
165 return Err(BlockError::BlockPowDifficultyIncorrect);
166 }
167 Ok(())
168 }
169
170 pub fn validate_merkle_tree(&self) -> Result<(), BlockError> {
172 let mut ids = vec![];
173 for tx in &self.transactions {
174 tx.check_completeness()
175 .map_err(|_| BlockError::IncompleteTransaction)?;
176 ids.push(tx.transaction_id.unwrap());
177 }
178 let tree = MerkleTree::build(&ids);
179 if tree.root_hash() != self.meta.merkle_tree_root {
180 return Err(BlockError::InvalidMerkleTreeRoot);
181 }
182 Ok(())
183 }
184
185 pub fn validate_address_inclusion_filter(&self) -> Result<(), BlockError> {
187 if AddressInclusionFilter::create_filter(&self.transactions)?
188 != self.meta.address_inclusion_filter
189 {
190 return Err(BlockError::IncorrectAddressInclusionFilter);
191 }
192 Ok(())
193 }
194
195 pub fn address_count(&self) -> usize {
196 self.transactions
197 .iter()
198 .fold(0, |acc, tx| acc + tx.address_count())
199 }
200}
201
202#[derive(Encode, Decode, Serialize, Deserialize, Clone, Debug)]
204pub struct BlockMetadata {
205 pub block_pow_difficulty: [u8; 32],
206 pub tx_pow_difficulty: [u8; 32],
207 pub previous_block: Hash,
208 pub hash: Option<Hash>,
209 pub merkle_tree_root: [u8; 32],
210 pub address_inclusion_filter: AddressInclusionFilter,
211}