Expand description
The BlockParser
trait allows you to implement a custom parser or use one of the predefined ones.
For example, imagine you want to take the biggest tx using Transaction::total_size
from
every block and sum their output [Amount
].
You can use the DefaultParser
to simply iterate over the Block
:
use bitcoin_block_parser::*;
let mut amount = bitcoin::Amount::ZERO;
for block in DefaultParser.parse_dir("/path/to/blocks").unwrap() {
let txs = block.unwrap().txdata;
let max = txs.into_iter().max_by_key(|tx| tx.total_size());
for output in max.unwrap().output {
amount += output.value;
}
}
println!("Sum of txids: {}", amount);
If you only want to run on a subset of blocks use HeaderParser
:
use bitcoin_block_parser::*;
let headers = HeaderParser::parse("/path/to/blocks").unwrap();
// Skip the first 200,000 blocks
for block in DefaultParser.parse(&headers[200_000..]) {
// Do whatever you need with the blocks
}
If you wish to increase performance you may need to implement your own parser. This example
uses ~2x less memory and less time since BlockParser::extract
reduces the data size and runs
on multiple threads. The more compute and memory your algorithm uses, the more you may benefit
from this.
use bitcoin::*;
use bitcoin_block_parser::*;
#[derive(Clone)]
struct AmountParser;
impl BlockParser<Amount> for AmountParser {
fn extract(&self, block: Block) -> Vec<Amount> {
let max = block.txdata.iter().max_by_key(|tx| tx.total_size());
vec![max.unwrap().output.iter().map(|out| out.value).sum()]
}
}
let receiver = AmountParser.parse_dir("/path/to/blocks").unwrap();
let amounts: anyhow::Result<Vec<Amount>> = receiver.iter().collect();
println!("Sum of txids: {}", amounts.unwrap().into_iter().sum::<Amount>());
You can also cache data within your BlockParser
by using an Arc
that will be shared
across all threads. Updating any locked stated should take place in BlockParser::batch
to reduce the contention on the lock.
use std::sync::*;
use bitcoin::*;
use bitcoin_block_parser::*;
#[derive(Clone, Default)]
struct AmountParser(Arc<Mutex<Amount>>);
impl BlockParser<Amount> for AmountParser {
fn extract(&self, block: bitcoin::Block) -> Vec<Amount> {
let max = block.txdata.iter().max_by_key(|tx| tx.total_size());
vec![max.unwrap().output.iter().map(|out| out.value).sum()]
}
fn batch(&self, items: Vec<Amount>) -> Vec<Amount> {
let mut sum = self.0.lock().unwrap();
for item in items {
*sum += item;
}
vec![]
}
}
let parser = AmountParser::default();
for _ in parser.parse_dir("/path/to/blocks").unwrap() {}
println!("Sum of txids: {:?}", parser.0);
Structs§
- Parser that returns
Block
for users that don’t implement a customBlockParser
- Parse all the blocks represented by the headers, ensuring the blocks are returned in the same order the
ParsedHeader
were passed in. - Options to tune the performance of the parser, generally you can stick to the defaults unless you run into memory issues.
Traits§
- Implement this trait to create a custom
Block
parser.