header_store.rs 15 KB

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