Struct bitcoin_explorer::BitcoinDB
source · pub struct BitcoinDB(_);
Expand description
This is the main struct of this crate!! Click and read the doc.
All queries start from initializing BitcoinDB
.
Note: This is an Arc wrap around InnerDB
.
Implementations§
source§impl BitcoinDB
impl BitcoinDB
sourcepub fn get_connected_block<T: ConnectedBlock>(
&self,
height: usize
) -> OpResult<T>
pub fn get_connected_block<T: ConnectedBlock>( &self, height: usize ) -> OpResult<T>
Get a block with inputs replaced by connected outputs.
This function requires txindex
to be set to true
for BitcoinDB
,
and requires that flag txindex=1
has been enabled when
running Bitcoin Core.
A transaction cannot be found using this function if it is
not yet indexed using txindex
.
Caveat!!
Performance Warning
Slow! For massive computation, use db.iter_connected_block()
.
sourcepub fn get_connected_transaction<T: ConnectedTx>(
&self,
txid: &Txid
) -> OpResult<T>
pub fn get_connected_transaction<T: ConnectedTx>( &self, txid: &Txid ) -> OpResult<T>
Get a transaction with outpoints replaced by outputs.
This function requires txindex
to be set to true
for BitcoinDB
,
and requires that flag txindex=1
has been enabled when
running Bitcoin Core.
A transaction cannot be found using this function if it is
not yet indexed using txindex
.
Format: full (FConnectedTransaction)
/ simple (SConnectedTransaction)
.
Caveats
Performance Warning
Slow! For massive computation, use db.iter_connected_block()
.
sourcepub fn iter_connected_block<TBlock>(
&self,
end: usize
) -> ConnectedBlockIter<TBlock> ⓘwhere
TBlock: 'static + ConnectedBlock + Send,
pub fn iter_connected_block<TBlock>( &self, end: usize ) -> ConnectedBlockIter<TBlock> ⓘwhere TBlock: 'static + ConnectedBlock + Send,
Iterate through all blocks for a given heights (excluded).
Format: full (FConnectedBlock)
/ simple (SConnectedBlock)
.
This iterator use unspent output
to track down the connected
outputs of each outpoints.
Note
This does NOT require txindex=true
.
Performance
Using default feature:
Requires 4 GB memory, finishes in 2.5 hours from 0-70000 block.
Using non-default feature
Requires 32 GB memory, finished in 30 minutes from 0-70000 block.
Example
use bitcoin_explorer::{BitcoinDB, FConnectedBlock, SConnectedBlock};
use std::path::Path;
let path = Path::new("/Users/me/bitcoin");
// launch without reading txindex
let db = BitcoinDB::new(path, false).unwrap();
// iterate over block from 0 to 700000, (simple format)
for block in db.iter_connected_block::<SConnectedBlock>(700000) {
for tx in block.txdata {
println!("do something for this transaction");
}
}
source§impl BitcoinDB
impl BitcoinDB
sourcepub fn new(p: &Path, tx_index: bool) -> OpResult<BitcoinDB>
pub fn new(p: &Path, tx_index: bool) -> OpResult<BitcoinDB>
This is the main structure for reading Bitcoin blockchain data.
Instantiating this class by passing the -datadir
directory of
Bitcoin core to the new()
method.
tx_index
: whether to try to open tx_index levelDB.
Example
use bitcoin_explorer::BitcoinDB;
use std::path::Path;
let path = Path::new("/Users/me/bitcoin");
// launch without reading txindex
let db = BitcoinDB::new(path, false).unwrap();
// launch attempting to read txindex
let db = BitcoinDB::new(path, true).unwrap();
sourcepub fn get_max_height(&self) -> usize
👎Deprecated since 1.2.6: use get_block_count()
instead
pub fn get_max_height(&self) -> usize
get_block_count()
insteadGet the maximum height found in block index.
Note, not all blocks lower than this height have
been downloaded (different from get_block_count()
).
Deprecated: use get_block_count()
sourcepub fn get_block_count(&self) -> usize
pub fn get_block_count(&self) -> usize
Get the maximum number of blocks downloaded.
This API guarantee that block 0 to get_block_count() - 1
have been downloaded and available for query.
sourcepub fn get_header(&self, height: usize) -> OpResult<&BlockIndexRecord>
pub fn get_header(&self, height: usize) -> OpResult<&BlockIndexRecord>
Get block header information.
This is an in-memory query, thus very fast. This method is useful for computing blockchain statistics.
Example
Compute total number of transactions
use bitcoin_explorer::BitcoinDB;
use std::path::Path;
let path = Path::new("/Users/me/bitcoin");
// launch without reading txindex
let db = BitcoinDB::new(path, false).unwrap();
let mut total_number_of_tx: usize = 0;
// This computation should finish immediately. No Disk Access.
for i in 0..db.get_block_count() {
let header = db.get_header(i).unwrap();
total_number_of_tx += header.n_tx as usize;
}
println!("total number of transactions found on disk : {}.", total_number_of_tx);
sourcepub fn get_hash_from_height(&self, height: usize) -> OpResult<BlockHash>
pub fn get_hash_from_height(&self, height: usize) -> OpResult<BlockHash>
Get block hash of a certain height.
sourcepub fn get_height_from_hash(&self, hash: &BlockHash) -> OpResult<usize>
pub fn get_height_from_hash(&self, hash: &BlockHash) -> OpResult<usize>
Get block height of certain hash.
Note that the hash is a hex string of the block hash.
sourcepub fn get_block<T: From<Block>>(&self, height: usize) -> OpResult<T>
pub fn get_block<T: From<Block>>(&self, height: usize) -> OpResult<T>
Get a block (in different formats (Block, FBlock, SBlock))
Example
use bitcoin_explorer::{BitcoinDB, FBlock, SBlock, Block};
use std::path::Path;
let path = Path::new("/Users/me/bitcoin");
// launch without reading txindex
let db = BitcoinDB::new(path, false).unwrap();
// get block of height 600000 (in different formats)
let block: Block = db.get_block(600000).unwrap();
let block: FBlock = db.get_block(600000).unwrap();
let block: SBlock = db.get_block(600000).unwrap();
sourcepub fn get_transaction<T: From<Transaction>>(&self, txid: &Txid) -> OpResult<T>
pub fn get_transaction<T: From<Transaction>>(&self, txid: &Txid) -> OpResult<T>
Get a transaction by providing txid.
This function requires txindex
to be set to true
for BitcoinDB
,
and requires that flag txindex=1
has been enabled when
running Bitcoin Core.
A transaction cannot be found using this function if it is
not yet indexed using txindex
.
Example
use bitcoin_explorer::{BitcoinDB, Transaction, FTransaction, STransaction, Txid, FromHex};
use std::path::Path;
let path = Path::new("/Users/me/bitcoin");
// !!must launch with txindex=true!!
let db = BitcoinDB::new(path, true).unwrap();
// get transaction
// e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468
let txid_str = "e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468";
let txid = Txid::from_hex(txid_str).unwrap();
// get transactions in different formats
let tx: Transaction = db.get_transaction(&txid).unwrap();
let tx: FTransaction = db.get_transaction(&txid).unwrap();
let tx: STransaction = db.get_transaction(&txid).unwrap();
sourcepub fn get_height_of_transaction(&self, txid: &Txid) -> OpResult<usize>
pub fn get_height_of_transaction(&self, txid: &Txid) -> OpResult<usize>
Get the height of the block containing a particular transaction.
This function requires txindex
to be set to true
for BitcoinDB
,
and requires that flag txindex=1
has been enabled when
running Bitcoin Core.
A transaction cannot be found using this function if it is
not yet indexed using txindex
.
sourcepub fn iter_block<T>(&self, start: usize, end: usize) -> BlockIter<T> ⓘwhere
T: From<Block> + Send + 'static,
pub fn iter_block<T>(&self, start: usize, end: usize) -> BlockIter<T> ⓘwhere T: From<Block> + Send + 'static,
Iterate through all blocks from start
to end
(excluded).
Formats: Block
/ FBlock
/ SBlock
.
Performance
This iterator is implemented to read the blocks in concurrency,
but the result is still produced in sequential order.
Results read are stored in a synced queue for next()
to get.
The iterator stops automatically when a block cannot be read (i.e., when the max height in the database met).
This is a very efficient implementation. Using SSD and intel core i7 (4 core, 8 threads) Iterating from height 0 to 700000 takes about 10 minutes.
Example
use bitcoin_explorer::{BitcoinDB, Block, SBlock, FBlock};
use std::path::Path;
let path = Path::new("/Users/me/bitcoin");
// launch without reading txindex
let db = BitcoinDB::new(path, false).unwrap();
// iterate over block from 600000 to 700000
for block in db.iter_block::<Block>(600000, 700000) {
for tx in block.txdata {
println!("do something for this transaction");
}
}
// iterate over block from 600000 to 700000
for block in db.iter_block::<FBlock>(600000, 700000) {
for tx in block.txdata {
println!("do something for this transaction");
}
}
// iterate over block from 600000 to 700000
for block in db.iter_block::<SBlock>(600000, 700000) {
for tx in block.txdata {
println!("do something for this transaction");
}
}
sourcepub fn iter_heights<T, TIter>(&self, heights: TIter) -> BlockIter<T> ⓘwhere
T: 'static + From<Block> + Send,
TIter: IntoIterator<Item = usize> + Send + 'static,
<TIter as IntoIterator>::IntoIter: Send + 'static,
pub fn iter_heights<T, TIter>(&self, heights: TIter) -> BlockIter<T> ⓘwhere T: 'static + From<Block> + Send, TIter: IntoIterator<Item = usize> + Send + 'static, <TIter as IntoIterator>::IntoIter: Send + 'static,
Iterate through all blocks of given heights.
Formats: Block
/ FBlock
/ SBlock
.
Performance
This iterator is implemented to read the blocks in concurrency,
but the result is still produced in the given order in heights
.
Results read are stored in a synced queue for next()
to get.
This is a very efficient implementation. Using SSD and intel core i7 (4 core, 8 threads) Iterating from height 0 to 700000 takes about 10 minutes.
Fails Fast
The iterator stops immediately when a height
cannot be found.
Example
use bitcoin_explorer::{BitcoinDB, Block, FBlock, SBlock};
use std::path::Path;
let path = Path::new("/Users/me/bitcoin");
// launch without reading txindex
let db = BitcoinDB::new(path, false).unwrap();
let some_heights = vec![3, 5, 7, 9];
// iterate over blocks from 600000 to 700000
for block in db.iter_heights::<Block, _>(some_heights.clone()) {
for tx in block.txdata {
println!("do something for this transaction");
}
}
// iterate over simple blocks from 600000 to 700000
for block in db.iter_heights::<SBlock, _>(some_heights.clone()) {
for tx in block.txdata {
println!("do something for this transaction");
}
}
// iterate over full blocks from 600000 to 700000
for block in db.iter_heights::<FBlock, _>(some_heights.clone()) {
for tx in block.txdata {
println!("do something for this transaction");
}
}