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, 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
38#[derive(Encode, Decode, Serialize, Deserialize, Clone, Debug)]
41pub struct Block {
42 pub transactions: Vec<Transaction>,
43 pub timestamp: u64,
44 pub nonce: u64,
45 pub meta: BlockMetadata,
46}
47
48impl Block {
49 pub fn new_block_now(
51 transactions: Vec<Transaction>,
52 block_pow_difficulty: &[u8; 32],
53 tx_pow_difficulty: &[u8; 32],
54 previous_block: Hash,
55 merkle_tree_root: &[u8; 32],
56 address_inclusion_filter: AddressInclusionFilter,
57 ) -> Self {
58 Block {
59 transactions,
60 timestamp: chrono::Utc::now().timestamp() as u64,
61 nonce: 0,
62 meta: BlockMetadata {
63 block_pow_difficulty: *block_pow_difficulty,
64 tx_pow_difficulty: *tx_pow_difficulty,
65 previous_block,
66 hash: None,
67 merkle_tree_root: *merkle_tree_root,
68 address_inclusion_filter,
69 },
70 }
71 }
72
73 pub fn get_hashing_buf(&self) -> Result<Vec<u8>, EncodeError> {
76 let mut hash_less_block = self.clone();
77 hash_less_block.meta.hash = None; for transaction in &mut hash_less_block.transactions {
81 transaction.inputs = vec![];
82 transaction.outputs = vec![];
83 }
84 bincode::encode_to_vec(hash_less_block, bincode::config::standard())
85 }
86
87 #[deprecated]
90 pub fn compute_pow(&mut self) -> Result<(), EncodeError> {
91 let tx_difficulty_big_int = BigUint::from_bytes_be(&calculate_block_difficulty(
92 &self.meta.block_pow_difficulty,
93 self.transactions.len(),
94 ));
95 let mut rng: rand::prelude::ThreadRng = rand::rng();
96 loop {
97 self.nonce = rng.random();
98 let hashing_buf = self.get_hashing_buf()?;
99 if BigUint::from_bytes_be(&*Hash::new(&hashing_buf)) <= tx_difficulty_big_int {
100 self.meta.hash = Some(Hash::new(&hashing_buf));
101 return Ok(());
102 }
103 }
104 }
105
106 pub fn check_meta(&self) -> Result<(), BlockError> {
108 self.check_completeness()?;
109 self.validate_block_hash()?;
110 self.validate_block_hash()?;
111 self.validate_merkle_tree()?;
112 Ok(())
113 }
114
115 pub fn check_completeness(&self) -> Result<(), BlockError> {
117 self.meta
118 .hash
119 .ok_or(BlockError::IncompleteBlock)
120 .map(|_| ())?;
121 Ok(())
122 }
123
124 pub fn validate_block_hash(&self) -> Result<(), BlockError> {
126 self.check_completeness()?;
127 if !self
128 .meta
129 .hash
130 .ok_or(BlockError::IncompleteBlock)?
131 .compare_with_data(
132 &self
133 .get_hashing_buf()
134 .map_err(|_| BlockError::EncodeError)?,
135 )
136 {
137 return Err(BlockError::InvalidBlockHash);
138 }
139 Ok(())
140 }
141
142 pub fn validate_difficulties(
144 &self,
145 real_block_pow_difficulty: &[u8; 32],
146 real_tx_pow_difficulty: &[u8; 32],
147 ) -> Result<(), BlockError> {
148 if self.meta.block_pow_difficulty != *real_block_pow_difficulty
149 || self.meta.tx_pow_difficulty != *real_tx_pow_difficulty
150 {
151 return Err(BlockError::DifficultyMismatch);
152 }
153 if BigUint::from_bytes_be(&*self.meta.hash.unwrap())
154 > BigUint::from_bytes_be(&calculate_block_difficulty(
155 real_block_pow_difficulty,
156 self.transactions.len(),
157 ))
158 {
159 return Err(BlockError::BlockPowDifficultyIncorrect);
160 }
161 Ok(())
162 }
163
164 pub fn validate_merkle_tree(&self) -> Result<(), BlockError> {
166 let mut ids = vec![];
167 for tx in &self.transactions {
168 tx.check_completeness()
169 .map_err(|_| BlockError::IncompleteTransaction)?;
170 ids.push(tx.transaction_id.unwrap());
171 }
172 let tree = MerkleTree::build(&ids);
173 if tree.root_hash() != self.meta.merkle_tree_root {
174 return Err(BlockError::InvalidMerkleTreeRoot);
175 }
176 Ok(())
177 }
178
179 pub fn address_count(&self) -> usize {
180 self.transactions
181 .iter()
182 .fold(0, |acc, tx| acc + tx.address_count())
183 }
184}
185
186#[derive(Encode, Decode, Serialize, Deserialize, Clone, Debug)]
188pub struct BlockMetadata {
189 pub block_pow_difficulty: [u8; 32],
190 pub tx_pow_difficulty: [u8; 32],
191 pub previous_block: Hash,
192 pub hash: Option<Hash>,
193 pub merkle_tree_root: [u8; 32],
194 pub address_inclusion_filter: AddressInclusionFilter,
195}