Skip to content

Commit

Permalink
Merge pull request #66 from chainwayxyz/block_functions
Browse files Browse the repository at this point in the history
Add get_chain_tips and get_block_hash block functions
  • Loading branch information
ceyhunsen authored Nov 7, 2024
2 parents d1dd0af + c16c241 commit bf21d04
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 8 deletions.
29 changes: 28 additions & 1 deletion src/client/rpc_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -609,6 +609,33 @@ impl RpcApi for Client {
errors: None,
})
}

#[tracing::instrument(skip_all)]
fn get_chain_tips(&self) -> bitcoincore_rpc::Result<json::GetChainTipsResult> {
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])
}

#[tracing::instrument(skip_all)]
fn get_block_hash(&self, height: u64) -> bitcoincore_rpc::Result<bitcoin::BlockHash> {
Ok(self
.ledger
.get_block_with_height(height as u32)?
.block_hash())
}
}

#[cfg(test)]
Expand Down
22 changes: 17 additions & 5 deletions src/ledger/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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),
Expand All @@ -163,6 +160,21 @@ impl Ledger {
let mut encoded_hash: Vec<u8> = 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],
Expand Down
4 changes: 2 additions & 2 deletions src/ledger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
(
Expand Down

0 comments on commit bf21d04

Please sign in to comment.