Struct bitcoin_explorer::BitcoinDB [−][src]
pub struct BitcoinDB {
pub block_index: BlockIndex,
pub blk_file: BlkFile,
pub tx_db: TxDB,
}Expand description
This is the main struct of this crate!! Click and read the doc.
All queries start from initializing BitcoinDB.
Fields
block_index: BlockIndexblk_file: BlkFiletx_db: TxDBImplementations
Get a block with inputs replaced by connected outputs.
This function requires txindex to be set to true,
and txindex=1 when running Bitcoin Core.
Caveat!!
This is a very slow function!!
For massive processing of connected blocks, use iter.
Get a transaction with outpoints replaced by outputs.
Format: full (FConnectedTransaction) / simple (SConnectedTransaction).
Caveats
Slow! Not suitable for massive computation. Use iter.
pub fn iter_connected_block<TBlock>(
&self,
end: u32
) -> ConnectedBlockIter<TBlock>ⓘNotable traits for ConnectedBlockIter<TBlock>impl<TBlock> Iterator for ConnectedBlockIter<TBlock> type Item = TBlock; where
TBlock: 'static + BlockConnectable + Send,
pub fn iter_connected_block<TBlock>(
&self,
end: u32
) -> ConnectedBlockIter<TBlock>ⓘNotable traits for ConnectedBlockIter<TBlock>impl<TBlock> Iterator for ConnectedBlockIter<TBlock> type Item = TBlock; where
TBlock: 'static + BlockConnectable + Send,
impl<TBlock> Iterator for ConnectedBlockIter<TBlock> type Item = TBlock;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
Iterating through height from 0 to 700000 takes 5 hours. The performance bottleneck is most likely diskIO.
This iterator is implemented to read the blocks in concurrency,
but each block connects its outpoints to outputs only after
all previous blocks have finished inserting their outputs in
unspent cache.
The result is still produced in the sequential order.
Because this iterator tracks unspent outputs, it can use up to 20GB to 30GB memory.
This iterator can only start from genesis block, because it has to track unspent transactions.
TODO: might use txindex to allow for iterating starting from larger heights.
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, (full format)
for block in db.iter_connected_block::<FConnectedBlock>(700000) {
for tx in block.txdata {
println!("do something for this transaction");
}
}
// 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");
}
}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();Get the maximum height found in block index.
It is not necessarily true that any height smaller than
get_max_height() can be used to query get_block().
This max_height is only the max height of block header
information. The actual block data might not have been
synced for querying. get_block_header(), get_height_from_hash()
get_hash_from_height(), will necessarily return valid
data, as long as height is smaller than get_max_height().
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: usize = 0;
// This computation should finish immediately. No Disk Access.
for i in 0..700000 {
let header = db.get_header(i).unwrap();
total_number += header.n_tx as usize;
}
println!("total tx from block 0 to 700000: {}.", total_number);Get block hash of a certain height.
Get block height of certain hash.
Note that the hash is a hex string of the block hash.
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();Get a transaction by providing txid.
This function requires txindex to be set to true,
and txindex=1 when running Bitcoin Core.
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();Get the height of the block containing a particular transaction.
This function requires txindex to be set to true,
and txindex=1 when running Bitcoin Core.
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. Iterating from height 600000 to 700000 should take less than 30 minutes. The performance bottleneck is likely to be disk IO.
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");
}
}Iterate through all blocks for a given heights (excluded).
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. Iterating from height 600000 to 700000 should take less than 30 minutes. The performance bottleneck is likely to be disk IO.
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) {
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");
}
}