First correct working serialization.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
use crate::{Block, Transaction, Hash};
|
||||
use chrono::{Utc, DateTime};
|
||||
|
||||
pub struct Blockchain {
|
||||
pub chain_id: u32,
|
||||
pub version: u32,
|
||||
pub blocks: Vec<Block>,
|
||||
}
|
||||
|
||||
impl Blockchain {
|
||||
pub fn new(chain_id: u32, version: u32) -> Self {
|
||||
let mut blockchain = Blockchain{chain_id, version, blocks: Vec::new()};
|
||||
let mut genesis = Self::genesis(chain_id, version);
|
||||
genesis.mine();
|
||||
blockchain.add_block(genesis);
|
||||
blockchain
|
||||
}
|
||||
|
||||
pub fn new_block(&self, transaction: Transaction) -> Block {
|
||||
let prev_block = self.blocks.last().unwrap();
|
||||
let block = Block::new(prev_block.index + 1,Utc::now().timestamp(), self.chain_id, self.version, prev_block.hash.clone(), Some(transaction));
|
||||
block
|
||||
}
|
||||
|
||||
pub fn genesis(chain_id: u32, version: u32) -> Block {
|
||||
Block::new(0, Utc::now().timestamp(), chain_id, version, Hash::default(), None)
|
||||
}
|
||||
|
||||
pub fn add_block(&mut self, block: Block) {
|
||||
if self.check_block(&block, None) {
|
||||
println!("Adding block:\n{:?}", &block);
|
||||
self.blocks.push(block);
|
||||
} else {
|
||||
println!("Bad block found, ignoring:\n{:?}", &block);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check(&self) -> bool {
|
||||
let mut prev_block = None;
|
||||
for block in self.blocks.iter() {
|
||||
if !self.check_block(block, prev_block) {
|
||||
println!("Block {:?} is bad", block);
|
||||
return false;
|
||||
}
|
||||
prev_block = Some(block);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn check_block(&self, block: &Block, prev_block: Option<&Block>) -> bool {
|
||||
if !Self::check_block_hash(block) {
|
||||
return false;
|
||||
}
|
||||
if prev_block.is_none() {
|
||||
return true;
|
||||
}
|
||||
|
||||
return block.prev_block_hash == prev_block.unwrap().hash;
|
||||
}
|
||||
|
||||
pub fn check_block_hash(block: &Block) -> bool {
|
||||
// We need to clear Hash value to rehash it without it for check :(
|
||||
let mut copy: Block = block.clone();
|
||||
copy.hash = Hash::default();
|
||||
let data = serde_json::to_string(©).unwrap();
|
||||
Block::hash(data.as_bytes()) == block.hash
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user