Files
Alfis/src/blockchain/block.rs
T

103 lines
3.2 KiB
Rust
Raw Normal View History

2019-12-01 22:45:25 +01:00
extern crate serde;
extern crate serde_json;
use std::fmt::Debug;
2021-06-09 20:36:36 +02:00
use serde::{Deserialize, Serialize};
2021-04-22 16:31:42 +02:00
use crate::blockchain::hash_utils::{hash_difficulty, key_hash_difficulty};
use crate::blockchain::transaction::TransactionType;
2021-06-09 20:36:36 +02:00
use crate::bytes::Bytes;
use crate::Transaction;
2019-12-01 22:45:25 +01:00
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub struct Block {
pub index: u64,
pub timestamp: i64,
pub version: u32,
pub difficulty: u32,
2019-12-01 22:45:25 +01:00
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")]
2021-06-09 20:36:36 +02:00
pub transaction: Option<Transaction>
2019-12-01 22:45:25 +01:00
}
impl Block {
pub fn new(transaction: Option<Transaction>, pub_key: Bytes, prev_block_hash: Bytes, difficulty: u32) -> Self {
2019-12-01 22:45:25 +01:00
Block {
index: 0,
timestamp: 0,
version: 0,
difficulty,
2019-12-01 22:45:25 +01:00
random: 0,
nonce: 0,
transaction,
prev_block_hash,
hash: Bytes::default(),
pub_key,
signature: Bytes::default()
2019-12-01 22:45:25 +01:00
}
}
2021-12-25 18:40:36 +01:00
#[allow(clippy::too_many_arguments)]
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
}
}
2021-05-30 00:33:13 +02:00
pub fn from_bytes(data: &[u8]) -> serde_cbor::Result<Self> {
serde_cbor::from_slice(data)
}
2019-12-01 22:45:25 +01:00
pub fn is_genesis(&self) -> bool {
self.index == 1 &&
matches!(Transaction::get_type(&self.transaction), TransactionType::Origin) &&
self.prev_block_hash == Bytes::default()
2019-12-01 22:45:25 +01:00
}
2021-05-30 00:33:13 +02:00
/// Serializes block to CBOR for network
pub fn as_bytes(&self) -> Vec<u8> {
2021-05-30 00:33:13 +02:00
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()
}
2021-04-22 16:31:42 +02:00
/// Checks if this block is superior than the other
pub fn is_better_than(&self, other: &Block) -> bool {
2021-04-22 16:31:42 +02:00
if self.transaction.is_some() && other.transaction.is_none() {
return true;
}
2021-04-29 19:27:45 +02:00
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;
2021-04-22 16:31:42 +02:00
if my_diff > it_diff {
return true;
}
2021-04-22 16:31:42 +02:00
false
}
2019-12-01 22:45:25 +01:00
}