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 1/3] 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 ( From 3dca4f61fdfcfc217a70da4c7e727f6f9e1eb854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ceyhun=20=C5=9Een?= Date: Thu, 7 Nov 2024 11:40:35 +0700 Subject: [PATCH 2/3] block: Add get_block_hash. --- src/client/rpc_api.rs | 5 +++++ src/ledger/block.rs | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/client/rpc_api.rs b/src/client/rpc_api.rs index 2984216..3b8024b 100644 --- a/src/client/rpc_api.rs +++ b/src/client/rpc_api.rs @@ -628,6 +628,11 @@ impl RpcApi for Client { Ok(vec![tip]) } + + #[tracing::instrument(skip_all)] + fn get_block_hash(&self, height: u64) -> bitcoincore_rpc::Result { + Ok(self.ledger.get_block_with_height(height as u32)?.block_hash()) + } } #[cfg(test)] diff --git a/src/ledger/block.rs b/src/ledger/block.rs index 6017ff9..19eea9e 100644 --- a/src/ledger/block.rs +++ b/src/ledger/block.rs @@ -182,7 +182,6 @@ impl Ledger { "SELECT body FROM blocks WHERE hash = ?1", params![encoded_hash], |row| { - tracing::error!("row {:?}", row); Ok(row.get::<_, Vec>(0).unwrap()) }, ) { From c16c241dcca0caf59637eb4f4def99e0afc80e37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ceyhun=20=C5=9Een?= Date: Thu, 7 Nov 2024 11:43:42 +0700 Subject: [PATCH 3/3] Fmt and lint. --- src/client/rpc_api.rs | 5 ++++- src/ledger/block.rs | 9 ++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/client/rpc_api.rs b/src/client/rpc_api.rs index 3b8024b..1838431 100644 --- a/src/client/rpc_api.rs +++ b/src/client/rpc_api.rs @@ -631,7 +631,10 @@ impl RpcApi for Client { #[tracing::instrument(skip_all)] fn get_block_hash(&self, height: u64) -> bitcoincore_rpc::Result { - Ok(self.ledger.get_block_with_height(height as u32)?.block_hash()) + Ok(self + .ledger + .get_block_with_height(height as u32)? + .block_hash()) } } diff --git a/src/ledger/block.rs b/src/ledger/block.rs index 19eea9e..56411c5 100644 --- a/src/ledger/block.rs +++ b/src/ledger/block.rs @@ -145,10 +145,7 @@ impl Ledger { } }; // Genesis block will also return a database error. Ignore that. - let body = match body { - Ok(b) => b, - Err(_) => Vec::new(), - }; + let body = body.unwrap_or_default(); match Block::consensus_decode(&mut body.as_slice()) { Ok(block) => Ok(block), @@ -181,9 +178,7 @@ impl Ledger { 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| Ok(row.get::<_, Vec>(0).unwrap()), ) { Ok(qr) => qr, Err(e) => {