summaryrefslogtreecommitdiff
path: root/src/blocks.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/blocks.rs')
-rw-r--r--src/blocks.rs88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/blocks.rs b/src/blocks.rs
new file mode 100644
index 0000000..39abde2
--- /dev/null
+++ b/src/blocks.rs
@@ -0,0 +1,88 @@
+use std::{
+ hash::{DefaultHasher, Hash, Hasher},
+ ops::Deref,
+};
+
+use serde::{Deserialize, Serialize};
+
+use crate::{ZERO_PREFIX_AMOUNT, transaction::Transaction};
+
+#[derive(Deserialize, Serialize, Clone, Copy)]
+pub struct Block {
+ pub prev_hash: u64,
+ pub trans: Transaction,
+ pub pow: Option<u64>,
+}
+
+impl Block {
+ fn new(prev_hash: Option<u64>, trans: Transaction) -> Self {
+ Self {
+ prev_hash: prev_hash.unwrap_or(0), // special blocks
+ trans,
+ pow: None,
+ }
+ }
+
+ fn calc_pow(&self) -> u64 {
+ for i in 0.. {
+ // reset every loop
+ let mut hasher = DefaultHasher::new();
+ (&self.prev_hash, &self.trans, i).hash(&mut hasher);
+ let hashed = hasher.finish();
+ if hashed
+ .to_string()
+ .starts_with(
+ &"0".repeat(ZERO_PREFIX_AMOUNT)
+ .to_string(),
+ )
+ {
+ return hashed;
+ }
+ }
+ unreachable!()
+ }
+
+ pub fn calc_set_pow(&mut self) {
+ self.pow = Some(self.calc_pow());
+ }
+}
+
+impl Hash for Block {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.prev_hash
+ .hash(state);
+ self.trans
+ .hash(state);
+ if self
+ .pow
+ .is_none()
+ {
+ Self::calc_pow(self).hash(state);
+ } else {
+ self.pow
+ .hash(state);
+ }
+ }
+}
+
+#[derive(Default, Deserialize, Serialize, Clone)]
+pub struct BlockChain {
+ blocks: Vec<Block>,
+}
+
+impl BlockChain {
+ pub fn new(blocks: Vec<Block>) -> Self {
+ Self {
+ blocks,
+ }
+ }
+
+ pub fn store(&mut self, block: Block) {}
+}
+
+impl Deref for BlockChain {
+ type Target = Vec<Block>;
+ fn deref(&self) -> &Self::Target {
+ &self.blocks
+ }
+}