block_store.rs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  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 darkfi_sdk::{
  19. crypto::{
  20. schnorr::{SchnorrSecret, Signature},
  21. MerkleTree, SecretKey,
  22. },
  23. pasta::{group::ff::FromUniformBytes, pallas},
  24. tx::TransactionHash,
  25. };
  26. #[cfg(feature = "async-serial")]
  27. use darkfi_serial::async_trait;
  28. use darkfi_serial::{deserialize, serialize, SerialDecodable, SerialEncodable};
  29. use num_bigint::BigUint;
  30. use sled_overlay::sled;
  31. use crate::{tx::Transaction, util::time::Timestamp, Error, Result};
  32. use super::{parse_record, parse_u32_key_record, Header, HeaderHash, SledDbOverlayPtr};
  33. /// This struct represents a tuple of the form (`header`, `txs`, `signature`).
  34. ///
  35. /// The header and transactions are stored as hashes, serving as pointers to the actual data
  36. /// in the sled database.
  37. /// NOTE: This struct fields are considered final, as it represents a blockchain block.
  38. #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
  39. pub struct Block {
  40. /// Block header
  41. pub header: HeaderHash,
  42. /// Trasaction hashes
  43. pub txs: Vec<TransactionHash>,
  44. /// Block producer signature
  45. pub signature: Signature,
  46. }
  47. impl Block {
  48. pub fn new(header: HeaderHash, txs: Vec<TransactionHash>, signature: Signature) -> Self {
  49. Self { header, txs, signature }
  50. }
  51. /// A block's hash is the same as the hash of its header
  52. pub fn hash(&self) -> HeaderHash {
  53. self.header
  54. }
  55. /// Generate a `Block` from a `BlockInfo`
  56. pub fn from_block_info(block_info: &BlockInfo) -> Self {
  57. let header = block_info.header.hash();
  58. let txs = block_info.txs.iter().map(|tx| tx.hash()).collect();
  59. let signature = block_info.signature;
  60. Self { header, txs, signature }
  61. }
  62. }
  63. /// Structure representing full block data.
  64. ///
  65. /// It acts as a wrapper struct over `Block`, enabling us
  66. /// to include more information that might be used in different
  67. /// block versions, without affecting the original struct.
  68. #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
  69. pub struct BlockInfo {
  70. /// Block header data
  71. pub header: Header,
  72. /// Transactions payload
  73. pub txs: Vec<Transaction>,
  74. /// Block producer signature
  75. pub signature: Signature,
  76. }
  77. impl Default for BlockInfo {
  78. /// Represents the genesis block on current timestamp
  79. fn default() -> Self {
  80. Self {
  81. header: Header::default(),
  82. txs: vec![Transaction::default()],
  83. signature: Signature::dummy(),
  84. }
  85. }
  86. }
  87. impl BlockInfo {
  88. pub fn new(header: Header, txs: Vec<Transaction>, signature: Signature) -> Self {
  89. Self { header, txs, signature }
  90. }
  91. /// Generate an empty block for provided Header.
  92. /// Transactions and the producer signature must be added after.
  93. pub fn new_empty(header: Header) -> Self {
  94. let txs = vec![];
  95. let signature = Signature::dummy();
  96. Self { header, txs, signature }
  97. }
  98. /// A block's hash is the same as the hash of its header
  99. pub fn hash(&self) -> HeaderHash {
  100. self.header.hash()
  101. }
  102. /// Append a transaction to the block. Also adds it to the Merkle tree.
  103. /// Note: when we append a tx we rebuild the whole tree, so its preferable
  104. /// to append them all at once using `append_txs`.
  105. pub fn append_tx(&mut self, tx: Transaction) {
  106. let mut tree = MerkleTree::new(1);
  107. // Append existing block transactions to the tree
  108. for block_tx in &self.txs {
  109. append_tx_to_merkle_tree(&mut tree, block_tx);
  110. }
  111. // Append the new transaction
  112. append_tx_to_merkle_tree(&mut tree, &tx);
  113. self.txs.push(tx);
  114. // Grab the tree root and store it in the header
  115. self.header.root = tree.root(0).unwrap();
  116. }
  117. /// Append a vector of transactions to the block. Also adds them to the
  118. /// Merkle tree.
  119. /// Note: when we append txs we rebuild the whole tree, so its preferable
  120. /// to append them all at once.
  121. pub fn append_txs(&mut self, txs: Vec<Transaction>) {
  122. let mut tree = MerkleTree::new(1);
  123. // Append existing block transactions to the tree
  124. for block_tx in &self.txs {
  125. append_tx_to_merkle_tree(&mut tree, block_tx);
  126. }
  127. // Append the new transactions
  128. for tx in txs {
  129. append_tx_to_merkle_tree(&mut tree, &tx);
  130. self.txs.push(tx);
  131. }
  132. // Grab the tree root and store it in the header
  133. self.header.root = tree.root(0).unwrap();
  134. }
  135. /// Sign block header using provided secret key
  136. pub fn sign(&mut self, secret_key: &SecretKey) {
  137. self.signature = secret_key.sign(self.hash().inner());
  138. }
  139. }
  140. /// Auxiliary structure used to keep track of blocks order.
  141. #[derive(Debug, SerialEncodable, SerialDecodable)]
  142. pub struct BlockOrder {
  143. /// Block height
  144. pub height: u32,
  145. /// Block header hash of that height
  146. pub block: HeaderHash,
  147. }
  148. /// Auxiliary structure used to keep track of block ranking information.
  149. ///
  150. /// Note: we only need height cummulative ranks, but we also keep its actual
  151. /// ranks, so we can verify the sequence and/or know specific block height
  152. /// ranks, if ever needed.
  153. #[derive(Debug, SerialEncodable, SerialDecodable)]
  154. pub struct BlockRanks {
  155. /// Block target rank
  156. pub target_rank: BigUint,
  157. /// Height cummulative targets rank
  158. pub targets_rank: BigUint,
  159. /// Block hash rank
  160. pub hash_rank: BigUint,
  161. /// Height cummulative hashes rank
  162. pub hashes_rank: BigUint,
  163. }
  164. impl BlockRanks {
  165. pub fn new(
  166. target_rank: BigUint,
  167. targets_rank: BigUint,
  168. hash_rank: BigUint,
  169. hashes_rank: BigUint,
  170. ) -> Self {
  171. Self { target_rank, targets_rank, hash_rank, hashes_rank }
  172. }
  173. }
  174. /// Auxiliary structure used to keep track of block PoW difficulty information.
  175. ///
  176. /// Note: we only need height cummulative difficulty, but we also keep its actual
  177. /// difficulty, so we can verify the sequence and/or know specific block height
  178. /// difficulty, if ever needed.
  179. #[derive(Debug, SerialEncodable, SerialDecodable)]
  180. pub struct BlockDifficulty {
  181. /// Block height number
  182. pub height: u32,
  183. /// Block creation timestamp
  184. pub timestamp: Timestamp,
  185. /// Height difficulty
  186. pub difficulty: BigUint,
  187. /// Height cummulative difficulty (total + height difficulty)
  188. pub cummulative_difficulty: BigUint,
  189. /// Block ranks
  190. pub ranks: BlockRanks,
  191. }
  192. impl BlockDifficulty {
  193. pub fn new(
  194. height: u32,
  195. timestamp: Timestamp,
  196. difficulty: BigUint,
  197. cummulative_difficulty: BigUint,
  198. ranks: BlockRanks,
  199. ) -> Self {
  200. Self { height, timestamp, difficulty, cummulative_difficulty, ranks }
  201. }
  202. /// Represents the genesis block difficulty
  203. pub fn genesis(timestamp: Timestamp) -> Self {
  204. let ranks = BlockRanks::new(
  205. BigUint::from(0u64),
  206. BigUint::from(0u64),
  207. BigUint::from(0u64),
  208. BigUint::from(0u64),
  209. );
  210. BlockDifficulty::new(0u32, timestamp, BigUint::from(0u64), BigUint::from(0u64), ranks)
  211. }
  212. }
  213. pub const SLED_BLOCK_TREE: &[u8] = b"_blocks";
  214. pub const SLED_BLOCK_ORDER_TREE: &[u8] = b"_block_order";
  215. pub const SLED_BLOCK_DIFFICULTY_TREE: &[u8] = b"_block_difficulty";
  216. /// The `BlockStore` is a structure representing all `sled` trees related
  217. /// to storing the blockchain's blocks information.
  218. #[derive(Clone)]
  219. pub struct BlockStore {
  220. /// Main `sled` tree, storing all the blockchain's blocks, where the
  221. /// key is the blocks' hash, and value is the serialized block.
  222. pub main: sled::Tree,
  223. /// The `sled` tree storing the order of the blockchain's blocks,
  224. /// where the key is the height number, and the value is the blocks'
  225. /// hash.
  226. pub order: sled::Tree,
  227. /// The `sled` tree storing the the difficulty information of the
  228. /// blockchain's blocks, where the key is the block height number,
  229. /// and the value is the blocks' hash.
  230. pub difficulty: sled::Tree,
  231. }
  232. impl BlockStore {
  233. /// Opens a new or existing `BlockStore` on the given sled database.
  234. pub fn new(db: &sled::Db) -> Result<Self> {
  235. let main = db.open_tree(SLED_BLOCK_TREE)?;
  236. let order = db.open_tree(SLED_BLOCK_ORDER_TREE)?;
  237. let difficulty = db.open_tree(SLED_BLOCK_DIFFICULTY_TREE)?;
  238. Ok(Self { main, order, difficulty })
  239. }
  240. /// Insert a slice of [`Block`] into the store's main tree.
  241. pub fn insert(&self, blocks: &[Block]) -> Result<Vec<HeaderHash>> {
  242. let (batch, ret) = self.insert_batch(blocks);
  243. self.main.apply_batch(batch)?;
  244. Ok(ret)
  245. }
  246. /// Insert a slice of `u32` and block hashes into the store's
  247. /// order tree.
  248. pub fn insert_order(&self, heights: &[u32], hashes: &[HeaderHash]) -> Result<()> {
  249. let batch = self.insert_batch_order(heights, hashes);
  250. self.order.apply_batch(batch)?;
  251. Ok(())
  252. }
  253. /// Insert a slice of [`BlockDifficulty`] into the store's
  254. /// difficulty tree.
  255. pub fn insert_difficulty(&self, block_difficulties: &[BlockDifficulty]) -> Result<()> {
  256. let batch = self.insert_batch_difficulty(block_difficulties);
  257. self.difficulty.apply_batch(batch)?;
  258. Ok(())
  259. }
  260. /// Generate the sled batch corresponding to an insert to the main
  261. /// tree, so caller can handle the write operation.
  262. /// The block's hash() function output is used as the key,
  263. /// while value is the serialized [`Block`] itself.
  264. /// On success, the function returns the block hashes in the same order.
  265. pub fn insert_batch(&self, blocks: &[Block]) -> (sled::Batch, Vec<HeaderHash>) {
  266. let mut ret = Vec::with_capacity(blocks.len());
  267. let mut batch = sled::Batch::default();
  268. for block in blocks {
  269. let blockhash = block.hash();
  270. batch.insert(blockhash.inner(), serialize(block));
  271. ret.push(blockhash);
  272. }
  273. (batch, ret)
  274. }
  275. /// Generate the sled batch corresponding to an insert to the order
  276. /// tree, so caller can handle the write operation.
  277. /// The block height is used as the key, and the block hash is used as value.
  278. pub fn insert_batch_order(&self, heights: &[u32], hashes: &[HeaderHash]) -> sled::Batch {
  279. let mut batch = sled::Batch::default();
  280. for (i, height) in heights.iter().enumerate() {
  281. batch.insert(&height.to_be_bytes(), hashes[i].inner());
  282. }
  283. batch
  284. }
  285. /// Generate the sled batch corresponding to an insert to the difficulty
  286. /// tree, so caller can handle the write operation.
  287. /// The block's height number is used as the key, while value is
  288. // the serialized [`BlockDifficulty`] itself.
  289. pub fn insert_batch_difficulty(&self, block_difficulties: &[BlockDifficulty]) -> sled::Batch {
  290. let mut batch = sled::Batch::default();
  291. for block_difficulty in block_difficulties {
  292. batch.insert(&block_difficulty.height.to_be_bytes(), serialize(block_difficulty));
  293. }
  294. batch
  295. }
  296. /// Check if the store's main tree contains a given block hash.
  297. pub fn contains(&self, blockhash: &HeaderHash) -> Result<bool> {
  298. Ok(self.main.contains_key(blockhash.inner())?)
  299. }
  300. /// Check if the store's order tree contains a given height.
  301. pub fn contains_order(&self, height: u32) -> Result<bool> {
  302. Ok(self.order.contains_key(height.to_be_bytes())?)
  303. }
  304. /// Fetch given block hashes from the store's main tree.
  305. /// The resulting vector contains `Option`, which is `Some` if the block
  306. /// was found in the block store, and otherwise it is `None`, if it has not.
  307. /// The second parameter is a boolean which tells the function to fail in
  308. /// case at least one block was not found.
  309. pub fn get(&self, block_hashes: &[HeaderHash], strict: bool) -> Result<Vec<Option<Block>>> {
  310. let mut ret = Vec::with_capacity(block_hashes.len());
  311. for hash in block_hashes {
  312. if let Some(found) = self.main.get(hash.inner())? {
  313. let block = deserialize(&found)?;
  314. ret.push(Some(block));
  315. continue
  316. }
  317. if strict {
  318. return Err(Error::BlockNotFound(hash.as_string()))
  319. }
  320. ret.push(None);
  321. }
  322. Ok(ret)
  323. }
  324. /// Fetch given heights from the store's order tree.
  325. /// The resulting vector contains `Option`, which is `Some` if the height
  326. /// was found in the block order store, and otherwise it is `None`, if it has not.
  327. /// The second parameter is a boolean which tells the function to fail in
  328. /// case at least one height was not found.
  329. pub fn get_order(&self, heights: &[u32], strict: bool) -> Result<Vec<Option<HeaderHash>>> {
  330. let mut ret = Vec::with_capacity(heights.len());
  331. for height in heights {
  332. if let Some(found) = self.order.get(height.to_be_bytes())? {
  333. let block_hash = deserialize(&found)?;
  334. ret.push(Some(block_hash));
  335. continue
  336. }
  337. if strict {
  338. return Err(Error::BlockHeightNotFound(*height))
  339. }
  340. ret.push(None);
  341. }
  342. Ok(ret)
  343. }
  344. /// Fetch given block height numbers from the store's difficulty tree.
  345. /// The resulting vector contains `Option`, which is `Some` if the block
  346. /// height number was found in the block difficulties store, and otherwise
  347. /// it is `None`, if it has not.
  348. /// The second parameter is a boolean which tells the function to fail in
  349. /// case at least one block height number was not found.
  350. pub fn get_difficulty(
  351. &self,
  352. heights: &[u32],
  353. strict: bool,
  354. ) -> Result<Vec<Option<BlockDifficulty>>> {
  355. let mut ret = Vec::with_capacity(heights.len());
  356. for height in heights {
  357. if let Some(found) = self.difficulty.get(height.to_be_bytes())? {
  358. let block_difficulty = deserialize(&found)?;
  359. ret.push(Some(block_difficulty));
  360. continue
  361. }
  362. if strict {
  363. return Err(Error::BlockDifficultyNotFound(*height))
  364. }
  365. ret.push(None);
  366. }
  367. Ok(ret)
  368. }
  369. /// Retrieve all blocks from the store's main tree in the form of a
  370. /// tuple (`hash`, `block`).
  371. /// Be careful as this will try to load everything in memory.
  372. pub fn get_all(&self) -> Result<Vec<(HeaderHash, Block)>> {
  373. let mut blocks = vec![];
  374. for block in self.main.iter() {
  375. blocks.push(parse_record(block.unwrap())?);
  376. }
  377. Ok(blocks)
  378. }
  379. /// Retrieve complete order from the store's order tree in the form
  380. /// of a vector containing (`height`, `hash`) tuples.
  381. /// Be careful as this will try to load everything in memory.
  382. pub fn get_all_order(&self) -> Result<Vec<(u32, HeaderHash)>> {
  383. let mut order = vec![];
  384. for record in self.order.iter() {
  385. order.push(parse_u32_key_record(record.unwrap())?);
  386. }
  387. Ok(order)
  388. }
  389. /// Retrieve all block difficulties from the store's difficulty tree in
  390. /// the form of a vector containing (`height`, `difficulty`) tuples.
  391. /// Be careful as this will try to load everything in memory.
  392. pub fn get_all_difficulty(&self) -> Result<Vec<(u32, BlockDifficulty)>> {
  393. let mut block_difficulties = vec![];
  394. for record in self.difficulty.iter() {
  395. block_difficulties.push(parse_u32_key_record(record.unwrap())?);
  396. }
  397. Ok(block_difficulties)
  398. }
  399. /// Fetch n hashes before given height. In the iteration, if an order
  400. /// height is not found, the iteration stops and the function returns what
  401. /// it has found so far in the store's order tree.
  402. pub fn get_before(&self, height: u32, n: usize) -> Result<Vec<HeaderHash>> {
  403. let mut ret = vec![];
  404. let mut key = height;
  405. let mut counter = 0;
  406. while counter < n {
  407. if let Some(found) = self.order.get_lt(key.to_be_bytes())? {
  408. let (height, hash) = parse_u32_key_record(found)?;
  409. key = height;
  410. ret.push(hash);
  411. counter += 1;
  412. continue
  413. }
  414. break
  415. }
  416. Ok(ret.iter().rev().copied().collect())
  417. }
  418. /// Fetch all hashes after given height. In the iteration, if an order
  419. /// height is not found, the iteration stops and the function returns what
  420. /// it has found so far in the store's order tree.
  421. pub fn get_all_after(&self, height: u32) -> Result<Vec<HeaderHash>> {
  422. let mut ret = vec![];
  423. let mut key = height;
  424. while let Some(found) = self.order.get_gt(key.to_be_bytes())? {
  425. let (height, hash) = parse_u32_key_record(found)?;
  426. key = height;
  427. ret.push(hash);
  428. }
  429. Ok(ret)
  430. }
  431. /// Fetch the first block hash in the order tree, based on the `Ord`
  432. /// implementation for `Vec<u8>`.
  433. pub fn get_first(&self) -> Result<(u32, HeaderHash)> {
  434. let Some(found) = self.order.first()? else { return Err(Error::BlockHeightNotFound(0u32)) };
  435. let (height, hash) = parse_u32_key_record(found)?;
  436. Ok((height, hash))
  437. }
  438. /// Fetch the last block hash in the order tree, based on the `Ord`
  439. /// implementation for `Vec<u8>`.
  440. pub fn get_last(&self) -> Result<(u32, HeaderHash)> {
  441. let found = self.order.last()?.unwrap();
  442. let (height, hash) = parse_u32_key_record(found)?;
  443. Ok((height, hash))
  444. }
  445. /// Fetch the last record in the difficulty tree, based on the `Ord`
  446. /// implementation for `Vec<u8>`. If the tree is empty,
  447. /// returns `None`.
  448. pub fn get_last_difficulty(&self) -> Result<Option<BlockDifficulty>> {
  449. let Some(found) = self.difficulty.last()? else { return Ok(None) };
  450. let block_difficulty = deserialize(&found.1)?;
  451. Ok(Some(block_difficulty))
  452. }
  453. /// Fetch the last N records from the store's difficulty tree, in order.
  454. pub fn get_last_n_difficulties(&self, n: usize) -> Result<Vec<BlockDifficulty>> {
  455. // Build an iterator to retrieve last N records
  456. let records = self.difficulty.iter().rev().take(n);
  457. // Since the iterator grabs in right -> left order,
  458. // we deserialize found records, and push them in reverse order
  459. let mut last_n = vec![];
  460. for record in records {
  461. last_n.insert(0, deserialize(&record?.1)?);
  462. }
  463. Ok(last_n)
  464. }
  465. /// Retrieve store's order tree records count.
  466. pub fn len(&self) -> usize {
  467. self.order.len()
  468. }
  469. /// Check if store's order tree contains any records.
  470. pub fn is_empty(&self) -> bool {
  471. self.order.is_empty()
  472. }
  473. }
  474. /// Overlay structure over a [`BlockStore`] instance.
  475. pub struct BlockStoreOverlay(SledDbOverlayPtr);
  476. impl BlockStoreOverlay {
  477. pub fn new(overlay: &SledDbOverlayPtr) -> Result<Self> {
  478. overlay.lock().unwrap().open_tree(SLED_BLOCK_TREE, true)?;
  479. overlay.lock().unwrap().open_tree(SLED_BLOCK_ORDER_TREE, true)?;
  480. overlay.lock().unwrap().open_tree(SLED_BLOCK_DIFFICULTY_TREE, true)?;
  481. Ok(Self(overlay.clone()))
  482. }
  483. /// Insert a slice of [`Block`] into the overlay's main tree.
  484. /// The block's hash() function output is used as the key,
  485. /// while value is the serialized [`Block`] itself.
  486. /// On success, the function returns the block hashes in the same order.
  487. pub fn insert(&self, blocks: &[Block]) -> Result<Vec<HeaderHash>> {
  488. let mut ret = Vec::with_capacity(blocks.len());
  489. let mut lock = self.0.lock().unwrap();
  490. for block in blocks {
  491. let blockhash = block.hash();
  492. lock.insert(SLED_BLOCK_TREE, blockhash.inner(), &serialize(block))?;
  493. ret.push(blockhash);
  494. }
  495. Ok(ret)
  496. }
  497. /// Insert a slice of `u32` and block hashes into overlay's order tree.
  498. /// The block height is used as the key, and the blockhash is used as value.
  499. pub fn insert_order(&self, heights: &[u32], hashes: &[HeaderHash]) -> Result<()> {
  500. if heights.len() != hashes.len() {
  501. return Err(Error::InvalidInputLengths)
  502. }
  503. let mut lock = self.0.lock().unwrap();
  504. for (i, height) in heights.iter().enumerate() {
  505. lock.insert(SLED_BLOCK_ORDER_TREE, &height.to_be_bytes(), hashes[i].inner())?;
  506. }
  507. Ok(())
  508. }
  509. /// Insert a slice of [`BlockDifficulty`] into the overlay's difficulty tree.
  510. pub fn insert_difficulty(&self, block_difficulties: &[BlockDifficulty]) -> Result<()> {
  511. let mut lock = self.0.lock().unwrap();
  512. for block_difficulty in block_difficulties {
  513. lock.insert(
  514. SLED_BLOCK_DIFFICULTY_TREE,
  515. &block_difficulty.height.to_be_bytes(),
  516. &serialize(block_difficulty),
  517. )?;
  518. }
  519. Ok(())
  520. }
  521. /// Fetch given block hashes from the overlay's main tree.
  522. /// The resulting vector contains `Option`, which is `Some` if the block
  523. /// was found in the overlay, and otherwise it is `None`, if it has not.
  524. /// The second parameter is a boolean which tells the function to fail in
  525. /// case at least one block was not found.
  526. pub fn get(&self, block_hashes: &[HeaderHash], strict: bool) -> Result<Vec<Option<Block>>> {
  527. let mut ret = Vec::with_capacity(block_hashes.len());
  528. let lock = self.0.lock().unwrap();
  529. for hash in block_hashes {
  530. if let Some(found) = lock.get(SLED_BLOCK_TREE, hash.inner())? {
  531. let block = deserialize(&found)?;
  532. ret.push(Some(block));
  533. continue
  534. }
  535. if strict {
  536. return Err(Error::BlockNotFound(hash.as_string()))
  537. }
  538. ret.push(None);
  539. }
  540. Ok(ret)
  541. }
  542. /// Fetch given heights from the overlay's order tree.
  543. /// The resulting vector contains `Option`, which is `Some` if the height
  544. /// was found in the overlay, and otherwise it is `None`, if it has not.
  545. /// The second parameter is a boolean which tells the function to fail in
  546. /// case at least one height was not found.
  547. pub fn get_order(&self, heights: &[u32], strict: bool) -> Result<Vec<Option<HeaderHash>>> {
  548. let mut ret = Vec::with_capacity(heights.len());
  549. let lock = self.0.lock().unwrap();
  550. for height in heights {
  551. if let Some(found) = lock.get(SLED_BLOCK_ORDER_TREE, &height.to_be_bytes())? {
  552. let block_hash = deserialize(&found)?;
  553. ret.push(Some(block_hash));
  554. continue
  555. }
  556. if strict {
  557. return Err(Error::BlockHeightNotFound(*height))
  558. }
  559. ret.push(None);
  560. }
  561. Ok(ret)
  562. }
  563. /// Fetch the last block hash in the overlay's order tree, based on the `Ord`
  564. /// implementation for `Vec<u8>`.
  565. pub fn get_last(&self) -> Result<(u32, HeaderHash)> {
  566. let found = match self.0.lock().unwrap().last(SLED_BLOCK_ORDER_TREE)? {
  567. Some(b) => b,
  568. None => return Err(Error::BlockHeightNotFound(0u32)),
  569. };
  570. let (height, hash) = parse_u32_key_record(found)?;
  571. Ok((height, hash))
  572. }
  573. /// Check if overlay's order tree contains any records.
  574. pub fn is_empty(&self) -> Result<bool> {
  575. Ok(self.0.lock().unwrap().is_empty(SLED_BLOCK_ORDER_TREE)?)
  576. }
  577. }
  578. /// Auxiliary function to append a transaction to a Merkle tree.
  579. pub fn append_tx_to_merkle_tree(tree: &mut MerkleTree, tx: &Transaction) {
  580. let mut buf = [0u8; 64];
  581. buf[..32].copy_from_slice(tx.hash().inner());
  582. let leaf = pallas::Base::from_uniform_bytes(&buf);
  583. tree.append(leaf.into());
  584. }