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> {
46 let mut hash_less_block = self.clone();
47 hash_less_block.hash = None; for transaction in &mut hash_less_block.transactions {
51 transaction.inputs = vec![];
52 transaction.outputs = vec![];
53 }
54 bincode::encode_to_vec(hash_less_block, bincode::config::standard())
55 }
56
57 #[deprecated]
60 pub fn compute_pow(&mut self) -> Result<(), EncodeError> {
61 let tx_difficulty_big_int = BigUint::from_bytes_be(&calculate_block_difficulty(
62 &self.block_pow_difficulty,
63 self.transactions.len(),
64 ));
65 let mut rng: rand::prelude::ThreadRng = rand::rng();
66 loop {
67 self.nonce = rng.random();
68 let hashing_buf = self.get_hashing_buf()?;
69 if BigUint::from_bytes_be(&*Hash::new(&hashing_buf)) <= tx_difficulty_big_int {
70 self.hash = Some(Hash::new(&hashing_buf));
71 return Ok(());
72 }
73 }
74 }
75}