header_store.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 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 std::{fmt, str::FromStr};
  19. use darkfi_sdk::{
  20. blockchain::block_version,
  21. crypto::{MerkleNode, MerkleTree},
  22. hex::decode_hex_arr,
  23. AsHex,
  24. };
  25. #[cfg(feature = "async-serial")]
  26. use darkfi_serial::async_trait;
  27. use darkfi_serial::{deserialize, serialize, Encodable, SerialDecodable, SerialEncodable};
  28. use sled_overlay::sled;
  29. use crate::{util::time::Timestamp, Error, Result};
  30. use super::{parse_record, parse_u32_key_record, SledDbOverlayPtr};
  31. #[derive(Copy, Clone, Debug, Eq, PartialEq, SerialEncodable, SerialDecodable)]
  32. // We have to introduce a type rather than using an alias so we can restrict API access
  33. pub struct HeaderHash(pub [u8; 32]);
  34. impl HeaderHash {
  35. pub fn new(data: [u8; 32]) -> Self {
  36. Self(data)
  37. }
  38. #[inline]
  39. pub fn inner(&self) -> &[u8; 32] {
  40. &self.0
  41. }
  42. pub fn as_string(&self) -> String {
  43. self.0.hex().to_string()
  44. }
  45. }
  46. impl FromStr for HeaderHash {
  47. type Err = Error;
  48. fn from_str(header_hash_str: &str) -> Result<Self> {
  49. Ok(Self(decode_hex_arr(header_hash_str)?))
  50. }
  51. }
  52. impl fmt::Display for HeaderHash {
  53. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  54. write!(f, "{}", self.0.hex())
  55. }
  56. }
  57. /// This struct represents a tuple of the form (version, previous, height, timestamp, nonce, merkle_tree).
  58. #[derive(Debug, Clone, PartialEq, Eq, SerialEncodable, SerialDecodable)]
  59. pub struct Header {
  60. /// Block version
  61. pub version: u8,
  62. /// Previous block hash
  63. pub previous: HeaderHash,
  64. /// Block height
  65. pub height: u32,
  66. /// Block creation timestamp
  67. pub timestamp: Timestamp,
  68. /// The block's nonce. This value changes arbitrarily with mining.
  69. pub nonce: u64,
  70. /// Merkle tree root of the transactions hashes contained in this block
  71. pub root: MerkleNode,
  72. }
  73. impl Header {
  74. pub fn new(previous: HeaderHash, height: u32, timestamp: Timestamp, nonce: u64) -> Self {
  75. let version = block_version(height);
  76. let root = MerkleTree::new(1).root(0).unwrap();
  77. Self { version, previous, height, timestamp, nonce, root }
  78. }
  79. /// Compute the header's hash
  80. pub fn hash(&self) -> HeaderHash {
  81. let mut hasher = blake3::Hasher::new();
  82. // Blake3 hasher .update() method never fails.
  83. // This call returns a Result due to how the Write trait is specified.
  84. // Calling unwrap() here should be safe.
  85. self.encode(&mut hasher).expect("blake3 hasher");
  86. HeaderHash(hasher.finalize().into())
  87. }
  88. }
  89. impl Default for Header {
  90. /// Represents the genesis header on current timestamp
  91. fn default() -> Self {
  92. Header::new(
  93. HeaderHash::new(blake3::hash(b"Let there be dark!").into()),
  94. 0u32,
  95. Timestamp::current_time(),
  96. 0u64,
  97. )
  98. }
  99. }
  100. impl fmt::Display for Header {
  101. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  102. let s = format!(
  103. "{} {{\n\t{}: {}\n\t{}: {}\n\t{}: {}\n\t{}: {}\n\t{}: {}\n\t{}: {}\n\t{}: {}\n}}",
  104. "Header",
  105. "Hash",
  106. self.hash(),
  107. "Version",
  108. self.version,
  109. "Previous",
  110. self.previous,
  111. "Height",
  112. self.height,
  113. "Timestamp",
  114. self.timestamp,
  115. "Nonce",
  116. self.nonce,
  117. "Root",
  118. self.root,
  119. );
  120. write!(f, "{}", s)
  121. }
  122. }
  123. pub const SLED_HEADER_TREE: &[u8] = b"_headers";
  124. pub const SLED_SYNC_HEADER_TREE: &[u8] = b"_sync_headers";
  125. /// The `HeaderStore` is a structure representing all `sled` trees related
  126. /// to storing the blockchain's blocks's header information.
  127. #[derive(Clone)]
  128. pub struct HeaderStore {
  129. /// Main `sled` tree, storing all the blockchain's blocks' headers,
  130. /// where the key is the headers' hash, and value is the serialized header.
  131. pub main: sled::Tree,
  132. /// The `sled` tree storing all the node pending headers while syncing,
  133. /// where the key is the height number, and the value is the serialized
  134. /// header.
  135. pub sync: sled::Tree,
  136. }
  137. impl HeaderStore {
  138. /// Opens a new or existing `HeaderStore` on the given sled database.
  139. pub fn new(db: &sled::Db) -> Result<Self> {
  140. let main = db.open_tree(SLED_HEADER_TREE)?;
  141. let sync = db.open_tree(SLED_SYNC_HEADER_TREE)?;
  142. Ok(Self { main, sync })
  143. }
  144. /// Insert a slice of [`Header`] into the store's main tree.
  145. pub fn insert(&self, headers: &[Header]) -> Result<Vec<HeaderHash>> {
  146. let (batch, ret) = self.insert_batch(headers);
  147. self.main.apply_batch(batch)?;
  148. Ok(ret)
  149. }
  150. /// Insert a slice of [`Header`] into the store's sync tree.
  151. pub fn insert_sync(&self, headers: &[Header]) -> Result<()> {
  152. let batch = self.insert_batch_sync(headers);
  153. self.sync.apply_batch(batch)?;
  154. Ok(())
  155. }
  156. /// Generate the sled batch corresponding to an insert to the main
  157. /// tree, so caller can handle the write operation.
  158. /// The header's hash() function output is used as the key,
  159. /// while value is the serialized [`Header`] itself.
  160. /// On success, the function returns the header hashes in the same
  161. /// order, along with the corresponding operation batch.
  162. pub fn insert_batch(&self, headers: &[Header]) -> (sled::Batch, Vec<HeaderHash>) {
  163. let mut ret = Vec::with_capacity(headers.len());
  164. let mut batch = sled::Batch::default();
  165. for header in headers {
  166. let headerhash = header.hash();
  167. batch.insert(headerhash.inner(), serialize(header));
  168. ret.push(headerhash);
  169. }
  170. (batch, ret)
  171. }
  172. /// Generate the sled batch corresponding to an insert to the sync
  173. /// tree, so caller can handle the write operation.
  174. /// The header height is used as the key, while value is the serialized
  175. /// [`Header`] itself.
  176. pub fn insert_batch_sync(&self, headers: &[Header]) -> sled::Batch {
  177. let mut batch = sled::Batch::default();
  178. for header in headers {
  179. batch.insert(&header.height.to_be_bytes(), serialize(header));
  180. }
  181. batch
  182. }
  183. /// Check if the store's main tree contains a given header hash.
  184. pub fn contains(&self, headerhash: &HeaderHash) -> Result<bool> {
  185. Ok(self.main.contains_key(headerhash.inner())?)
  186. }
  187. /// Fetch given header hashes from the store's main tree.
  188. /// The resulting vector contains `Option`, which is `Some` if the header
  189. /// was found in the store's main tree, and otherwise it is `None`, if it
  190. /// has not. The second parameter is a boolean which tells the function to
  191. /// fail in case at least one header was not found.
  192. pub fn get(&self, headerhashes: &[HeaderHash], strict: bool) -> Result<Vec<Option<Header>>> {
  193. let mut ret = Vec::with_capacity(headerhashes.len());
  194. for hash in headerhashes {
  195. if let Some(found) = self.main.get(hash.inner())? {
  196. let header = deserialize(&found)?;
  197. ret.push(Some(header));
  198. continue
  199. }
  200. if strict {
  201. return Err(Error::HeaderNotFound(hash.inner().hex()))
  202. }
  203. ret.push(None);
  204. }
  205. Ok(ret)
  206. }
  207. /// Retrieve all headers from the store's main tree in the form of a tuple
  208. /// (`headerhash`, `header`).
  209. /// Be careful as this will try to load everything in memory.
  210. pub fn get_all(&self) -> Result<Vec<(HeaderHash, Header)>> {
  211. let mut headers = vec![];
  212. for header in self.main.iter() {
  213. headers.push(parse_record(header.unwrap())?);
  214. }
  215. Ok(headers)
  216. }
  217. /// Retrieve all headers from the store's sync tree in the form of a tuple
  218. /// (`height`, `header`).
  219. /// Be careful as this will try to load everything in memory.
  220. pub fn get_all_sync(&self) -> Result<Vec<(u32, Header)>> {
  221. let mut headers = vec![];
  222. for record in self.sync.iter() {
  223. headers.push(parse_u32_key_record(record.unwrap())?);
  224. }
  225. Ok(headers)
  226. }
  227. /// Fetch the fisrt header in the store's sync tree, based on the `Ord`
  228. /// implementation for `Vec<u8>`.
  229. pub fn get_first_sync(&self) -> Result<Option<Header>> {
  230. let Some(found) = self.sync.first()? else { return Ok(None) };
  231. let (_, header) = parse_u32_key_record(found)?;
  232. Ok(Some(header))
  233. }
  234. /// Fetch the last header in the store's sync tree, based on the `Ord`
  235. /// implementation for `Vec<u8>`.
  236. pub fn get_last_sync(&self) -> Result<Option<Header>> {
  237. let Some(found) = self.sync.last()? else { return Ok(None) };
  238. let (_, header) = parse_u32_key_record(found)?;
  239. Ok(Some(header))
  240. }
  241. /// Fetch n hashes after given height. In the iteration, if a header
  242. /// height is not found, the iteration stops and the function returns what
  243. /// it has found so far in the store's sync tree.
  244. pub fn get_after_sync(&self, height: u32, n: usize) -> Result<Vec<Header>> {
  245. let mut ret = vec![];
  246. let mut key = height;
  247. let mut counter = 0;
  248. while counter < n {
  249. if let Some(found) = self.sync.get_gt(key.to_be_bytes())? {
  250. let (height, hash) = parse_u32_key_record(found)?;
  251. key = height;
  252. ret.push(hash);
  253. counter += 1;
  254. continue
  255. }
  256. break
  257. }
  258. Ok(ret)
  259. }
  260. /// Retrieve store's sync tree records count.
  261. pub fn len_sync(&self) -> usize {
  262. self.sync.len()
  263. }
  264. /// Check if store's sync tree contains any records.
  265. pub fn is_empty_sync(&self) -> bool {
  266. self.sync.is_empty()
  267. }
  268. /// Remove a slice of [`u32`] from the store's sync tree.
  269. pub fn remove_sync(&self, heights: &[u32]) -> Result<()> {
  270. let batch = self.remove_batch_sync(heights);
  271. self.sync.apply_batch(batch)?;
  272. Ok(())
  273. }
  274. /// Remove all records from the store's sync tree.
  275. pub fn remove_all_sync(&self) -> Result<()> {
  276. let headers = self.get_all_sync()?;
  277. let heights = headers.iter().map(|h| h.0).collect::<Vec<u32>>();
  278. let batch = self.remove_batch_sync(&heights);
  279. self.sync.apply_batch(batch)?;
  280. Ok(())
  281. }
  282. /// Generate the sled batch corresponding to a remove from the store's sync
  283. /// tree, so caller can handle the write operation.
  284. pub fn remove_batch_sync(&self, heights: &[u32]) -> sled::Batch {
  285. let mut batch = sled::Batch::default();
  286. for height in heights {
  287. batch.remove(&height.to_be_bytes());
  288. }
  289. batch
  290. }
  291. }
  292. /// Overlay structure over a [`HeaderStore`] instance.
  293. pub struct HeaderStoreOverlay(SledDbOverlayPtr);
  294. impl HeaderStoreOverlay {
  295. pub fn new(overlay: &SledDbOverlayPtr) -> Result<Self> {
  296. overlay.lock().unwrap().open_tree(SLED_HEADER_TREE, true)?;
  297. Ok(Self(overlay.clone()))
  298. }
  299. /// Insert a slice of [`Header`] into the overlay.
  300. /// The header's hash() function output is used as the key,
  301. /// while value is the serialized [`Header`] itself.
  302. /// On success, the function returns the header hashes in the same order.
  303. pub fn insert(&self, headers: &[Header]) -> Result<Vec<HeaderHash>> {
  304. let mut ret = Vec::with_capacity(headers.len());
  305. let mut lock = self.0.lock().unwrap();
  306. for header in headers {
  307. let headerhash = header.hash();
  308. lock.insert(SLED_HEADER_TREE, headerhash.inner(), &serialize(header))?;
  309. ret.push(headerhash);
  310. }
  311. Ok(ret)
  312. }
  313. /// Fetch given headerhashes from the overlay.
  314. /// The resulting vector contains `Option`, which is `Some` if the header
  315. /// was found in the overlay, and otherwise it is `None`, if it has not.
  316. /// The second parameter is a boolean which tells the function to fail in
  317. /// case at least one header was not found.
  318. pub fn get(&self, headerhashes: &[HeaderHash], strict: bool) -> Result<Vec<Option<Header>>> {
  319. let mut ret = Vec::with_capacity(headerhashes.len());
  320. let lock = self.0.lock().unwrap();
  321. for hash in headerhashes {
  322. if let Some(found) = lock.get(SLED_HEADER_TREE, hash.inner())? {
  323. let header = deserialize(&found)?;
  324. ret.push(Some(header));
  325. continue
  326. }
  327. if strict {
  328. return Err(Error::HeaderNotFound(hash.inner().hex()))
  329. }
  330. ret.push(None);
  331. }
  332. Ok(ret)
  333. }
  334. }