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
11#[derive(Encode, Decode, Serialize, Deserialize, Clone, Debug)]
14pub struct Block {
15 pub transactions: Vec<Transaction>,
16 pub timestamp: u64,
17 pub nonce: u64,
18 pub block_pow_difficulty: [u8; 32],
19 pub tx_pow_difficulty: [u8; 32],
20 pub previous_block: Hash,
21 pub hash: Option<Hash>,
22}
23
24impl Block {
25 pub fn new_block_now(
27 transactions: Vec<Transaction>,
28 block_pow_difficulty: &[u8; 32],
29 tx_pow_difficulty: &[u8; 32],
30 previous_block: Hash
31 ) -> Self {
32 Block {
33 transactions,
34 timestamp: chrono::Utc::now().timestamp() as u64,
35 nonce: 0,
36 block_pow_difficulty: *block_pow_difficulty,
37 tx_pow_difficulty: *tx_pow_difficulty,
38 previous_block,
39 hash: None,
40 }
41 }
42
43 pub fn get_hashing_buf(&self) -> Result<Vec<u8>, EncodeError> {
45 let mut hash_less_block = self.clone();
46 hash_less_block.hash = None;
47 bincode::encode_to_vec(hash_less_block, bincode::config::standard())
48 }
49
50 #[deprecated]
53 pub fn compute_pow(&mut self) -> Result<(), EncodeError> {
54 let tx_difficulty_big_int = BigUint::from_bytes_be(&calculate_block_difficulty(
55 &self.block_pow_difficulty,
56 self.transactions.len(),
57 ));
58 let mut rng: rand::prelude::ThreadRng = rand::rng();
59 loop {
60 self.nonce = rng.random();
61 let hashing_buf = self.get_hashing_buf()?;
62 if BigUint::from_bytes_be(&*Hash::new(&hashing_buf)) <= tx_difficulty_big_int {
63 self.hash = Some(Hash::new(&hashing_buf));
64 return Ok(());
65 }
66 }
67 }
68}