mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot
This commit is contained in:
@@ -14,6 +14,6 @@ bitcoin = { workspace = true }
|
||||
bitcoincore-rpc = { workspace = true }
|
||||
brk_error = { workspace = true }
|
||||
brk_logger = { workspace = true }
|
||||
brk_structs = { workspace = true }
|
||||
brk_types = { workspace = true }
|
||||
log = { workspace = true }
|
||||
parking_lot = { workspace = true }
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use std::{mem, sync::Arc, time::Duration};
|
||||
|
||||
use bitcoin::block::Header;
|
||||
use bitcoin::consensus::encode;
|
||||
use bitcoincore_rpc::json::{GetBlockHeaderResult, GetBlockResult, GetTxOutResult};
|
||||
use bitcoincore_rpc::{Client as CoreClient, Error as RpcError, RpcApi};
|
||||
use brk_error::Result;
|
||||
use brk_structs::{BlockHash, Height, Sats, Transaction, TxIn, TxOut, TxStatus, Txid, Vout};
|
||||
use brk_types::{BlockHash, Height, Sats, Transaction, TxIn, TxOut, TxStatus, Txid, Vout};
|
||||
|
||||
pub use bitcoincore_rpc::Auth;
|
||||
|
||||
@@ -63,6 +64,14 @@ impl Client {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn get_block_header<'a, H>(&self, hash: &'a H) -> Result<Header>
|
||||
where
|
||||
&'a H: Into<&'a bitcoin::BlockHash>,
|
||||
{
|
||||
self.call(|c| c.get_block_header(hash.into()))
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn get_block_info<'a, H>(&self, hash: &'a H) -> Result<GetBlockResult>
|
||||
where
|
||||
&'a H: Into<&'a bitcoin::BlockHash>,
|
||||
@@ -187,44 +196,32 @@ impl Client {
|
||||
Ok(block_info.confirmations > 0)
|
||||
}
|
||||
|
||||
pub fn get_closest_valid_height(&self, hash: BlockHash) -> Result<u64> {
|
||||
// First, try to get block info for the hash
|
||||
match self.get_block_info(&hash) {
|
||||
pub fn get_closest_valid_height(&self, hash: BlockHash) -> Result<(Height, BlockHash)> {
|
||||
match self.get_block_header_info(&hash) {
|
||||
Ok(block_info) => {
|
||||
// Check if this block is in the main chain
|
||||
if self.is_in_main_chain(&hash)? {
|
||||
// Block is in the main chain
|
||||
Ok(block_info.height as u64)
|
||||
} else {
|
||||
// Confirmations is -1, meaning it's on a fork
|
||||
// We need to find where it diverged from the main chain
|
||||
return Ok((block_info.height.into(), hash));
|
||||
}
|
||||
|
||||
// Get the previous block hash and walk backwards
|
||||
let mut current_hash = block_info
|
||||
.previousblockhash
|
||||
.map(BlockHash::from)
|
||||
.ok_or("Genesis block has no previous block")?;
|
||||
let mut hash = block_info
|
||||
.previous_block_hash
|
||||
.map(BlockHash::from)
|
||||
.ok_or("Genesis block has no previous block")?;
|
||||
|
||||
loop {
|
||||
if self.is_in_main_chain(¤t_hash)? {
|
||||
// Found a block in the main chain
|
||||
let current_info = self.get_block_header_info(¤t_hash)?;
|
||||
return Ok(current_info.height as u64);
|
||||
}
|
||||
|
||||
// Continue walking backwards
|
||||
let current_info = self.get_block_header_info(¤t_hash)?;
|
||||
current_hash = current_info
|
||||
.previous_block_hash
|
||||
.map(BlockHash::from)
|
||||
.ok_or("Reached genesis without finding main chain")?;
|
||||
loop {
|
||||
if self.is_in_main_chain(&hash)? {
|
||||
let current_info = self.get_block_header_info(&hash)?;
|
||||
return Ok((current_info.height.into(), hash));
|
||||
}
|
||||
|
||||
let info = self.get_block_header_info(&hash)?;
|
||||
hash = info
|
||||
.previous_block_hash
|
||||
.map(BlockHash::from)
|
||||
.ok_or("Reached genesis without finding main chain")?;
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
// Block not found in the node's database at all
|
||||
Err("Block hash not found in blockchain".into())
|
||||
}
|
||||
Err(_) => Err("Block hash not found in blockchain".into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user