mod.rs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2026 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::{
  19. slice,
  20. sync::{Arc, Mutex},
  21. };
  22. use darkfi_sdk::tx::TransactionHash;
  23. use darkfi_serial::{deserialize, Decodable};
  24. use sled_overlay::{
  25. sled,
  26. sled::{IVec, Transactional},
  27. };
  28. use tracing::debug;
  29. #[cfg(feature = "async-serial")]
  30. use darkfi_serial::{deserialize_async, AsyncDecodable};
  31. use crate::{tx::Transaction, util::time::Timestamp, Error, Result};
  32. /// Block related definitions and storage implementations
  33. pub mod block_store;
  34. pub use block_store::{
  35. Block, BlockDifficulty, BlockInfo, BlockStore, BlockStoreOverlay, SLED_BLOCK_DIFFICULTY_TREE,
  36. SLED_BLOCK_ORDER_TREE, SLED_BLOCK_STATE_INVERSE_DIFF_TREE, SLED_BLOCK_TREE,
  37. };
  38. /// Header definition and storage implementation
  39. pub mod header_store;
  40. pub use header_store::{
  41. Header, HeaderHash, HeaderStore, HeaderStoreOverlay, SLED_HEADER_TREE, SLED_SYNC_HEADER_TREE,
  42. };
  43. /// Transactions related storage implementations
  44. pub mod tx_store;
  45. pub use tx_store::{
  46. TxStore, TxStoreOverlay, SLED_PENDING_TX_ORDER_TREE, SLED_PENDING_TX_TREE,
  47. SLED_TX_LOCATION_TREE, SLED_TX_TREE,
  48. };
  49. /// Contracts and Wasm storage implementations
  50. pub mod contract_store;
  51. pub use contract_store::{
  52. ContractStore, ContractStoreOverlay, SLED_BINCODE_TREE, SLED_CONTRACTS_TREE,
  53. SLED_CONTRACTS_TREES_TREE,
  54. };
  55. /// Monero definitions needed for merge mining
  56. pub mod monero;
  57. /// Structure holding all sled trees that define the concept of Blockchain.
  58. #[derive(Clone)]
  59. pub struct Blockchain {
  60. /// Main pointer to the sled db connection
  61. pub sled_db: sled::Db,
  62. /// Headers sled tree
  63. pub headers: HeaderStore,
  64. /// Blocks sled tree
  65. pub blocks: BlockStore,
  66. /// Transactions related sled trees
  67. pub transactions: TxStore,
  68. /// Contracts related sled trees
  69. pub contracts: ContractStore,
  70. }
  71. impl Blockchain {
  72. /// Instantiate a new `Blockchain` with the given `sled` database.
  73. pub fn new(db: &sled::Db) -> Result<Self> {
  74. let headers = HeaderStore::new(db)?;
  75. let blocks = BlockStore::new(db)?;
  76. let transactions = TxStore::new(db)?;
  77. let contracts = ContractStore::new(db)?;
  78. Ok(Self { sled_db: db.clone(), headers, blocks, transactions, contracts })
  79. }
  80. /// Insert a given [`BlockInfo`] into the blockchain database.
  81. /// This functions wraps all the logic of separating the block into specific
  82. /// data that can be fed into the different trees of the database.
  83. /// Upon success, the functions returns the block hash that
  84. /// were given and appended to the ledger.
  85. pub fn add_block(&self, block: &BlockInfo) -> Result<HeaderHash> {
  86. let mut trees = vec![];
  87. let mut batches = vec![];
  88. // Store header
  89. let (headers_batch, _) = self.headers.insert_batch(slice::from_ref(&block.header));
  90. trees.push(self.headers.main.clone());
  91. batches.push(headers_batch);
  92. // Store block
  93. let blk: Block = Block::from_block_info(block);
  94. let (bocks_batch, block_hashes) = self.blocks.insert_batch(&[blk]);
  95. let block_hash = block_hashes[0];
  96. let block_hash_vec = [block_hash];
  97. trees.push(self.blocks.main.clone());
  98. batches.push(bocks_batch);
  99. // Store block order
  100. let blocks_order_batch =
  101. self.blocks.insert_batch_order(&[block.header.height], &block_hash_vec);
  102. trees.push(self.blocks.order.clone());
  103. batches.push(blocks_order_batch);
  104. // Store transactions
  105. let (txs_batch, txs_hashes) = self.transactions.insert_batch(&block.txs);
  106. trees.push(self.transactions.main.clone());
  107. batches.push(txs_batch);
  108. // Store transactions_locations
  109. let txs_locations_batch =
  110. self.transactions.insert_batch_location(&txs_hashes, block.header.height);
  111. trees.push(self.transactions.location.clone());
  112. batches.push(txs_locations_batch);
  113. // Perform an atomic transaction over the trees and apply the batches.
  114. self.atomic_write(&trees, &batches)?;
  115. Ok(block_hash)
  116. }
  117. /// Check if the given [`BlockInfo`] is in the database and all trees.
  118. pub fn has_block(&self, block: &BlockInfo) -> Result<bool> {
  119. let blockhash = match self.blocks.get_order(&[block.header.height], true) {
  120. Ok(v) => v[0].unwrap(),
  121. Err(_) => return Ok(false),
  122. };
  123. // Check if we have all transactions
  124. let txs: Vec<TransactionHash> = block.txs.iter().map(|tx| tx.hash()).collect();
  125. if self.transactions.get(&txs, true).is_err() {
  126. return Ok(false)
  127. }
  128. // Check provided info produces the same hash
  129. Ok(blockhash == block.hash())
  130. }
  131. /// Retrieve [`BlockInfo`]s by given hashes. Fails if any of them is not found.
  132. pub fn get_blocks_by_hash(&self, hashes: &[HeaderHash]) -> Result<Vec<BlockInfo>> {
  133. let blocks = self.blocks.get(hashes, true)?;
  134. let blocks: Vec<Block> = blocks.iter().map(|x| x.clone().unwrap()).collect();
  135. let ret = self.get_blocks_infos(&blocks)?;
  136. Ok(ret)
  137. }
  138. /// Retrieve all [`BlockInfo`] for given slice of [`Block`].
  139. /// Fails if any of them is not found
  140. fn get_blocks_infos(&self, blocks: &[Block]) -> Result<Vec<BlockInfo>> {
  141. let mut ret = Vec::with_capacity(blocks.len());
  142. for block in blocks {
  143. let headers = self.headers.get(&[block.header], true)?;
  144. // Since we used strict get, its safe to unwrap here
  145. let header = headers[0].clone().unwrap();
  146. let txs = self.transactions.get(&block.txs, true)?;
  147. let txs = txs.iter().map(|x| x.clone().unwrap()).collect();
  148. let info = BlockInfo::new(header, txs, block.signature);
  149. ret.push(info);
  150. }
  151. Ok(ret)
  152. }
  153. /// Retrieve [`BlockInfo`]s by given heights. Does not fail if any of them are not found.
  154. pub fn get_blocks_by_heights(&self, heights: &[u32]) -> Result<Vec<BlockInfo>> {
  155. debug!(target: "blockchain", "get_blocks_by_heights(): {heights:?}");
  156. let blockhashes = self.blocks.get_order(heights, false)?;
  157. let mut hashes = vec![];
  158. for i in blockhashes.into_iter().flatten() {
  159. hashes.push(i);
  160. }
  161. self.get_blocks_by_hash(&hashes)
  162. }
  163. /// Retrieve [`Header`]s by given hashes. Fails if any of them is not found.
  164. pub fn get_headers_by_hash(&self, hashes: &[HeaderHash]) -> Result<Vec<Header>> {
  165. let headers = self.headers.get(hashes, true)?;
  166. let ret: Vec<Header> = headers.iter().map(|x| x.clone().unwrap()).collect();
  167. Ok(ret)
  168. }
  169. /// Retrieve [`Header`]s by given heights. Fails if any of them is not found.
  170. pub fn get_headers_by_heights(&self, heights: &[u32]) -> Result<Vec<Header>> {
  171. debug!(target: "blockchain", "get_headers_by_heights(): {heights:?}");
  172. let blockhashes = self.blocks.get_order(heights, true)?;
  173. let mut hashes = vec![];
  174. for i in blockhashes.into_iter().flatten() {
  175. hashes.push(i);
  176. }
  177. self.get_headers_by_hash(&hashes)
  178. }
  179. /// Retrieve n headers before given block height.
  180. pub fn get_headers_before(&self, height: u32, n: usize) -> Result<Vec<Header>> {
  181. debug!(target: "blockchain", "get_headers_before(): {height} -> {n}");
  182. let hashes = self.blocks.get_before(height, n)?;
  183. let headers = self.headers.get(&hashes, true)?;
  184. Ok(headers.iter().map(|h| h.clone().unwrap()).collect())
  185. }
  186. /// Retrieve stored blocks count
  187. pub fn len(&self) -> usize {
  188. self.blocks.len()
  189. }
  190. /// Retrieve stored txs count
  191. pub fn txs_len(&self) -> usize {
  192. self.transactions.len()
  193. }
  194. /// Check if blockchain contains any blocks
  195. pub fn is_empty(&self) -> bool {
  196. self.blocks.is_empty()
  197. }
  198. /// Retrieve genesis (first) block height and hash.
  199. pub fn genesis(&self) -> Result<(u32, HeaderHash)> {
  200. self.blocks.get_first()
  201. }
  202. /// Retrieve genesis (first) block info.
  203. pub fn genesis_block(&self) -> Result<BlockInfo> {
  204. let (_, hash) = self.genesis()?;
  205. Ok(self.get_blocks_by_hash(&[hash])?[0].clone())
  206. }
  207. /// Retrieve the last block height and hash.
  208. pub fn last(&self) -> Result<(u32, HeaderHash)> {
  209. self.blocks.get_last()
  210. }
  211. /// Retrieve the last block header.
  212. pub fn last_header(&self) -> Result<Header> {
  213. let (_, hash) = self.last()?;
  214. Ok(self.headers.get(&[hash], true)?[0].clone().unwrap())
  215. }
  216. /// Retrieve the last block info.
  217. pub fn last_block(&self) -> Result<BlockInfo> {
  218. let (_, hash) = self.last()?;
  219. Ok(self.get_blocks_by_hash(&[hash])?[0].clone())
  220. }
  221. /// Retrieve the last block difficulty. If the tree is empty,
  222. /// returns `BlockDifficulty::genesis` difficulty.
  223. pub fn last_block_difficulty(&self) -> Result<BlockDifficulty> {
  224. if let Some(found) = self.blocks.get_last_difficulty()? {
  225. return Ok(found)
  226. }
  227. let genesis_block = self.genesis_block()?;
  228. Ok(BlockDifficulty::genesis(genesis_block.header.timestamp))
  229. }
  230. /// Check if block order for the given height is in the database.
  231. pub fn has_height(&self, height: u32) -> Result<bool> {
  232. let vec = match self.blocks.get_order(&[height], true) {
  233. Ok(v) => v,
  234. Err(_) => return Ok(false),
  235. };
  236. Ok(!vec.is_empty())
  237. }
  238. /// Insert a given slice of pending transactions into the blockchain database.
  239. /// On success, the function returns the transaction hashes in the same order
  240. /// as the input transactions.
  241. pub fn add_pending_txs(&self, txs: &[Transaction]) -> Result<Vec<TransactionHash>> {
  242. let (txs_batch, txs_hashes) = self.transactions.insert_batch_pending(txs);
  243. let txs_order_batch = self.transactions.insert_batch_pending_order(&txs_hashes)?;
  244. // Perform an atomic transaction over the trees and apply the batches.
  245. let trees = [self.transactions.pending.clone(), self.transactions.pending_order.clone()];
  246. let batches = [txs_batch, txs_order_batch];
  247. self.atomic_write(&trees, &batches)?;
  248. Ok(txs_hashes)
  249. }
  250. /// Retrieve all transactions from the pending tx store.
  251. /// Be careful as this will try to load everything in memory.
  252. pub fn get_pending_txs(&self) -> Result<Vec<Transaction>> {
  253. let txs = self.transactions.get_all_pending()?;
  254. let indexes = self.transactions.get_all_pending_order()?;
  255. if txs.len() != indexes.len() {
  256. return Err(Error::InvalidInputLengths)
  257. }
  258. let mut ret = Vec::with_capacity(txs.len());
  259. for index in indexes {
  260. ret.push(txs.get(&index.1).unwrap().clone());
  261. }
  262. Ok(ret)
  263. }
  264. /// Remove a given slice of pending transactions from the blockchain database.
  265. pub fn remove_pending_txs(&self, txs: &[Transaction]) -> Result<()> {
  266. let txs_hashes: Vec<TransactionHash> = txs.iter().map(|tx| tx.hash()).collect();
  267. self.remove_pending_txs_hashes(&txs_hashes)
  268. }
  269. /// Remove a given slice of pending transactions hashes from the blockchain database.
  270. pub fn remove_pending_txs_hashes(&self, txs: &[TransactionHash]) -> Result<()> {
  271. let indexes = self.transactions.get_all_pending_order()?;
  272. // We could do indexes.iter().map(|x| txs.contains(x.1)).collect.map(|x| x.0).collect
  273. // but this is faster since we don't do the second iteration
  274. let mut removed_indexes = vec![];
  275. for index in indexes {
  276. if txs.contains(&index.1) {
  277. removed_indexes.push(index.0);
  278. }
  279. }
  280. let txs_batch = self.transactions.remove_batch_pending(txs);
  281. let txs_order_batch = self.transactions.remove_batch_pending_order(&removed_indexes);
  282. // Perform an atomic transaction over the trees and apply the batches.
  283. let trees = [self.transactions.pending.clone(), self.transactions.pending_order.clone()];
  284. let batches = [txs_batch, txs_order_batch];
  285. self.atomic_write(&trees, &batches)?;
  286. Ok(())
  287. }
  288. /// Remove all transactions from the pending tx store not in the
  289. /// provided vector and rebuild the remaining ones order.
  290. pub fn reset_pending_txs(&self, exclude_txs: &[TransactionHash]) -> Result<()> {
  291. let mut txs = vec![];
  292. let mut removed_txs = vec![];
  293. for tx in self.transactions.get_all_pending()?.keys() {
  294. if exclude_txs.contains(tx) {
  295. txs.push(*tx);
  296. continue
  297. }
  298. removed_txs.push(*tx);
  299. }
  300. let indexes: Vec<u64> =
  301. self.transactions.get_all_pending_order()?.iter().map(|(k, _)| *k).collect();
  302. let txs_batch = self.transactions.remove_batch_pending(&removed_txs);
  303. let txs_order_batch = self.transactions.remove_batch_pending_order(&indexes);
  304. let txs_new_order_batch = self.transactions.insert_batch_pending_order(&txs)?;
  305. // Perform an atomic transaction over the trees and apply the batches.
  306. let trees = [
  307. self.transactions.pending.clone(),
  308. self.transactions.pending_order.clone(),
  309. self.transactions.pending_order.clone(),
  310. ];
  311. let batches = [txs_batch, txs_order_batch, txs_new_order_batch];
  312. self.atomic_write(&trees, &batches)?;
  313. Ok(())
  314. }
  315. /// Auxiliary function to write to multiple trees completely atomic.
  316. fn atomic_write(&self, trees: &[sled::Tree], batches: &[sled::Batch]) -> Result<()> {
  317. if trees.len() != batches.len() {
  318. return Err(Error::InvalidInputLengths)
  319. }
  320. trees.transaction(|trees| {
  321. for (index, tree) in trees.iter().enumerate() {
  322. tree.apply_batch(&batches[index])?;
  323. }
  324. Ok::<(), sled::transaction::ConflictableTransactionError<sled::Error>>(())
  325. })?;
  326. Ok(())
  327. }
  328. /// Retrieve all blocks contained in the blockchain in order.
  329. /// Be careful as this will try to load everything in memory.
  330. pub fn get_all(&self) -> Result<Vec<BlockInfo>> {
  331. let order = self.blocks.get_all_order()?;
  332. let order: Vec<HeaderHash> = order.iter().map(|x| x.1).collect();
  333. let blocks = self.get_blocks_by_hash(&order)?;
  334. Ok(blocks)
  335. }
  336. /// Retrieve [`BlockInfo`]s by given heights range.
  337. pub fn get_by_range(&self, start: u32, end: u32) -> Result<Vec<BlockInfo>> {
  338. let blockhashes = self.blocks.get_order_by_range(start, end)?;
  339. let hashes: Vec<HeaderHash> = blockhashes.into_iter().map(|(_, hash)| hash).collect();
  340. self.get_blocks_by_hash(&hashes)
  341. }
  342. /// Retrieve last 'N' [`BlockInfo`]s from the blockchain.
  343. pub fn get_last_n(&self, n: usize) -> Result<Vec<BlockInfo>> {
  344. let records = self.blocks.get_last_n_orders(n)?;
  345. let mut last_n = vec![];
  346. for record in records {
  347. let header_hash = record.1;
  348. let blocks = self.get_blocks_by_hash(&[header_hash])?;
  349. for block in blocks {
  350. last_n.push(block.clone());
  351. }
  352. }
  353. Ok(last_n)
  354. }
  355. /// Auxiliary function to reset the blockchain and consensus state
  356. /// to the provided block height.
  357. pub fn reset_to_height(&self, height: u32) -> Result<()> {
  358. // First we grab the last block height
  359. let (last, _) = self.last()?;
  360. // Check if request height is after our last height
  361. if height >= last {
  362. return Ok(())
  363. }
  364. // Grab all state inverse diffs until requested height,
  365. // going backwards.
  366. let heights: Vec<u32> = (height + 1..=last).rev().collect();
  367. let inverse_diffs = self.blocks.get_state_inverse_diff(&heights, true)?;
  368. // Create an overlay to apply the reverse diffs
  369. let overlay = BlockchainOverlay::new(self)?;
  370. // Apply the inverse diffs sequence
  371. let overlay_lock = overlay.lock().unwrap();
  372. let mut lock = overlay_lock.overlay.lock().unwrap();
  373. for inverse_diff in inverse_diffs {
  374. // Since we used strict retrieval it's safe to unwrap here
  375. let inverse_diff = inverse_diff.unwrap();
  376. lock.add_diff(&inverse_diff)?;
  377. lock.apply_diff(&inverse_diff)?;
  378. self.sled_db.flush()?;
  379. }
  380. drop(lock);
  381. drop(overlay_lock);
  382. Ok(())
  383. }
  384. /// Grab the RandomX VM current and next key, based on provided key
  385. /// changing height and delay. Optionally, a height can be provided
  386. /// to get the keys before it.
  387. ///
  388. /// NOTE: the height calculation logic is verified using test:
  389. // test_randomx_keys_retrieval_logic
  390. pub fn get_randomx_vm_keys(
  391. &self,
  392. key_change_height: &u32,
  393. key_change_delay: &u32,
  394. height: Option<u32>,
  395. ) -> Result<(HeaderHash, Option<HeaderHash>)> {
  396. // Grab last known block header
  397. let last = match height {
  398. Some(h) => &self.get_headers_by_heights(&[if h != 0 { h - 1 } else { 0 }])?[0],
  399. None => &self.last_header()?,
  400. };
  401. // Check if we passed the first key change height
  402. if &last.height <= key_change_height {
  403. // Genesis is our current
  404. let current = self.genesis()?.1;
  405. // Check if last known block header is the next key
  406. let next = if &last.height == key_change_height { Some(last.hash()) } else { None };
  407. return Ok((current, next))
  408. }
  409. // Find the current and next key based on distance of last
  410. // known block header height from the key change height.
  411. let distance = last.height % key_change_height;
  412. // When distance is 0, current key is the block header
  413. // located at last_height - key_change_height height, while
  414. // last known block header is the next key.
  415. if distance == 0 {
  416. return Ok((
  417. self.get_headers_by_heights(&[last.height - key_change_height])?[0].hash(),
  418. Some(last.hash()),
  419. ))
  420. }
  421. // When distance is less than key change delay, current key
  422. // is the block header located at last_height - (distance + key_change_height)
  423. // height, while the block header located at last_height - distance
  424. // height is the next key.
  425. if &distance < key_change_delay {
  426. return Ok((
  427. self.get_headers_by_heights(&[last.height - (distance + key_change_height)])?[0]
  428. .hash(),
  429. Some(self.get_headers_by_heights(&[last.height - distance])?[0].hash()),
  430. ))
  431. }
  432. // When distance is greater or equal to key change delay,
  433. // current key is the block header located at last_height - distance
  434. // height and we don't know the next key.
  435. let current = self.get_headers_by_heights(&[last.height - distance])?[0].hash();
  436. Ok((current, None))
  437. }
  438. }
  439. /// Atomic pointer to sled db overlay.
  440. pub type SledDbOverlayPtr = Arc<Mutex<sled_overlay::SledDbOverlay>>;
  441. /// Atomic pointer to blockchain overlay.
  442. pub type BlockchainOverlayPtr = Arc<Mutex<BlockchainOverlay>>;
  443. /// Overlay structure over a [`Blockchain`] instance.
  444. pub struct BlockchainOverlay {
  445. /// Main [`sled_overlay::SledDbOverlay`] to the sled db connection
  446. pub overlay: SledDbOverlayPtr,
  447. /// Headers overlay
  448. pub headers: HeaderStoreOverlay,
  449. /// Blocks overlay
  450. pub blocks: BlockStoreOverlay,
  451. /// Transactions overlay
  452. pub transactions: TxStoreOverlay,
  453. /// Contract overlay
  454. pub contracts: ContractStoreOverlay,
  455. }
  456. impl BlockchainOverlay {
  457. /// Instantiate a new `BlockchainOverlay` over the given [`Blockchain`] instance.
  458. pub fn new(blockchain: &Blockchain) -> Result<BlockchainOverlayPtr> {
  459. // Here we configure all our blockchain sled trees to be protected in the overlay
  460. let protected_trees = vec![
  461. SLED_BLOCK_TREE,
  462. SLED_BLOCK_ORDER_TREE,
  463. SLED_BLOCK_DIFFICULTY_TREE,
  464. SLED_BLOCK_STATE_INVERSE_DIFF_TREE,
  465. SLED_HEADER_TREE,
  466. SLED_SYNC_HEADER_TREE,
  467. SLED_TX_TREE,
  468. SLED_TX_LOCATION_TREE,
  469. SLED_PENDING_TX_TREE,
  470. SLED_PENDING_TX_ORDER_TREE,
  471. SLED_CONTRACTS_TREE,
  472. SLED_CONTRACTS_TREES_TREE,
  473. SLED_BINCODE_TREE,
  474. ];
  475. let overlay = Arc::new(Mutex::new(sled_overlay::SledDbOverlay::new(
  476. &blockchain.sled_db,
  477. protected_trees,
  478. )));
  479. let headers = HeaderStoreOverlay::new(&overlay)?;
  480. let blocks = BlockStoreOverlay::new(&overlay)?;
  481. let transactions = TxStoreOverlay::new(&overlay)?;
  482. let contracts = ContractStoreOverlay::new(&overlay)?;
  483. Ok(Arc::new(Mutex::new(Self { overlay, headers, blocks, transactions, contracts })))
  484. }
  485. /// Check if blockchain contains any blocks
  486. pub fn is_empty(&self) -> Result<bool> {
  487. self.blocks.is_empty()
  488. }
  489. /// Retrieve the last block height and hash.
  490. pub fn last(&self) -> Result<(u32, HeaderHash)> {
  491. self.blocks.get_last()
  492. }
  493. /// Retrieve the last block info.
  494. pub fn last_block(&self) -> Result<BlockInfo> {
  495. let (_, hash) = self.last()?;
  496. Ok(self.get_blocks_by_hash(&[hash])?[0].clone())
  497. }
  498. /// Retrieve the last block height.
  499. pub fn last_block_height(&self) -> Result<u32> {
  500. Ok(self.last()?.0)
  501. }
  502. /// Retrieve the last block timestamp.
  503. pub fn last_block_timestamp(&self) -> Result<Timestamp> {
  504. let (_, hash) = self.last()?;
  505. Ok(self.get_blocks_by_hash(&[hash])?[0].header.timestamp)
  506. }
  507. /// Insert a given [`BlockInfo`] into the overlay.
  508. /// This functions wraps all the logic of separating the block into specific
  509. /// data that can be fed into the different trees of the overlay.
  510. /// Upon success, the functions returns the block hash that
  511. /// were given and appended to the overlay.
  512. /// Since we are adding to the overlay, we don't need to exeucte
  513. /// the writes atomically.
  514. pub fn add_block(&self, block: &BlockInfo) -> Result<HeaderHash> {
  515. // Store header
  516. self.headers.insert(slice::from_ref(&block.header))?;
  517. // Store block
  518. let blk: Block = Block::from_block_info(block);
  519. let txs_hashes = blk.txs.clone();
  520. let block_hash = self.blocks.insert(&[blk])?[0];
  521. let block_hash_vec = [block_hash];
  522. // Store block order
  523. self.blocks.insert_order(&[block.header.height], &block_hash_vec)?;
  524. // Store transactions
  525. self.transactions.insert(&block.txs)?;
  526. // Store transactions locations
  527. self.transactions.insert_location(&txs_hashes, block.header.height)?;
  528. Ok(block_hash)
  529. }
  530. /// Check if the given [`BlockInfo`] is in the database and all trees.
  531. pub fn has_block(&self, block: &BlockInfo) -> Result<bool> {
  532. let blockhash = match self.blocks.get_order(&[block.header.height], true) {
  533. Ok(v) => v[0].unwrap(),
  534. Err(_) => return Ok(false),
  535. };
  536. // Check if we have all transactions
  537. let txs: Vec<TransactionHash> = block.txs.iter().map(|tx| tx.hash()).collect();
  538. if self.transactions.get(&txs, true).is_err() {
  539. return Ok(false)
  540. }
  541. // Check provided info produces the same hash
  542. Ok(blockhash == block.hash())
  543. }
  544. /// Retrieve [`Header`]s by given hashes. Fails if any of them is not found.
  545. pub fn get_headers_by_hash(&self, hashes: &[HeaderHash]) -> Result<Vec<Header>> {
  546. let headers = self.headers.get(hashes, true)?;
  547. let ret: Vec<Header> = headers.iter().map(|x| x.clone().unwrap()).collect();
  548. Ok(ret)
  549. }
  550. /// Retrieve [`BlockInfo`]s by given hashes. Fails if any of them is not found.
  551. pub fn get_blocks_by_hash(&self, hashes: &[HeaderHash]) -> Result<Vec<BlockInfo>> {
  552. let blocks = self.blocks.get(hashes, true)?;
  553. let blocks: Vec<Block> = blocks.iter().map(|x| x.clone().unwrap()).collect();
  554. let ret = self.get_blocks_infos(&blocks)?;
  555. Ok(ret)
  556. }
  557. /// Retrieve all [`BlockInfo`] for given slice of [`Block`].
  558. /// Fails if any of them is not found
  559. fn get_blocks_infos(&self, blocks: &[Block]) -> Result<Vec<BlockInfo>> {
  560. let mut ret = Vec::with_capacity(blocks.len());
  561. for block in blocks {
  562. let headers = self.headers.get(&[block.header], true)?;
  563. // Since we used strict get, its safe to unwrap here
  564. let header = headers[0].clone().unwrap();
  565. let txs = self.transactions.get(&block.txs, true)?;
  566. let txs = txs.iter().map(|x| x.clone().unwrap()).collect();
  567. let info = BlockInfo::new(header, txs, block.signature);
  568. ret.push(info);
  569. }
  570. Ok(ret)
  571. }
  572. /// Retrieve [`Block`]s by given hashes and return their transactions hashes.
  573. pub fn get_blocks_txs_hashes(&self, hashes: &[HeaderHash]) -> Result<Vec<TransactionHash>> {
  574. let blocks = self.blocks.get(hashes, true)?;
  575. let mut ret = vec![];
  576. for block in blocks {
  577. ret.extend_from_slice(&block.unwrap().txs);
  578. }
  579. Ok(ret)
  580. }
  581. /// Checkpoint overlay so we can revert to it, if needed.
  582. pub fn checkpoint(&self) {
  583. self.overlay.lock().unwrap().checkpoint();
  584. }
  585. /// Revert to current overlay checkpoint.
  586. pub fn revert_to_checkpoint(&self) {
  587. self.overlay.lock().unwrap().revert_to_checkpoint();
  588. }
  589. /// Auxiliary function to create a full clone using SledDbOverlay::clone,
  590. /// generating new pointers for the underlying overlays.
  591. pub fn full_clone(&self) -> Result<BlockchainOverlayPtr> {
  592. let overlay = Arc::new(Mutex::new(self.overlay.lock().unwrap().clone()));
  593. let headers = HeaderStoreOverlay::new(&overlay)?;
  594. let blocks = BlockStoreOverlay::new(&overlay)?;
  595. let transactions = TxStoreOverlay::new(&overlay)?;
  596. let contracts = ContractStoreOverlay::new(&overlay)?;
  597. Ok(Arc::new(Mutex::new(Self { overlay, headers, blocks, transactions, contracts })))
  598. }
  599. }
  600. /// Parse a sled record in the form of a tuple (`key`, `value`).
  601. pub fn parse_record<T1: Decodable, T2: Decodable>(record: (IVec, IVec)) -> Result<(T1, T2)> {
  602. let key = deserialize(&record.0)?;
  603. let value = deserialize(&record.1)?;
  604. Ok((key, value))
  605. }
  606. /// Parse a sled record with a u32 key, encoded in Big Endian bytes,
  607. /// in the form of a tuple (`key`, `value`).
  608. pub fn parse_u32_key_record<T: Decodable>(record: (IVec, IVec)) -> Result<(u32, T)> {
  609. let key_bytes: [u8; 4] = record.0.as_ref().try_into().unwrap();
  610. let key = u32::from_be_bytes(key_bytes);
  611. let value = deserialize(&record.1)?;
  612. Ok((key, value))
  613. }
  614. /// Parse a sled record with a u64 key, encoded in Big Endian bytes,
  615. /// in the form of a tuple (`key`, `value`).
  616. pub fn parse_u64_key_record<T: Decodable>(record: (IVec, IVec)) -> Result<(u64, T)> {
  617. let key_bytes: [u8; 8] = record.0.as_ref().try_into().unwrap();
  618. let key = u64::from_be_bytes(key_bytes);
  619. let value = deserialize(&record.1)?;
  620. Ok((key, value))
  621. }
  622. #[cfg(feature = "async-serial")]
  623. /// Parse a sled record in the form of a tuple (`key`, `value`).
  624. pub async fn parse_record_async<T1: AsyncDecodable, T2: AsyncDecodable>(
  625. record: (IVec, IVec),
  626. ) -> Result<(T1, T2)> {
  627. let key = deserialize_async(&record.0).await?;
  628. let value = deserialize_async(&record.1).await?;
  629. Ok((key, value))
  630. }
  631. #[cfg(feature = "async-serial")]
  632. /// Parse a sled record with a u32 key, encoded in Big Endian bytes,
  633. /// in the form of a tuple (`key`, `value`).
  634. pub async fn parse_u32_key_record_async<T: AsyncDecodable>(
  635. record: (IVec, IVec),
  636. ) -> Result<(u32, T)> {
  637. let key_bytes: [u8; 4] = record.0.as_ref().try_into().unwrap();
  638. let key = u32::from_be_bytes(key_bytes);
  639. let value = deserialize_async(&record.1).await?;
  640. Ok((key, value))
  641. }
  642. #[cfg(feature = "async-serial")]
  643. /// Parse a sled record with a u64 key, encoded in Big Endian bytes,
  644. /// in the form of a tuple (`key`, `value`).
  645. pub async fn parse_u64_key_record_async<T: AsyncDecodable>(
  646. record: (IVec, IVec),
  647. ) -> Result<(u64, T)> {
  648. let key_bytes: [u8; 8] = record.0.as_ref().try_into().unwrap();
  649. let key = u64::from_be_bytes(key_bytes);
  650. let value = deserialize_async(&record.1).await?;
  651. Ok((key, value))
  652. }
  653. #[cfg(test)]
  654. mod tests {
  655. use crate::validator::pow::{RANDOMX_KEY_CHANGE_DELAY, RANDOMX_KEY_CHANGING_HEIGHT};
  656. /// Compute the RandomX VM current and next key heights, based on
  657. /// provided key changing height and delay.
  658. fn get_randomx_vm_keys_heights(last: u32) -> (u32, Option<u32>) {
  659. // Check if we passed the first key change height
  660. if last <= RANDOMX_KEY_CHANGING_HEIGHT {
  661. // Genesis is our current
  662. let current = 0;
  663. // Check if last height is the next key height
  664. let next = if last == RANDOMX_KEY_CHANGING_HEIGHT { Some(last) } else { None };
  665. return (current, next)
  666. }
  667. // Find the current and next key based on distance of last
  668. // height from the key change height.
  669. let distance = last % RANDOMX_KEY_CHANGING_HEIGHT;
  670. // When distance is 0, current key is the last_height - RANDOMX_KEY_CHANGING_HEIGHT
  671. // height, while last is the next key.
  672. if distance == 0 {
  673. return (last - RANDOMX_KEY_CHANGING_HEIGHT, Some(last))
  674. }
  675. // When distance is less than key change delay, current key
  676. // is the last_height - (distance + RANDOMX_KEY_CHANGING_HEIGHT) height,
  677. // while the last_height - distance height is the next key.
  678. if distance < RANDOMX_KEY_CHANGE_DELAY {
  679. return (last - (distance + RANDOMX_KEY_CHANGING_HEIGHT), Some(last - distance))
  680. }
  681. // When distance is greater or equal to key change delay,
  682. // current key is the last_height - distance height and we
  683. // don't know the next key height.
  684. let current = last - distance;
  685. (current, None)
  686. }
  687. #[test]
  688. fn test_randomx_keys_retrieval_logic() {
  689. // last < RANDOMX_KEY_CHANGING_HEIGHT(2048)
  690. let (current, next) = get_randomx_vm_keys_heights(2047);
  691. assert_eq!(current, 0);
  692. assert!(next.is_none());
  693. // last == RANDOMX_KEY_CHANGING_HEIGHT(2048)
  694. let (current, next) = get_randomx_vm_keys_heights(2048);
  695. assert_eq!(current, 0);
  696. assert_eq!(next, Some(2048));
  697. // last > RANDOMX_KEY_CHANGING_HEIGHT(2048)
  698. // last % RANDOMX_KEY_CHANGING_HEIGHT(2048) == 0
  699. let (current, next) = get_randomx_vm_keys_heights(4096);
  700. assert_eq!(current, 2048);
  701. assert_eq!(next, Some(4096));
  702. // last % RANDOMX_KEY_CHANGING_HEIGHT(2048) < RANDOMX_KEY_CHANGE_DELAY(64)
  703. let (current, next) = get_randomx_vm_keys_heights(4097);
  704. assert_eq!(current, 2048);
  705. assert_eq!(next, Some(4096));
  706. // last % RANDOMX_KEY_CHANGING_HEIGHT(2048) == RANDOMX_KEY_CHANGE_DELAY(64)
  707. let (current, next) = get_randomx_vm_keys_heights(4160);
  708. assert_eq!(current, 4096);
  709. assert!(next.is_none());
  710. // last % RANDOMX_KEY_CHANGING_HEIGHT(2048) > RANDOMX_KEY_CHANGE_DELAY(64)
  711. let (current, next) = get_randomx_vm_keys_heights(4161);
  712. assert_eq!(current, 4096);
  713. assert!(next.is_none());
  714. }
  715. }