block_store.rs 29 KB

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