Skip to content

Commit 06c9c5d

Browse files
committed
use OnceLock for BlockExtra::block
1 parent e18af46 commit 06c9c5d

File tree

9 files changed

+19
-23
lines changed

9 files changed

+19
-23
lines changed

cli/examples/signatures_in_witness.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fn main() -> Result<(), Box<dyn Error>> {
3333
);
3434
}
3535

36-
for tx in &block_extra.block().expect("block is not loaded").txdata {
36+
for tx in &block_extra.block().txdata {
3737
for input in &tx.input {
3838
for witness in input.witness.iter() {
3939
if let Ok(_sig) = deserialize::<ParsedSignature>(witness) {

cli/examples/with_pipe.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn main() -> Result<(), Box<dyn Error>> {
2020

2121
for block_extra in iter {
2222
let txs_fee = block_extra.fee().expect("launch without `--skip-prevout`");
23-
let block = block_extra.block().expect("block is not loaded");
23+
let block = block_extra.block();
2424
let coinbase = &block.txdata[0];
2525
let coinbase_sum_outputs: u64 = coinbase
2626
.output

lib/src/block_extra.rs

+11-14
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::collections::HashMap;
99
use std::convert::TryFrom;
1010
use std::io::{Read, Seek, SeekFrom};
1111
use std::ops::DerefMut;
12+
use std::sync::OnceLock;
1213

1314
/// The bitcoin block and additional metadata returned by the [crate::iter()] method
1415
#[derive(Debug, Eq, PartialEq)]
@@ -22,7 +23,7 @@ pub struct BlockExtra {
2223
/// avoiding the performance costs and use visitor directly on the bytes with [`bitcoin_slices`]
2324
block_bytes: Vec<u8>,
2425

25-
block: Option<Block>,
26+
block: OnceLock<Block>,
2627

2728
/// The bitcoin block hash, same as `block.block_hash()` but result from hashing is cached
2829
pub(crate) block_hash: BlockHash,
@@ -77,7 +78,7 @@ impl TryFrom<FsBlock> for BlockExtra {
7778
Ok(BlockExtra {
7879
version: fs_block.serialization_version,
7980
block_bytes,
80-
block: None,
81+
block: OnceLock::new(),
8182
block_hash: fs_block.hash,
8283
size: (fs_block.end - fs_block.start) as u32,
8384
next: fs_block.next,
@@ -98,13 +99,10 @@ impl BlockExtra {
9899

99100
/// Returns the block from the bytes
100101
///
101-
/// This is an expensive operations, re-use the results instead of calling it multiple times
102-
pub fn block(&self) -> Option<&Block> {
103-
self.block.as_ref()
104-
}
105-
106-
pub fn init_block(&mut self) {
107-
self.block = Some(Block::consensus_decode(&mut &self.block_bytes[..]).unwrap());
102+
/// This is an expensive operation, re-use the results instead of calling it multiple times
103+
pub fn block(&self) -> &Block {
104+
self.block
105+
.get_or_init(|| Block::consensus_decode(&mut &self.block_bytes[..]).unwrap())
108106
}
109107

110108
pub fn block_bytes(&self) -> &[u8] {
@@ -180,9 +178,7 @@ impl BlockExtra {
180178
///
181179
/// requires serializing the block bytes, consider using a visitor on the bytes for performance
182180
pub fn iter_tx(&self) -> impl Iterator<Item = (&Txid, &Transaction)> {
183-
self.txids
184-
.iter()
185-
.zip(self.block().expect("block not loaded").txdata.iter())
181+
self.txids.iter().zip(self.block().txdata.iter())
186182
}
187183
}
188184

@@ -246,7 +242,7 @@ impl Decodable for BlockExtra {
246242
let mut b = BlockExtra {
247243
version,
248244
block_bytes,
249-
block: None,
245+
block: OnceLock::new(),
250246
block_hash,
251247
size,
252248
next: Decodable::consensus_decode(d)?,
@@ -325,6 +321,7 @@ pub mod test {
325321
use bitcoin::hashes::Hash;
326322
use bitcoin::{BlockHash, CompactTarget};
327323
use std::collections::HashMap;
324+
use std::sync::OnceLock;
328325

329326
#[test]
330327
fn block_extra_round_trip() {
@@ -358,7 +355,7 @@ pub mod test {
358355
BlockExtra {
359356
version: 0,
360357
block_bytes,
361-
block: None,
358+
block: OnceLock::new(),
362359
block_hash: BlockHash::all_zeros(),
363360
size,
364361
next: vec![BlockHash::all_zeros()],

lib/src/iter.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ mod inner_test {
5959
let genesis = genesis_block(Network::Testnet);
6060
let mut current = genesis.clone();
6161
for b in iter(test_conf()).skip(1) {
62-
let block = b.block().unwrap();
62+
let block = b.block();
6363
assert_eq!(current.block_hash(), block.header.prev_blockhash);
6464
current = block.clone();
6565
}

lib/src/stages/fee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl Fee {
5555

5656
let mut outpoint_values =
5757
HashMap::with_capacity(block_extra.block_total_inputs());
58-
let block = block_extra.block().expect("block is not loaded");
58+
let block = block_extra.block();
5959

6060
for tx in block.txdata.iter().skip(1) {
6161
for input in tx.input.iter() {

lib/src/stages/reorder.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,11 @@ impl Reorder {
147147
while let Some(block_to_send) = blocks.remove(&next) {
148148
let mut block_extra: BlockExtra =
149149
block_to_send.try_into().unwrap();
150-
block_extra.init_block();
151150
busy_time += now.elapsed().as_nanos();
152151
next = block_extra.next[0];
153152
block_extra.height = height;
154153
blocks.follows.remove(&block_extra.block_hash);
155-
let block = block_extra.block().expect("block is not loaded");
154+
let block = block_extra.block();
156155

157156
blocks.blocks.remove(&block.header.prev_blockhash);
158157

lib/src/utxo/db.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ impl UtxoStore for DbUtxo {
7373
height, self.updated_up_to_height
7474
);
7575
if height > self.updated_up_to_height {
76-
let block = block_extra.block().expect("block is not loaded");
76+
let block = block_extra.block();
7777

7878
// since we can spend outputs created in this same block, we first put outputs in memory...
7979
let total_outputs = block_extra.block_total_outputs();

lib/src/utxo/mem.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl MemUtxo {
3535

3636
impl UtxoStore for MemUtxo {
3737
fn add_outputs_get_inputs(&mut self, block_extra: &BlockExtra, _height: u32) -> Vec<TxOut> {
38-
let block = block_extra.block().expect("block is not loaded");
38+
let block = block_extra.block();
3939
for (txid, tx) in block_extra.iter_tx() {
4040
self.add_tx_outputs(txid, &tx);
4141
}

lib/src/utxo/redb.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl RedbUtxo {
5858

5959
impl UtxoStore for RedbUtxo {
6060
fn add_outputs_get_inputs(&mut self, block_extra: &BlockExtra, height: u32) -> Vec<TxOut> {
61-
let block = block_extra.block().expect("block is not loaded");
61+
let block = block_extra.block();
6262
// let mut outpoint_buffer = [0u8; 36]; // txid (32) + vout (4)
6363

6464
// max script size for spendable output is 10k https://bitcoin.stackexchange.com/a/35881/6693 ...

0 commit comments

Comments
 (0)