blockchain.rs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. use std::{
  2. collections::hash_map::DefaultHasher,
  3. hash::{Hash, Hasher},
  4. };
  5. use serde::{Deserialize, Serialize};
  6. use super::block::Block;
  7. /// This struct represents a sequence of blocks starting with the genesis block.
  8. #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
  9. pub struct Blockchain {
  10. pub blocks: Vec<Block>,
  11. }
  12. impl Blockchain {
  13. pub fn new(intial_block: Block) -> Blockchain {
  14. Blockchain { blocks: vec![intial_block] }
  15. }
  16. /// A block is considered valid when its parent hash is equal to the hash of the
  17. /// previous block and their epochs are incremental, exluding genesis.
  18. /// Additional validity rules can be applied.
  19. pub fn check_block_validity(&self, block: &Block, previous_block: &Block) {
  20. assert!(block.st != "⊥", "Genesis block provided.");
  21. let mut hasher = DefaultHasher::new();
  22. previous_block.hash(&mut hasher);
  23. assert!(
  24. block.st == hasher.finish().to_string() && block.sl > previous_block.sl,
  25. "Provided block is invalid."
  26. );
  27. }
  28. /// A blockchain is considered valid, when every block is valid, based on check_block_validity method.
  29. pub fn check_chain_validity(&self) {
  30. for (index, block) in self.blocks[1..].iter().enumerate() {
  31. self.check_block_validity(&block, &self.blocks[index])
  32. }
  33. }
  34. /// Insertion of a valid block.
  35. pub fn add_block(&mut self, block: &Block) {
  36. self.check_block_validity(&block, &self.blocks.last().unwrap());
  37. self.blocks.push(block.clone());
  38. }
  39. /// Blockchain notarization check.
  40. pub fn is_notarized(&self) -> bool {
  41. for block in &self.blocks {
  42. if !block.metadata.sm.notarized {
  43. return false
  44. }
  45. }
  46. true
  47. }
  48. }