Selaa lähdekoodia

blockchain: enhancements to block store access

This commit extends the capabilities of the block store by introducing the following functionalities:

HeaderHash Retrieval:
- retrieval of header hashes within a specified range of height
- retrieval of the last N header hashes from the stored blocks

BlockInfo Retrieval:
- retrieval of BlockInfo records for given heights
- retrieval of the last N BlockInfo records
- retrieval of BlockInfo records within a specified range of heights

These enhancements provide more versatile access and manipulation of stored blocks, enhancing overall block management and retrieval.
kalm 1 vuosi sitten
vanhempi
sitoutus
a1583381df
2 muutettua tiedostoa jossa 61 lisäystä ja 0 poistoa
  1. 38 0
      src/blockchain/block_store.rs
  2. 23 0
      src/blockchain/mod.rs

+ 38 - 0
src/blockchain/block_store.rs

@@ -504,6 +504,28 @@ impl BlockStore {
         Ok(order)
     }
 
+    /// Fetches the blocks within a specified range of height from the store's order tree
+    /// returning a collection of block heights with their associated [`HeaderHash`]s.
+    pub fn get_order_by_range(&self, start: u32, end: u32) -> Result<Vec<(u32, HeaderHash)>> {
+        if start >= end {
+            return Err(Error::DatabaseError(format!(
+                "Heights range is invalid: {}..{}",
+                start, end
+            )))
+        }
+
+        let mut blocks = vec![];
+
+        let start_key = start.to_be_bytes();
+        let end_key = end.to_be_bytes();
+
+        for block in self.order.range(start_key..end_key) {
+            blocks.push(parse_u32_key_record(block.unwrap())?);
+        }
+
+        Ok(blocks)
+    }
+
     /// Retrieve all block difficulties from the store's difficulty tree in
     /// the form of a vector containing (`height`, `difficulty`) tuples.
     /// Be careful as this will try to load everything in memory.
@@ -573,6 +595,22 @@ impl BlockStore {
         Ok((height, hash))
     }
 
+    /// Fetch the last N records from order tree
+    pub fn get_last_n_orders(&self, n: usize) -> Result<Vec<(u32, HeaderHash)>> {
+        // Build an iterator to retrieve last N records
+        let records = self.order.iter().rev().take(n);
+
+        // Since the iterator grabs in right -> left order,
+        // we deserialize found records, and push them in reverse order
+        let mut last_n = vec![];
+        for record in records {
+            let record = record?;
+            let parsed_record = parse_u32_key_record(record)?;
+            last_n.insert(0, parsed_record);
+        }
+        Ok(last_n)
+    }
+
     /// Fetch the last record in the difficulty tree, based on the `Ord`
     /// implementation for `Vec<u8>`. If the tree is empty,
     /// returns `None`.

+ 23 - 0
src/blockchain/mod.rs

@@ -333,6 +333,29 @@ impl Blockchain {
         Ok(blocks)
     }
 
+    /// Retrieve [`BlockInfo`]s by given heights range.
+    pub fn get_by_range(&self, start: u32, end: u32) -> Result<Vec<BlockInfo>> {
+        let blockhashes = self.blocks.get_order_by_range(start, end)?;
+        let hashes: Vec<HeaderHash> = blockhashes.into_iter().map(|(_, hash)| hash).collect();
+        self.get_blocks_by_hash(&hashes)
+    }
+
+    /// Retrieve last 'N' [`BlockInfo`]s from the blockchain.
+    pub fn get_last_n(&self, n: usize) -> Result<Vec<BlockInfo>> {
+        let records = self.blocks.get_last_n_orders(n)?;
+
+        let mut last_n = vec![];
+        for record in records {
+            let header_hash = record.1;
+            let blocks = self.get_blocks_by_hash(&[header_hash])?;
+            for block in blocks {
+                last_n.push(block.clone());
+            }
+        }
+
+        Ok(last_n)
+    }
+
     /// Auxiliary function to reset the blockchain and consensus state
     /// to the provided block height.
     pub fn reset_to_height(&self, height: u32) -> Result<()> {