From 1c82ab0c0b98819a47cb3fc4e9561528cfdcdb29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ceyhun=20=C5=9Een?= Date: Thu, 7 Nov 2024 11:36:49 +0700 Subject: [PATCH] blocks: Add get_chain_tips. --- src/client/rpc_api.rs | 21 ++++++++++++++++++++- src/ledger/block.rs | 22 ++++++++++++++++++++-- src/ledger/mod.rs | 4 ++-- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/client/rpc_api.rs b/src/client/rpc_api.rs index 8677174..2984216 100644 --- a/src/client/rpc_api.rs +++ b/src/client/rpc_api.rs @@ -17,7 +17,7 @@ use bitcoin::{ }; use bitcoincore_rpc::{ json::{ - self, GetRawTransactionResult, GetRawTransactionResultVin, + self, GetChainTipsResultStatus, GetRawTransactionResult, GetRawTransactionResultVin, GetRawTransactionResultVinScriptSig, GetRawTransactionResultVout, GetRawTransactionResultVoutScriptPubKey, GetTransactionResult, GetTransactionResultDetail, GetTransactionResultDetailCategory, GetTxOutResult, SignRawTransactionResult, WalletTxInfo, @@ -609,6 +609,25 @@ impl RpcApi for Client { errors: None, }) } + + #[tracing::instrument(skip_all)] + fn get_chain_tips(&self) -> bitcoincore_rpc::Result { + let height = self.ledger.get_block_height().unwrap(); + let hash = if height == 0 { + BlockHash::all_zeros() + } else { + self.ledger.get_block_with_height(height)?.block_hash() + }; + + let tip = json::GetChainTipsResultTip { + height: height as u64, + hash, + branch_length: height as usize, + status: GetChainTipsResultStatus::Active, + }; + + Ok(vec![tip]) + } } #[cfg(test)] diff --git a/src/ledger/block.rs b/src/ledger/block.rs index 46c2ae3..6017ff9 100644 --- a/src/ledger/block.rs +++ b/src/ledger/block.rs @@ -6,7 +6,7 @@ use crate::utils; use bitcoin::block::{Header, Version}; use bitcoin::consensus::{Decodable, Encodable}; use bitcoin::hashes::Hash; -use bitcoin::{Address, Block, BlockHash, CompactTarget, Transaction, Txid}; +use bitcoin::{Address, Block, BlockHash, CompactTarget, Transaction, TxMerkleNode, Txid}; use rusqlite::params; use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; @@ -163,10 +163,28 @@ impl Ledger { let mut encoded_hash: Vec = Vec::new(); hash.consensus_encode(&mut encoded_hash).unwrap(); + // Handle genesis block. + if hash == BlockHash::all_zeros() { + return Ok(Block { + header: Header { + version: Version::TWO, + prev_blockhash: BlockHash::all_zeros(), + merkle_root: TxMerkleNode::all_zeros(), + time: 0, + bits: CompactTarget::default(), + nonce: 0, + }, + txdata: vec![], + }); + } + let qr = match self.database.lock().unwrap().query_row( "SELECT body FROM blocks WHERE hash = ?1", params![encoded_hash], - |row| Ok(row.get::<_, Vec>(0).unwrap()), + |row| { + tracing::error!("row {:?}", row); + Ok(row.get::<_, Vec>(0).unwrap()) + }, ) { Ok(qr) => qr, Err(e) => { diff --git a/src/ledger/mod.rs b/src/ledger/mod.rs index 4b0120b..5867ff5 100644 --- a/src/ledger/mod.rs +++ b/src/ledger/mod.rs @@ -125,13 +125,13 @@ impl Ledger { ( height INTEGER NOT NULL, time INTEGER NOT NULL, - hash BLOB NOT NULL, + hash TEXT NOT NULL, coinbase TEXT NOT NULL, body BLOB NOT NULL CONSTRAINT height PRIMARY KEY ); - INSERT INTO blocks (height, time, hash, coinbase, body) VALUES (0, 500000000, 0, 0, 0); + INSERT INTO blocks (height, time, hash, coinbase, body) VALUES (0, 500000000, '00000000000000000000', 0, 0); CREATE TABLE mempool (