Skip to content

Commit bf21d04

Browse files
authored
Merge pull request #66 from chainwayxyz/block_functions
Add get_chain_tips and get_block_hash block functions
2 parents d1dd0af + c16c241 commit bf21d04

File tree

3 files changed

+47
-8
lines changed

3 files changed

+47
-8
lines changed

src/client/rpc_api.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use bitcoin::{
1717
};
1818
use bitcoincore_rpc::{
1919
json::{
20-
self, GetRawTransactionResult, GetRawTransactionResultVin,
20+
self, GetChainTipsResultStatus, GetRawTransactionResult, GetRawTransactionResultVin,
2121
GetRawTransactionResultVinScriptSig, GetRawTransactionResultVout,
2222
GetRawTransactionResultVoutScriptPubKey, GetTransactionResult, GetTransactionResultDetail,
2323
GetTransactionResultDetailCategory, GetTxOutResult, SignRawTransactionResult, WalletTxInfo,
@@ -609,6 +609,33 @@ impl RpcApi for Client {
609609
errors: None,
610610
})
611611
}
612+
613+
#[tracing::instrument(skip_all)]
614+
fn get_chain_tips(&self) -> bitcoincore_rpc::Result<json::GetChainTipsResult> {
615+
let height = self.ledger.get_block_height().unwrap();
616+
let hash = if height == 0 {
617+
BlockHash::all_zeros()
618+
} else {
619+
self.ledger.get_block_with_height(height)?.block_hash()
620+
};
621+
622+
let tip = json::GetChainTipsResultTip {
623+
height: height as u64,
624+
hash,
625+
branch_length: height as usize,
626+
status: GetChainTipsResultStatus::Active,
627+
};
628+
629+
Ok(vec![tip])
630+
}
631+
632+
#[tracing::instrument(skip_all)]
633+
fn get_block_hash(&self, height: u64) -> bitcoincore_rpc::Result<bitcoin::BlockHash> {
634+
Ok(self
635+
.ledger
636+
.get_block_with_height(height as u32)?
637+
.block_hash())
638+
}
612639
}
613640

614641
#[cfg(test)]

src/ledger/block.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::utils;
66
use bitcoin::block::{Header, Version};
77
use bitcoin::consensus::{Decodable, Encodable};
88
use bitcoin::hashes::Hash;
9-
use bitcoin::{Address, Block, BlockHash, CompactTarget, Transaction, Txid};
9+
use bitcoin::{Address, Block, BlockHash, CompactTarget, Transaction, TxMerkleNode, Txid};
1010
use rusqlite::params;
1111
use std::str::FromStr;
1212
use std::time::{SystemTime, UNIX_EPOCH};
@@ -145,10 +145,7 @@ impl Ledger {
145145
}
146146
};
147147
// Genesis block will also return a database error. Ignore that.
148-
let body = match body {
149-
Ok(b) => b,
150-
Err(_) => Vec::new(),
151-
};
148+
let body = body.unwrap_or_default();
152149

153150
match Block::consensus_decode(&mut body.as_slice()) {
154151
Ok(block) => Ok(block),
@@ -163,6 +160,21 @@ impl Ledger {
163160
let mut encoded_hash: Vec<u8> = Vec::new();
164161
hash.consensus_encode(&mut encoded_hash).unwrap();
165162

163+
// Handle genesis block.
164+
if hash == BlockHash::all_zeros() {
165+
return Ok(Block {
166+
header: Header {
167+
version: Version::TWO,
168+
prev_blockhash: BlockHash::all_zeros(),
169+
merkle_root: TxMerkleNode::all_zeros(),
170+
time: 0,
171+
bits: CompactTarget::default(),
172+
nonce: 0,
173+
},
174+
txdata: vec![],
175+
});
176+
}
177+
166178
let qr = match self.database.lock().unwrap().query_row(
167179
"SELECT body FROM blocks WHERE hash = ?1",
168180
params![encoded_hash],

src/ledger/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,13 @@ impl Ledger {
125125
(
126126
height INTEGER NOT NULL,
127127
time INTEGER NOT NULL,
128-
hash BLOB NOT NULL,
128+
hash TEXT NOT NULL,
129129
coinbase TEXT NOT NULL,
130130
body BLOB NOT NULL
131131
132132
CONSTRAINT height PRIMARY KEY
133133
);
134-
INSERT INTO blocks (height, time, hash, coinbase, body) VALUES (0, 500000000, 0, 0, 0);
134+
INSERT INTO blocks (height, time, hash, coinbase, body) VALUES (0, 500000000, '00000000000000000000', 0, 0);
135135
136136
CREATE TABLE mempool
137137
(

0 commit comments

Comments
 (0)