1use bincode::{Decode, Encode, error::EncodeError};
2use num_bigint::BigUint;
3use rand::Rng;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7 core::{difficulty::calculate_block_difficulty, transaction::Transaction},
8 crypto::Hash,
9};
10
11pub const MAX_TRANSACTIONS: usize = 500;
12
13#[derive(Encode, Decode, Serialize, Deserialize, Clone, Debug)]
16pub struct Block {
17 pub transactions: Vec<Transaction>,
18 pub timestamp: u64,
19 pub nonce: u64,
20 pub block_pow_difficulty: [u8; 32],
21 pub tx_pow_difficulty: [u8; 32],
22 pub previous_block: Hash,
23 pub hash: Option<Hash>,
24}
25
26impl Block {
27 pub fn new_block_now(
29 transactions: Vec<Transaction>,
30 block_pow_difficulty: &[u8; 32],
31 tx_pow_difficulty: &[u8; 32],
32 previous_block: Hash
33 ) -> Self {
34 Block {
35 transactions,
36 timestamp: chrono::Utc::now().timestamp() as u64,
37 nonce: 0,
38 block_pow_difficulty: *block_pow_difficulty,
39 tx_pow_difficulty: *tx_pow_difficulty,
40 previous_block,
41 hash: None,
42 }
43 }
44
45 pub fn get_hashing_buf(&self) -> Result<Vec<u8>, EncodeError> {
48 let mut hash_less_block = self.clone();
49 hash_less_block.hash = None; for transaction in &mut hash_less_block.transactions {
53 transaction.inputs = vec![];
54 transaction.outputs = vec![];
55 }
56 bincode::encode_to_vec(hash_less_block, bincode::config::standard())
57 }
58
59 #[deprecated]
62 pub fn compute_pow(&mut self) -> Result<(), EncodeError> {
63 let tx_difficulty_big_int = BigUint::from_bytes_be(&calculate_block_difficulty(
64 &self.block_pow_difficulty,
65 self.transactions.len(),
66 ));
67 let mut rng: rand::prelude::ThreadRng = rand::rng();
68 loop {
69 self.nonce = rng.random();
70 let hashing_buf = self.get_hashing_buf()?;
71 if BigUint::from_bytes_be(&*Hash::new(&hashing_buf)) <= tx_difficulty_big_int {
72 self.hash = Some(Hash::new(&hashing_buf));
73 return Ok(());
74 }
75 }
76 }
77}