You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Alfis/src/blockchain/block.rs

102 lines
3.1 KiB
Rust

extern crate serde;
extern crate serde_json;
use std::fmt::Debug;
use serde::{Deserialize, Serialize};
use crate::blockchain::hash_utils::{hash_difficulty, key_hash_difficulty};
use crate::blockchain::transaction::TransactionType;
use crate::bytes::Bytes;
use crate::Transaction;
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub struct Block {
pub index: u64,
pub timestamp: i64,
pub version: u32,
pub difficulty: u32,
pub random: u32,
pub nonce: u64,
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
pub hash: Bytes,
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
pub prev_block_hash: Bytes,
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
pub pub_key: Bytes,
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
pub signature: Bytes,
#[serde(skip_serializing_if = "Option::is_none")]
pub transaction: Option<Transaction>
}
impl Block {
pub fn new(transaction: Option<Transaction>, pub_key: Bytes, prev_block_hash: Bytes, difficulty: u32) -> Self {
Block {
index: 0,
timestamp: 0,
version: 0,
difficulty,
random: 0,
nonce: 0,
transaction,
prev_block_hash,
hash: Bytes::default(),
pub_key,
signature: Bytes::default()
}
}
pub fn from_all_params(index: u64, timestamp: i64, version: u32, difficulty: u32, random: u32, nonce: u64, prev_block_hash: Bytes, hash: Bytes, pub_key: Bytes, signature: Bytes, transaction: Option<Transaction>) -> Self {
Block {
index,
timestamp,
version,
difficulty,
random,
nonce,
transaction,
prev_block_hash,
hash,
pub_key,
signature
}
}
pub fn from_bytes(data: &[u8]) -> serde_cbor::Result<Self> {
serde_cbor::from_slice(data)
}
pub fn is_genesis(&self) -> bool {
self.index == 1 &&
matches!(Transaction::get_type(&self.transaction), TransactionType::Origin) &&
self.prev_block_hash == Bytes::default()
}
/// Serializes block to CBOR for network
pub fn as_bytes(&self) -> Vec<u8> {
serde_cbor::to_vec(&self).unwrap()
}
/// Serializes block to bincode format for hashing.
pub fn as_bytes_compact(&self) -> Vec<u8> {
bincode::serialize(&self).unwrap()
}
/// Checks if this block is superior than the other
pub fn is_better_than(&self, other: &Block) -> bool {
if self.transaction.is_some() && other.transaction.is_none() {
return true;
}
let hash_diff = hash_difficulty(self.hash.as_slice()) + key_hash_difficulty(self.hash.as_slice());
let my_diff = (hash_diff << 16) + (self.hash.get_tail_u64() % 0xFFFF) as u32;
let hash_diff = hash_difficulty(other.hash.as_slice()) + key_hash_difficulty(other.hash.as_slice());
let it_diff = (hash_diff << 16) + (other.hash.get_tail_u64() % 0xFFFF) as u32;
if my_diff > it_diff {
return true;
}
false
}
}