Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 5 additions & 25 deletions crates/node/src/apply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2391,27 +2391,16 @@ struct PreparedApply<'b> {
resolved: Arc<ResolvedUtxoView>,
}

/// Parses a block and resolves the outputs it spends.
///
/// `source` is where prevouts come from. Today that is always the committed
/// UTXO set; a window passes an overlay so a block can see outputs an earlier
/// block in the same window created.
///
/// Runs no consensus rule and mutates nothing, which is what lets a window
/// prepare several blocks before committing any of them.
/// A sink that compares what is written to it against `expected`.
///
/// Used to check preserved bytes against a block without serialising the block
/// into a second buffer: nothing is allocated and the first differing byte ends
/// the walk.
/// Compares encoded bytes against `expected` without allocating a second buffer.
/// The first differing byte ends the walk.
struct ByteEquality<'a> {
expected: &'a [u8],
offset: usize,
equal: bool,
}

impl std::io::Write for ByteEquality<'_> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
impl bitcoin_rs_primitives::Sink for ByteEquality<'_> {
fn write_all(&mut self, buf: &[u8]) {
if self.equal {
match self
.expected
Expand All @@ -2422,11 +2411,6 @@ impl std::io::Write for ByteEquality<'_> {
}
}
self.offset = self.offset.saturating_add(buf.len());
Ok(buf.len())
}

fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}

Expand All @@ -2437,11 +2421,7 @@ pub(crate) fn bytes_are_block(raw: &[u8], block: &Block) -> bool {
offset: 0,
equal: true,
};
// Encoding to a sink cannot fail; a write error here would be a bug in the
// sink above, and treating it as inequality is the safe reading either way.
if block.consensus_encode(&mut sink).is_err() {
return false;
}
block.consensus_encode(&mut sink);
// `offset` accumulated every written byte, so a longer `raw` (trailing
// bytes) fails here just as a shorter one fails in the sink.
sink.equal && sink.offset == raw.len()
Expand Down
2 changes: 1 addition & 1 deletion crates/node/src/chainstate_journal/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ fn decode_payload(payload: &[u8]) -> Result<JournalRecord, JournalRecordError> {
fn put_coin(out: &mut Vec<u8>, coin: &Coin) {
out.extend_from_slice(coin.outpoint.txid.as_bytes());
put_u32(out, coin.outpoint.vout);
let _ = coin.txout.consensus_encode(out);
coin.txout.consensus_encode(out);
put_u32(out, coin.height);
out.push(u8::from(coin.coinbase));
}
Expand Down
14 changes: 2 additions & 12 deletions crates/node/src/checkpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::io::{BufReader, BufWriter, Read, Seek, SeekFrom, Write};
use std::path::Path;

use bitcoin_rs_chain::{BlockTree, ChainWork, NodeId, TipSnapshot, accept_headers};
use bitcoin_rs_primitives::{ConsensusEncode, Header, deserialize};
use bitcoin_rs_primitives::{Hash256, Network};
use bitcoin_rs_primitives::{Header, deserialize};
use bitcoin_rs_utxo::stats::{
CoinStats, CoinStatsAccumulator, CoinStatsListener, coin_stats::COIN_STATS_ENCODED_LEN,
};
Expand Down Expand Up @@ -414,17 +414,7 @@ fn tip_from_node(
}

fn encode_header(header: &Header) -> Result<[u8; HEADER_LEN], HeaderCheckpointError> {
let mut encoded = [0_u8; HEADER_LEN];
let mut cursor = &mut encoded[..];
header
.consensus_encode(&mut cursor)
.map_err(|error| HeaderCheckpointError::Codec(error.to_string()))?;
if !cursor.is_empty() {
return Err(HeaderCheckpointError::Codec(
"Bitcoin header did not encode to 80 bytes".to_owned(),
));
}
Ok(encoded)
Ok(header.to_bytes())
}

#[derive(Clone, Debug, Serialize, Deserialize)]
Expand Down
6 changes: 3 additions & 3 deletions crates/p2p/src/wire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,14 +356,14 @@ pub fn wire_len(message: &Message) -> Result<usize, PeerError> {
pub fn encode_payload(message: &Message) -> Result<Vec<u8>, PeerError> {
let mut payload = Vec::new();
match message {
Message::Tx(tx) => tx.consensus_encode(&mut payload)?,
Message::Block(block) => block.consensus_encode(&mut payload)?,
Message::Tx(tx) => tx.consensus_encode(&mut payload),
Message::Block(block) => block.consensus_encode(&mut payload),
Message::Headers(headers) => {
let count = u64::try_from(headers.len())
.map_err(|_| PeerError::PayloadTooLarge(headers.len()))?;
encode_varint(&mut payload, count);
for header in headers {
header.consensus_encode(&mut payload)?;
header.consensus_encode(&mut payload);
payload.push(0);
}
}
Expand Down
3 changes: 2 additions & 1 deletion crates/primitives/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ type vocabulary.
`Header` do the same at block level with block-level hashing helpers; `OutPoint` is
the fixed-layout transaction outpoint; and `Hash256` is the fixed-width 256-bit hash
type the wrappers hash into. `encode` holds the consensus encoding and hashing helpers
shared by the primitive wrappers, `varint` the Bitcoin compact-size integer codec,
shared by the primitive wrappers (`Sink`, `ConsensusEncode`, analytic `consensus_size`),
`varint` the Bitcoin compact-size integer codec,
`sighash` the signature-hash mode wrappers (`Sighash`, `SighashError`), and `network`
the Bitcoin network constants re-exported as `Network`. The `version` module publishes
`PKG_VERSION` and `USER_AGENT`, the workspace release constants carried in wire and
Expand Down
6 changes: 4 additions & 2 deletions crates/primitives/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ impl Block {
/// (txid-layout) size.
#[must_use]
pub fn stripped_size(&self) -> usize {
consensus_len(&self.header)
.saturating_add(crate::varint::encode(crate::encode::compact_len(self.txs.len())).len())
Header::LEN
.saturating_add(crate::varint::encoded_len(crate::encode::compact_len(
self.txs.len(),
)))
.saturating_add(self.txs.iter().map(Tx::base_size).sum())
}

Expand Down
Loading
Loading