metadata.rs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. use darkfi::{
  2. util::serial::{deserialize, serialize, SerialDecodable, SerialEncodable},
  3. Result,
  4. };
  5. use super::{block::Block, participant::Participant, util::Timestamp, vote::Vote};
  6. const SLED_STREAMLET_METADATA_TREE: &[u8] = b"_streamlet_metadata";
  7. /// This struct represents additional Block information used by the consensus protocol.
  8. #[derive(Debug, Clone, PartialEq, SerialEncodable, SerialDecodable)]
  9. pub struct Metadata {
  10. /// Block creation timestamp
  11. pub timestamp: Timestamp,
  12. /// Block information used by Ouroboros consensus
  13. pub om: OuroborosMetadata,
  14. }
  15. impl Metadata {
  16. pub fn new(timestamp: Timestamp, proof: String, r: String, s: String) -> Metadata {
  17. Metadata { timestamp, om: OuroborosMetadata::new(proof, r, s) }
  18. }
  19. }
  20. /// This struct represents Block information used by Ouroboros consensus protocol.
  21. #[derive(Debug, Clone, PartialEq, SerialEncodable, SerialDecodable)]
  22. pub struct OuroborosMetadata {
  23. /// Proof the stakeholder is the block owner
  24. pub proof: String,
  25. /// Random seed for VRF
  26. pub r: String,
  27. /// Block owner signature
  28. pub s: String,
  29. }
  30. impl OuroborosMetadata {
  31. pub fn new(proof: String, r: String, s: String) -> OuroborosMetadata {
  32. OuroborosMetadata { proof, r, s }
  33. }
  34. }
  35. /// This struct represents Block information used by Streamlet consensus protocol.
  36. #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
  37. pub struct StreamletMetadata {
  38. /// Epoch votes
  39. pub votes: Vec<Vote>,
  40. /// Block notarization flag
  41. pub notarized: bool,
  42. /// Block finalization flag
  43. pub finalized: bool,
  44. /// Nodes participated in the voting process
  45. pub participants: Vec<Participant>,
  46. }
  47. impl StreamletMetadata {
  48. pub fn new(participants: Vec<Participant>) -> StreamletMetadata {
  49. StreamletMetadata { votes: Vec::new(), notarized: false, finalized: false, participants }
  50. }
  51. }
  52. #[derive(Debug)]
  53. pub struct StreamletMetadataStore(sled::Tree);
  54. impl StreamletMetadataStore {
  55. pub fn new(db: &sled::Db, genesis: i64) -> Result<Self> {
  56. let tree = db.open_tree(SLED_STREAMLET_METADATA_TREE)?;
  57. let store = Self(tree);
  58. if store.0.is_empty() {
  59. // Genesis block record is generated.
  60. let block = blake3::hash(&serialize(&Block::genesis_block(genesis)));
  61. let metadata = StreamletMetadata {
  62. votes: vec![],
  63. notarized: true,
  64. finalized: true,
  65. participants: vec![],
  66. };
  67. store.insert(block, &metadata)?;
  68. }
  69. Ok(store)
  70. }
  71. /// Insert streamlet metadata into the store.
  72. /// The block hash for the metadata is used as the key, where value is the serialized metadata.
  73. pub fn insert(&self, block: blake3::Hash, metadata: &StreamletMetadata) -> Result<()> {
  74. self.0.insert(block.as_bytes(), serialize(metadata))?;
  75. Ok(())
  76. }
  77. /// Fetch given streamlet metadata from the store.
  78. /// The resulting vector contains `Option` which is `Some` if the metadata
  79. /// was found in the store, and `None`, if it has not.
  80. pub fn get(&self, hashes: &[blake3::Hash]) -> Result<Vec<Option<StreamletMetadata>>> {
  81. let mut ret: Vec<Option<StreamletMetadata>> = Vec::with_capacity(hashes.len());
  82. for i in hashes {
  83. if let Some(found) = self.0.get(i.as_bytes())? {
  84. let metadata = deserialize(&found)?;
  85. ret.push(Some(metadata));
  86. } else {
  87. ret.push(None);
  88. }
  89. }
  90. Ok(ret)
  91. }
  92. /// Retrieve all streamlet metadata.
  93. /// Be carefull as this will try to load everything in memory.
  94. pub fn get_all(&self) -> Result<Vec<Option<(blake3::Hash, StreamletMetadata)>>> {
  95. let mut metadata = Vec::new();
  96. let mut iterator = self.0.into_iter().enumerate();
  97. while let Some((_, r)) = iterator.next() {
  98. let (k, v) = r.unwrap();
  99. let hash_bytes: [u8; 32] = k.as_ref().try_into().unwrap();
  100. let m = deserialize(&v)?;
  101. metadata.push(Some((hash_bytes.into(), m)));
  102. }
  103. Ok(metadata)
  104. }
  105. }