1use darkfi_sdk::{
20 crypto::{
21 schnorr::{SchnorrSecret, Signature},
22 MerkleTree, SecretKey,
23 },
24 pasta::{group::ff::FromUniformBytes, pallas},
25 tx::TransactionHash,
26};
27#[cfg(feature = "async-serial")]
28use darkfi_serial::async_trait;
29use darkfi_serial::{deserialize, serialize, SerialDecodable, SerialEncodable};
30use num_bigint::BigUint;
31use sled_overlay::{
32 serial::{parse_record, parse_u32_key_record},
33 sled, SledDbOverlayStateDiff,
34};
35
36use crate::{tx::Transaction, util::time::Timestamp, Error, Result};
37
38use super::{Header, HeaderHash, SledDbOverlayPtr};
39
40#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
46pub struct Block {
47 pub header: HeaderHash,
49 pub txs: Vec<TransactionHash>,
51 pub signature: Signature,
53}
54
55impl Block {
56 pub fn new(header: HeaderHash, txs: Vec<TransactionHash>, signature: Signature) -> Self {
57 Self { header, txs, signature }
58 }
59
60 pub fn hash(&self) -> HeaderHash {
62 self.header
63 }
64
65 pub fn from_block_info(block_info: &BlockInfo) -> Self {
67 let header = block_info.header.hash();
68 let txs = block_info.txs.iter().map(|tx| tx.hash()).collect();
69 let signature = block_info.signature;
70 Self { header, txs, signature }
71 }
72}
73
74#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
80pub struct BlockInfo {
81 pub header: Header,
83 pub txs: Vec<Transaction>,
85 pub signature: Signature,
87}
88
89impl Default for BlockInfo {
90 fn default() -> Self {
92 Self {
93 header: Header::default(),
94 txs: vec![Transaction::default()],
95 signature: Signature::dummy(),
96 }
97 }
98}
99
100impl BlockInfo {
101 pub fn new(header: Header, txs: Vec<Transaction>, signature: Signature) -> Self {
102 Self { header, txs, signature }
103 }
104
105 pub fn new_empty(header: Header) -> Self {
108 let txs = vec![];
109 let signature = Signature::dummy();
110 Self { header, txs, signature }
111 }
112
113 pub fn hash(&self) -> HeaderHash {
115 self.header.hash()
116 }
117
118 pub fn append_tx(&mut self, tx: Transaction) {
122 let mut tree = MerkleTree::new(1);
123 for block_tx in &self.txs {
125 append_tx_to_merkle_tree(&mut tree, block_tx);
126 }
127 append_tx_to_merkle_tree(&mut tree, &tx);
129 self.txs.push(tx);
130 self.header.transactions_root = tree.root(0).unwrap();
132 }
133
134 pub fn append_txs(&mut self, txs: Vec<Transaction>) {
139 let mut tree = MerkleTree::new(1);
140 for block_tx in &self.txs {
142 append_tx_to_merkle_tree(&mut tree, block_tx);
143 }
144 for tx in txs {
146 append_tx_to_merkle_tree(&mut tree, &tx);
147 self.txs.push(tx);
148 }
149 self.header.transactions_root = tree.root(0).unwrap();
151 }
152
153 pub fn sign(&mut self, secret_key: &SecretKey) {
155 self.signature = secret_key.sign(self.hash().inner());
156 }
157}
158
159#[derive(Debug, SerialEncodable, SerialDecodable)]
161pub struct BlockOrder {
162 pub height: u32,
164 pub block: HeaderHash,
166}
167
168#[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
174pub struct BlockRanks {
175 pub target_rank: BigUint,
177 pub targets_rank: BigUint,
179 pub hash_rank: BigUint,
181 pub hashes_rank: BigUint,
183}
184
185impl BlockRanks {
186 pub fn new(
187 target_rank: BigUint,
188 targets_rank: BigUint,
189 hash_rank: BigUint,
190 hashes_rank: BigUint,
191 ) -> Self {
192 Self { target_rank, targets_rank, hash_rank, hashes_rank }
193 }
194}
195
196#[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
202pub struct BlockDifficulty {
203 pub height: u32,
205 pub timestamp: Timestamp,
207 pub difficulty: BigUint,
209 pub cumulative_difficulty: BigUint,
211 pub ranks: BlockRanks,
213}
214
215impl BlockDifficulty {
216 pub fn new(
217 height: u32,
218 timestamp: Timestamp,
219 difficulty: BigUint,
220 cumulative_difficulty: BigUint,
221 ranks: BlockRanks,
222 ) -> Self {
223 Self { height, timestamp, difficulty, cumulative_difficulty, ranks }
224 }
225
226 pub fn genesis(timestamp: Timestamp) -> Self {
228 let ranks = BlockRanks::new(
229 BigUint::from(0u64),
230 BigUint::from(0u64),
231 BigUint::from(0u64),
232 BigUint::from(0u64),
233 );
234 BlockDifficulty::new(0u32, timestamp, BigUint::from(0u64), BigUint::from(0u64), ranks)
235 }
236}
237
238pub const SLED_BLOCK_TREE: &[u8] = b"_blocks";
239pub const SLED_BLOCK_ORDER_TREE: &[u8] = b"_block_order";
240pub const SLED_BLOCK_DIFFICULTY_TREE: &[u8] = b"_block_difficulty";
241pub const SLED_BLOCK_STATE_INVERSE_DIFF_TREE: &[u8] = b"_block_state_inverse_diff";
242
243#[derive(Clone)]
246pub struct BlockStore {
247 pub main: sled::Tree,
250 pub order: sled::Tree,
254 pub difficulty: sled::Tree,
258 pub state_inverse_diff: sled::Tree,
262}
263
264impl BlockStore {
265 pub fn new(db: &sled::Db) -> Result<Self> {
267 let main = db.open_tree(SLED_BLOCK_TREE)?;
268 let order = db.open_tree(SLED_BLOCK_ORDER_TREE)?;
269 let difficulty = db.open_tree(SLED_BLOCK_DIFFICULTY_TREE)?;
270 let state_inverse_diff = db.open_tree(SLED_BLOCK_STATE_INVERSE_DIFF_TREE)?;
271 Ok(Self { main, order, difficulty, state_inverse_diff })
272 }
273
274 pub fn insert(&self, blocks: &[Block]) -> Result<Vec<HeaderHash>> {
276 let (batch, ret) = self.insert_batch(blocks);
277 self.main.apply_batch(batch)?;
278 Ok(ret)
279 }
280
281 pub fn insert_order(&self, heights: &[u32], hashes: &[HeaderHash]) -> Result<()> {
284 let batch = self.insert_batch_order(heights, hashes);
285 self.order.apply_batch(batch)?;
286 Ok(())
287 }
288
289 pub fn insert_difficulty(&self, block_difficulties: &[BlockDifficulty]) -> Result<()> {
292 let batch = self.insert_batch_difficulty(block_difficulties);
293 self.difficulty.apply_batch(batch)?;
294 Ok(())
295 }
296
297 pub fn insert_state_inverse_diff(
300 &self,
301 heights: &[u32],
302 diffs: &[SledDbOverlayStateDiff],
303 ) -> Result<()> {
304 let batch = self.insert_batch_state_inverse_diff(heights, diffs);
305 self.state_inverse_diff.apply_batch(batch)?;
306 Ok(())
307 }
308
309 pub fn insert_batch(&self, blocks: &[Block]) -> (sled::Batch, Vec<HeaderHash>) {
315 let mut ret = Vec::with_capacity(blocks.len());
316 let mut batch = sled::Batch::default();
317
318 for block in blocks {
319 let blockhash = block.hash();
320 batch.insert(blockhash.inner(), serialize(block));
321 ret.push(blockhash);
322 }
323
324 (batch, ret)
325 }
326
327 pub fn insert_batch_order(&self, heights: &[u32], hashes: &[HeaderHash]) -> sled::Batch {
331 let mut batch = sled::Batch::default();
332
333 for (i, height) in heights.iter().enumerate() {
334 batch.insert(&height.to_be_bytes(), hashes[i].inner());
335 }
336
337 batch
338 }
339
340 pub fn insert_batch_difficulty(&self, block_difficulties: &[BlockDifficulty]) -> sled::Batch {
345 let mut batch = sled::Batch::default();
346
347 for block_difficulty in block_difficulties {
348 batch.insert(&block_difficulty.height.to_be_bytes(), serialize(block_difficulty));
349 }
350
351 batch
352 }
353
354 pub fn insert_batch_state_inverse_diff(
359 &self,
360 heights: &[u32],
361 diffs: &[SledDbOverlayStateDiff],
362 ) -> sled::Batch {
363 let mut batch = sled::Batch::default();
364
365 for (i, height) in heights.iter().enumerate() {
366 batch.insert(&height.to_be_bytes(), serialize(&diffs[i]));
367 }
368
369 batch
370 }
371
372 pub fn contains(&self, blockhash: &HeaderHash) -> Result<bool> {
374 Ok(self.main.contains_key(blockhash.inner())?)
375 }
376
377 pub fn contains_order(&self, height: u32) -> Result<bool> {
379 Ok(self.order.contains_key(height.to_be_bytes())?)
380 }
381
382 pub fn get(&self, block_hashes: &[HeaderHash], strict: bool) -> Result<Vec<Option<Block>>> {
388 let mut ret = Vec::with_capacity(block_hashes.len());
389
390 for hash in block_hashes {
391 if let Some(found) = self.main.get(hash.inner())? {
392 let block = deserialize(&found)?;
393 ret.push(Some(block));
394 continue
395 }
396 if strict {
397 return Err(Error::BlockNotFound(hash.as_string()))
398 }
399 ret.push(None);
400 }
401
402 Ok(ret)
403 }
404
405 pub fn get_order(&self, heights: &[u32], strict: bool) -> Result<Vec<Option<HeaderHash>>> {
411 let mut ret = Vec::with_capacity(heights.len());
412
413 for height in heights {
414 if let Some(found) = self.order.get(height.to_be_bytes())? {
415 let block_hash = deserialize(&found)?;
416 ret.push(Some(block_hash));
417 continue
418 }
419 if strict {
420 return Err(Error::BlockHeightNotFound(*height))
421 }
422 ret.push(None);
423 }
424
425 Ok(ret)
426 }
427
428 pub fn get_difficulty(
435 &self,
436 heights: &[u32],
437 strict: bool,
438 ) -> Result<Vec<Option<BlockDifficulty>>> {
439 let mut ret = Vec::with_capacity(heights.len());
440
441 for height in heights {
442 if let Some(found) = self.difficulty.get(height.to_be_bytes())? {
443 let block_difficulty = deserialize(&found)?;
444 ret.push(Some(block_difficulty));
445 continue
446 }
447 if strict {
448 return Err(Error::BlockDifficultyNotFound(*height))
449 }
450 ret.push(None);
451 }
452
453 Ok(ret)
454 }
455
456 pub fn get_state_inverse_diff(
463 &self,
464 heights: &[u32],
465 strict: bool,
466 ) -> Result<Vec<Option<SledDbOverlayStateDiff>>> {
467 let mut ret = Vec::with_capacity(heights.len());
468
469 for height in heights {
470 if let Some(found) = self.state_inverse_diff.get(height.to_be_bytes())? {
471 let state_inverse_diff = deserialize(&found)?;
472 ret.push(Some(state_inverse_diff));
473 continue
474 }
475 if strict {
476 return Err(Error::BlockStateInverseDiffNotFound(*height))
477 }
478 ret.push(None);
479 }
480
481 Ok(ret)
482 }
483
484 pub fn get_all(&self) -> Result<Vec<(HeaderHash, Block)>> {
488 let mut blocks = vec![];
489
490 for block in self.main.iter() {
491 blocks.push(parse_record(block.unwrap())?);
492 }
493
494 Ok(blocks)
495 }
496
497 pub fn get_all_order(&self) -> Result<Vec<(u32, HeaderHash)>> {
501 let mut order = vec![];
502
503 for record in self.order.iter() {
504 order.push(parse_u32_key_record(record.unwrap())?);
505 }
506
507 Ok(order)
508 }
509
510 pub fn get_order_by_range(&self, start: u32, end: u32) -> Result<Vec<(u32, HeaderHash)>> {
513 if start >= end {
514 return Err(Error::DatabaseError(format!("Heights range is invalid: {start}..{end}")))
515 }
516
517 let mut blocks = vec![];
518
519 let start_key = start.to_be_bytes();
520 let end_key = end.to_be_bytes();
521
522 for block in self.order.range(start_key..=end_key) {
523 blocks.push(parse_u32_key_record(block.unwrap())?);
524 }
525
526 Ok(blocks)
527 }
528
529 pub fn get_all_difficulty(&self) -> Result<Vec<(u32, BlockDifficulty)>> {
533 let mut block_difficulties = vec![];
534
535 for record in self.difficulty.iter() {
536 block_difficulties.push(parse_u32_key_record(record.unwrap())?);
537 }
538
539 Ok(block_difficulties)
540 }
541
542 pub fn get_before(&self, height: u32, n: usize) -> Result<Vec<HeaderHash>> {
546 let mut ret = vec![];
547
548 let mut key = height;
549 let mut counter = 0;
550 while counter < n {
551 let record = self.order.get_lt(key.to_be_bytes())?;
552 if record.is_none() {
553 break
554 }
555 let (height, hash) = parse_u32_key_record(record.unwrap())?;
558 key = height;
559 ret.insert(0, hash);
560 counter += 1;
561 }
562
563 Ok(ret)
564 }
565
566 pub fn get_all_after(&self, height: u32) -> Result<Vec<HeaderHash>> {
570 let mut ret = vec![];
571
572 let mut key = height;
573 while let Some(found) = self.order.get_gt(key.to_be_bytes())? {
574 let (height, hash) = parse_u32_key_record(found)?;
575 key = height;
576 ret.push(hash);
577 }
578
579 Ok(ret)
580 }
581
582 pub fn get_first(&self) -> Result<(u32, HeaderHash)> {
585 let Some(found) = self.order.first()? else { return Err(Error::BlockHeightNotFound(0u32)) };
586 let (height, hash) = parse_u32_key_record(found)?;
587
588 Ok((height, hash))
589 }
590
591 pub fn get_last(&self) -> Result<(u32, HeaderHash)> {
594 let found = self.order.last()?.unwrap();
595 let (height, hash) = parse_u32_key_record(found)?;
596
597 Ok((height, hash))
598 }
599
600 pub fn get_last_n_orders(&self, n: usize) -> Result<Vec<(u32, HeaderHash)>> {
602 let records = self.order.iter().rev().take(n);
604
605 let mut last_n = vec![];
608 for record in records {
609 let record = record?;
610 let parsed_record = parse_u32_key_record(record)?;
611 last_n.insert(0, parsed_record);
612 }
613 Ok(last_n)
614 }
615
616 pub fn get_last_difficulty(&self) -> Result<Option<BlockDifficulty>> {
620 let Some(found) = self.difficulty.last()? else { return Ok(None) };
621 let block_difficulty = deserialize(&found.1)?;
622 Ok(Some(block_difficulty))
623 }
624
625 pub fn get_last_n_difficulties(&self, n: usize) -> Result<Vec<BlockDifficulty>> {
627 let records = self.difficulty.iter().rev().take(n);
629 let mut last_n = vec![];
632 for record in records {
633 last_n.insert(0, deserialize(&record?.1)?);
634 }
635
636 Ok(last_n)
637 }
638
639 pub fn get_difficulties_before(&self, height: u32, n: usize) -> Result<Vec<BlockDifficulty>> {
643 let mut ret = vec![];
644
645 let mut key = height;
646 let mut counter = 0;
647 while counter < n {
648 let record = self.difficulty.get_lt(key.to_be_bytes())?;
649 if record.is_none() {
650 break
651 }
652 let (height, difficulty) = parse_u32_key_record(record.unwrap())?;
655 key = height;
656 ret.insert(0, difficulty);
657 counter += 1;
658 }
659
660 Ok(ret)
661 }
662
663 pub fn get_state_inverse_diffs_after(
668 &self,
669 height: u32,
670 ) -> Result<Vec<SledDbOverlayStateDiff>> {
671 let mut ret = vec![];
672
673 let mut key = height;
674 while let Some(found) = self.state_inverse_diff.get_gt(key.to_be_bytes())? {
675 let (height, state_inverse_diff) = parse_u32_key_record(found)?;
676 key = height;
677 ret.push(state_inverse_diff);
678 }
679
680 Ok(ret)
681 }
682
683 pub fn len(&self) -> usize {
685 self.order.len()
686 }
687
688 pub fn is_empty(&self) -> bool {
690 self.order.is_empty()
691 }
692}
693
694pub struct BlockStoreOverlay(SledDbOverlayPtr);
696
697impl BlockStoreOverlay {
698 pub fn new(overlay: &SledDbOverlayPtr) -> Result<Self> {
699 overlay.lock().unwrap().open_tree(SLED_BLOCK_TREE, true)?;
700 overlay.lock().unwrap().open_tree(SLED_BLOCK_ORDER_TREE, true)?;
701 overlay.lock().unwrap().open_tree(SLED_BLOCK_DIFFICULTY_TREE, true)?;
702 overlay.lock().unwrap().open_tree(SLED_BLOCK_STATE_INVERSE_DIFF_TREE, true)?;
703 Ok(Self(overlay.clone()))
704 }
705
706 pub fn insert(&self, blocks: &[Block]) -> Result<Vec<HeaderHash>> {
711 let mut ret = Vec::with_capacity(blocks.len());
712 let mut lock = self.0.lock().unwrap();
713
714 for block in blocks {
715 let blockhash = block.hash();
716 lock.insert(SLED_BLOCK_TREE, blockhash.inner(), &serialize(block))?;
717 ret.push(blockhash);
718 }
719
720 Ok(ret)
721 }
722
723 pub fn insert_order(&self, heights: &[u32], hashes: &[HeaderHash]) -> Result<()> {
726 if heights.len() != hashes.len() {
727 return Err(Error::InvalidInputLengths)
728 }
729
730 let mut lock = self.0.lock().unwrap();
731
732 for (i, height) in heights.iter().enumerate() {
733 lock.insert(SLED_BLOCK_ORDER_TREE, &height.to_be_bytes(), hashes[i].inner())?;
734 }
735
736 Ok(())
737 }
738
739 pub fn insert_difficulty(&self, block_difficulties: &[BlockDifficulty]) -> Result<()> {
741 let mut lock = self.0.lock().unwrap();
742
743 for block_difficulty in block_difficulties {
744 lock.insert(
745 SLED_BLOCK_DIFFICULTY_TREE,
746 &block_difficulty.height.to_be_bytes(),
747 &serialize(block_difficulty),
748 )?;
749 }
750
751 Ok(())
752 }
753
754 pub fn get(&self, block_hashes: &[HeaderHash], strict: bool) -> Result<Vec<Option<Block>>> {
760 let mut ret = Vec::with_capacity(block_hashes.len());
761 let lock = self.0.lock().unwrap();
762
763 for hash in block_hashes {
764 if let Some(found) = lock.get(SLED_BLOCK_TREE, hash.inner())? {
765 let block = deserialize(&found)?;
766 ret.push(Some(block));
767 continue
768 }
769 if strict {
770 return Err(Error::BlockNotFound(hash.as_string()))
771 }
772 ret.push(None);
773 }
774
775 Ok(ret)
776 }
777
778 pub fn get_order(&self, heights: &[u32], strict: bool) -> Result<Vec<Option<HeaderHash>>> {
784 let mut ret = Vec::with_capacity(heights.len());
785 let lock = self.0.lock().unwrap();
786
787 for height in heights {
788 if let Some(found) = lock.get(SLED_BLOCK_ORDER_TREE, &height.to_be_bytes())? {
789 let block_hash = deserialize(&found)?;
790 ret.push(Some(block_hash));
791 continue
792 }
793 if strict {
794 return Err(Error::BlockHeightNotFound(*height))
795 }
796 ret.push(None);
797 }
798
799 Ok(ret)
800 }
801
802 pub fn get_last(&self) -> Result<(u32, HeaderHash)> {
805 let found = match self.0.lock().unwrap().last(SLED_BLOCK_ORDER_TREE)? {
806 Some(b) => b,
807 None => return Err(Error::BlockHeightNotFound(0u32)),
808 };
809 let (height, hash) = parse_u32_key_record(found)?;
810
811 Ok((height, hash))
812 }
813
814 pub fn is_empty(&self) -> Result<bool> {
816 Ok(self.0.lock().unwrap().is_empty(SLED_BLOCK_ORDER_TREE)?)
817 }
818}
819
820pub fn append_tx_to_merkle_tree(tree: &mut MerkleTree, tx: &Transaction) {
822 let mut buf = [0u8; 64];
823 buf[..32].copy_from_slice(tx.hash().inner());
824 let leaf = pallas::Base::from_uniform_bytes(&buf);
825 tree.append(leaf.into());
826}