header_store.rs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2023 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use darkfi_sdk::crypto::{MerkleNode, MerkleTree};
  19. #[cfg(feature = "async-serial")]
  20. use darkfi_serial::async_trait;
  21. use darkfi_serial::{deserialize, serialize, Encodable, SerialDecodable, SerialEncodable};
  22. use crate::{util::time::Timestamp, Error, Result};
  23. use super::{block_store::BLOCK_VERSION, parse_record, SledDbOverlayPtr};
  24. /// This struct represents a tuple of the form (version, previous, epoch, slot, timestamp, merkle_root).
  25. #[derive(Debug, Clone, PartialEq, Eq, SerialEncodable, SerialDecodable)]
  26. pub struct Header {
  27. /// Block version
  28. pub version: u8,
  29. /// Previous block hash
  30. pub previous: blake3::Hash,
  31. /// Epoch
  32. pub epoch: u64,
  33. /// Slot UID
  34. pub slot: u64,
  35. /// Block creation timestamp
  36. pub timestamp: Timestamp,
  37. /// Root of the transaction hashes merkle tree
  38. pub root: MerkleNode,
  39. }
  40. impl Header {
  41. pub fn new(
  42. previous: blake3::Hash,
  43. epoch: u64,
  44. slot: u64,
  45. timestamp: Timestamp,
  46. root: MerkleNode,
  47. ) -> Self {
  48. let version = BLOCK_VERSION;
  49. Self { version, previous, epoch, slot, timestamp, root }
  50. }
  51. /// Calculate the header hash
  52. pub fn headerhash(&self) -> Result<blake3::Hash> {
  53. let mut hasher = blake3::Hasher::new();
  54. self.encode(&mut hasher)?;
  55. Ok(hasher.finalize())
  56. }
  57. }
  58. impl Default for Header {
  59. /// Represents the genesis header on current timestamp
  60. fn default() -> Self {
  61. Header::new(
  62. blake3::hash(b"Let there be dark!"),
  63. 0,
  64. 0,
  65. Timestamp::current_time(),
  66. MerkleTree::new(100).root(0).unwrap(),
  67. )
  68. }
  69. }
  70. /// [`Header`] sled tree
  71. const SLED_HEADER_TREE: &[u8] = b"_headers";
  72. /// The `HeaderStore` is a `sled` tree storing all the blockchain's blocks' headers
  73. /// where the key is the headers' hash, and value is the serialized header.
  74. #[derive(Clone)]
  75. pub struct HeaderStore(pub sled::Tree);
  76. impl HeaderStore {
  77. /// Opens a new or existing `HeaderStore` on the given sled database.
  78. pub fn new(db: &sled::Db) -> Result<Self> {
  79. let tree = db.open_tree(SLED_HEADER_TREE)?;
  80. Ok(Self(tree))
  81. }
  82. /// Insert a slice of [`Header`] into the blockstore.
  83. pub fn insert(&self, headers: &[Header]) -> Result<Vec<blake3::Hash>> {
  84. let (batch, ret) = self.insert_batch(headers)?;
  85. self.0.apply_batch(batch)?;
  86. Ok(ret)
  87. }
  88. /// Generate the sled batch corresponding to an insert, so caller
  89. /// can handle the write operation.
  90. /// The headers are hashed with BLAKE3 and this header hash is used as
  91. /// the key, while value is the serialized [`Header`] itself.
  92. /// On success, the function returns the header hashes in the same
  93. /// order, along with the corresponding operation batch.
  94. pub fn insert_batch(&self, headers: &[Header]) -> Result<(sled::Batch, Vec<blake3::Hash>)> {
  95. let mut ret = Vec::with_capacity(headers.len());
  96. let mut batch = sled::Batch::default();
  97. for header in headers {
  98. let serialized = serialize(header);
  99. let headerhash = blake3::hash(&serialized);
  100. batch.insert(headerhash.as_bytes(), serialized);
  101. ret.push(headerhash);
  102. }
  103. Ok((batch, ret))
  104. }
  105. /// Check if the headerstore contains a given headerhash.
  106. pub fn contains(&self, headerhash: &blake3::Hash) -> Result<bool> {
  107. Ok(self.0.contains_key(headerhash.as_bytes())?)
  108. }
  109. /// Fetch given headerhashes from the headerstore.
  110. /// The resulting vector contains `Option`, which is `Some` if the header
  111. /// was found in the headerstore, and otherwise it is `None`, if it has not.
  112. /// The second parameter is a boolean which tells the function to fail in
  113. /// case at least one header was not found.
  114. pub fn get(&self, headerhashes: &[blake3::Hash], strict: bool) -> Result<Vec<Option<Header>>> {
  115. let mut ret = Vec::with_capacity(headerhashes.len());
  116. for hash in headerhashes {
  117. if let Some(found) = self.0.get(hash.as_bytes())? {
  118. let header = deserialize(&found)?;
  119. ret.push(Some(header));
  120. } else {
  121. if strict {
  122. let s = hash.to_hex().as_str().to_string();
  123. return Err(Error::HeaderNotFound(s))
  124. }
  125. ret.push(None);
  126. }
  127. }
  128. Ok(ret)
  129. }
  130. /// Retrieve all headers from the headerstore in the form of a tuple
  131. /// (`headerhash`, `header`).
  132. /// Be careful as this will try to load everything in memory.
  133. pub fn get_all(&self) -> Result<Vec<(blake3::Hash, Header)>> {
  134. let mut headers = vec![];
  135. for header in self.0.iter() {
  136. headers.push(parse_record(header.unwrap())?);
  137. }
  138. Ok(headers)
  139. }
  140. }
  141. /// Overlay structure over a [`HeaderStore`] instance.
  142. pub struct HeaderStoreOverlay(SledDbOverlayPtr);
  143. impl HeaderStoreOverlay {
  144. pub fn new(overlay: &SledDbOverlayPtr) -> Result<Self> {
  145. overlay.lock().unwrap().open_tree(SLED_HEADER_TREE)?;
  146. Ok(Self(overlay.clone()))
  147. }
  148. /// Insert a slice of [`Header`] into the overlay.
  149. /// The headers are hashed with BLAKE3 and this headerhash is used as
  150. /// the key, while value is the serialized [`Header`] itself.
  151. /// On success, the function returns the header hashes in the same order.
  152. pub fn insert(&self, headers: &[Header]) -> Result<Vec<blake3::Hash>> {
  153. let mut ret = Vec::with_capacity(headers.len());
  154. let mut lock = self.0.lock().unwrap();
  155. for header in headers {
  156. let serialized = serialize(header);
  157. let headerhash = blake3::hash(&serialized);
  158. lock.insert(SLED_HEADER_TREE, headerhash.as_bytes(), &serialized)?;
  159. ret.push(headerhash);
  160. }
  161. Ok(ret)
  162. }
  163. /// Fetch given headerhashes from the overlay.
  164. /// The resulting vector contains `Option`, which is `Some` if the header
  165. /// was found in the overlay, and otherwise it is `None`, if it has not.
  166. /// The second parameter is a boolean which tells the function to fail in
  167. /// case at least one header was not found.
  168. pub fn get(&self, headerhashes: &[blake3::Hash], strict: bool) -> Result<Vec<Option<Header>>> {
  169. let mut ret = Vec::with_capacity(headerhashes.len());
  170. let lock = self.0.lock().unwrap();
  171. for hash in headerhashes {
  172. if let Some(found) = lock.get(SLED_HEADER_TREE, hash.as_bytes())? {
  173. let header = deserialize(&found)?;
  174. ret.push(Some(header));
  175. } else {
  176. if strict {
  177. let s = hash.to_hex().as_str().to_string();
  178. return Err(Error::HeaderNotFound(s))
  179. }
  180. ret.push(None);
  181. }
  182. }
  183. Ok(ret)
  184. }
  185. }