global: snapshot

This commit is contained in:
nym21
2025-10-23 18:30:29 +02:00
parent 6cd60a064b
commit 4f1653b086
234 changed files with 758 additions and 722 deletions

View File

@@ -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 }

View File

@@ -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(&current_hash)? {
// Found a block in the main chain
let current_info = self.get_block_header_info(&current_hash)?;
return Ok(current_info.height as u64);
}
// Continue walking backwards
let current_info = self.get_block_header_info(&current_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()),
}
}