1#![forbid(unsafe_code)]
4#![allow(bare_trait_objects)]
5#![allow(ellipsis_inclusive_range_patterns)]
6#![warn(rustdoc::broken_intra_doc_links)]
7#![warn(missing_docs)]
8#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
9
10#[cfg(not(any(feature = "std", feature = "no-std")))]
11compile_error!("at least one of the `std` or `no-std` features must be enabled");
12
13use bitcoin::absolute::LockTime;
14use bitcoin::hash_types::TxMerkleNode;
15use merkle::IncrementalHasher;
16use bitcoin::{io, Amount};
17
18extern crate alloc;
19extern crate core;
20
21pub mod merkle;
23
24use alloc::collections::VecDeque;
25use alloc::vec::Vec;
26use core::mem;
27use core::ops::{Deref, DerefMut};
28
29use bitcoin::consensus::{encode, Decodable, Encodable};
30use bitcoin::hashes::{sha256::HashEngine, Hash, HashEngine as _};
31use bitcoin::{
32 OutPoint, ScriptBuf, Sequence, TxIn, TxOut, Txid,
33 VarInt,
34};
35use bitcoin::blockdata::block::Header as BlockHeader;
36
37use log::*;
38
39#[derive(Debug)]
41pub enum Error {
42 IncompleteData,
44 ParseError,
46 TrailingData,
48}
49
50impl From<encode::Error> for Error {
51 fn from(e: encode::Error) -> Self {
52 debug!("parse error: {}", e);
53 Error::ParseError
54 }
55}
56
57impl From<io::Error> for Error {
58 fn from(e: io::Error) -> Self {
59 debug!("IO error: {}", e);
60 Error::ParseError
61 }
62}
63
64pub trait Listener {
66 fn on_block_start(&mut self, header: &BlockHeader);
68 fn on_transaction_start(&mut self, version: i32);
70 fn on_transaction_input(&mut self, txin: &TxIn);
72 fn on_transaction_output(&mut self, txout: &TxOut);
74 fn on_transaction_end(&mut self, locktime: LockTime, txid: Txid);
76 fn on_block_end(&mut self);
78}
79
80#[derive(Debug, PartialEq)]
81enum ParserState {
82 BeforeHeader,
83 ReadingTransactionHeader,
84 ReadingInputs(usize),
86 ReadingInputScript(usize, OutPoint, usize),
88 ReadingWitnesses(usize, usize, usize),
90 BeforeOutputs,
91 ReadingOutputs(usize),
92 ReadingOutputScript(usize, u64, usize),
94 ReadingLockTime,
95 FinishedBlock,
96}
97
98struct Buffer(VecDeque<u8>);
100
101impl Buffer {
102 fn with_capacity(capacity: usize) -> Self {
103 Self(VecDeque::with_capacity(capacity))
104 }
105}
106
107impl Deref for Buffer {
108 type Target = VecDeque<u8>;
109
110 fn deref(&self) -> &Self::Target {
111 &self.0
112 }
113}
114
115impl DerefMut for Buffer {
116 fn deref_mut(&mut self) -> &mut Self::Target {
117 &mut self.0
118 }
119}
120
121impl io::Read for Buffer {
122 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
123 let (ref mut front, _) = self.as_slices();
124 let n = io::Read::read(front, buf)?;
125 self.drain(..n);
126 Ok(n)
127 }
128}
129
130pub struct BlockDecoder {
143 buffer: Buffer,
144 buffer_capacity: usize,
145 max_script_size: usize,
147 parser_state: ParserState,
148 script: Option<Vec<u8>>,
150 remaining_txs: usize,
152 segwit_inputs: Option<usize>,
154 hasher: HashEngine,
156 merkle: IncrementalHasher,
158 merkle_root: Option<TxMerkleNode>,
160}
161
162impl BlockDecoder {
163 pub fn new() -> Self {
165 Self::new_with_capacity(100, 100)
166 }
167
168 pub fn new_with_capacity(buffer_capacity: usize, max_script_size: usize) -> Self {
171 assert!(buffer_capacity >= 100);
172 let hasher = Txid::engine();
173 Self {
174 buffer: Buffer::with_capacity(buffer_capacity),
175 buffer_capacity,
176 max_script_size,
177 parser_state: ParserState::BeforeHeader,
178 script: None,
179 remaining_txs: 0,
180 segwit_inputs: None,
181 hasher,
182 merkle: IncrementalHasher::new(),
183 merkle_root: None,
184 }
185 }
186
187 pub fn decode_next<L: Listener>(
189 &mut self,
190 mut data: &[u8],
191 listener: &mut L,
192 ) -> Result<(), Error> {
193 while !data.is_empty() {
194 let bytes_to_copy = usize::min(data.len(), self.buffer_capacity - self.buffer.len());
195 trace!("copying {} bytes", bytes_to_copy);
196 self.buffer.extend(&data[..bytes_to_copy]);
197 data = &data[bytes_to_copy..];
198
199 if !self.parse_step(listener)? {
200 break;
201 }
202 }
203
204 trace!("data is empty");
205 self.parse_step(listener)?;
207 trace!(
208 "no progress possible at state {:?} len {}",
209 self.parser_state,
210 self.buffer.len()
211 );
212 Ok(())
213 }
214
215 pub fn finish(self) -> Result<(), Error> {
217 assert_eq!(
218 self.merkle_root,
219 Some(self.merkle.finish()),
220 "merkle root mismatch"
221 );
222 if self.parser_state != ParserState::FinishedBlock {
223 Err(Error::IncompleteData)
224 } else {
225 Ok(())
226 }
227 }
228
229 fn parse_step<L: Listener>(&mut self, listener: &mut L) -> Result<bool, Error> {
231
232 let initial_buffer_len = self.buffer.len();
233
234 loop {
235 trace!("state is {:?} len {}", self.parser_state, self.buffer.len());
236 trace!("buffer {}", hex::encode(self.buffer.make_contiguous()));
237
238 match self.parser_state {
239 ParserState::BeforeHeader =>
240 {
242 if self.buffer.len() >= 80 + 5 {
243 let header = BlockHeader::consensus_decode(&mut self.buffer)?;
244 listener.on_block_start(&header);
245 self.merkle_root = Some(header.merkle_root);
246 let tx_count = VarInt::consensus_decode(&mut self.buffer)?;
247 self.remaining_txs = tx_count.0 as usize;
248 if self.remaining_txs == 0 {
250 return Err(Error::IncompleteData);
251 }
252 self.parser_state = ParserState::ReadingTransactionHeader;
253 } else {
254 break;
255 }
256 }
257 ParserState::ReadingTransactionHeader => {
258 if self.buffer.len() >= 4 + 5 {
260 let version = i32::consensus_decode(&mut self.buffer)?;
261 version.consensus_encode(&mut self.hasher)?;
262
263 let mut input_count = VarInt::consensus_decode(&mut self.buffer)?;
264 if input_count.0 == 0 {
265 let expected_one = VarInt::consensus_decode(&mut self.buffer)?;
267 if expected_one.0 != 1 {
268 return Err(Error::ParseError);
269 }
270
271 input_count = VarInt::consensus_decode(&mut self.buffer)?;
273 self.segwit_inputs = Some(input_count.0 as usize);
274 } else {
275 self.segwit_inputs = None;
276 }
277
278 input_count.consensus_encode(&mut self.hasher)?;
279
280 listener.on_transaction_start(version);
281 if input_count.0 > 0 {
282 self.parser_state = ParserState::ReadingInputs(input_count.0 as usize);
283 } else {
284 self.parser_state = ParserState::BeforeOutputs;
286 }
287 } else {
288 break;
289 }
290 }
291 ParserState::ReadingInputs(remaining_inputs) => {
292 if self.buffer.len() >= 36 + 3 {
294 let outpoint = OutPoint::consensus_decode(&mut self.buffer)?;
295 outpoint.consensus_encode(&mut self.hasher)?;
296
297 let script_len = VarInt::consensus_decode(&mut self.buffer)?;
298 script_len.consensus_encode(&mut self.hasher)?;
299 self.script = if script_len.0 > self.max_script_size as u64 {
300 None
301 } else {
302 Some(Vec::<u8>::with_capacity(script_len.0 as usize))
303 };
304 self.parser_state = ParserState::ReadingInputScript(
305 remaining_inputs,
306 outpoint,
307 script_len.0 as usize,
308 );
309 } else {
310 break;
311 }
312 }
313 ParserState::ReadingInputScript(
314 mut remaining_inputs,
315 outpoint,
316 mut remaining_script_len,
317 ) => {
318 if self.buffer.is_empty() {
319 break;
320 }
321 let to_read = usize::min(remaining_script_len, self.buffer.len());
322
323 if let Some(ref mut script) = self.script {
324 script.extend(self.buffer.range(..to_read));
325 }
326
327 for byte in self.buffer.drain(..to_read) {
328 self.hasher.input(&[byte]);
329 }
330
331 remaining_script_len -= to_read;
332 self.parser_state = ParserState::ReadingInputScript(
333 remaining_inputs,
334 outpoint,
335 remaining_script_len,
336 );
337
338 if remaining_script_len == 0 {
339 if self.buffer.len() >= 4 {
340 let sequence = Sequence(u32::consensus_decode(&mut self.buffer)?);
341 sequence.consensus_encode(&mut self.hasher)?;
342 let script = self.script.take().unwrap_or(Vec::new());
343 let txin = TxIn {
344 previous_output: outpoint,
345 script_sig: ScriptBuf::from(script),
346 sequence,
347 witness: Default::default(),
348 };
349 listener.on_transaction_input(&txin);
350 remaining_inputs -= 1;
351
352 if remaining_inputs == 0 {
353 self.parser_state = ParserState::BeforeOutputs;
354 } else {
355 self.parser_state = ParserState::ReadingInputs(remaining_inputs);
356 }
357 } else {
358 break;
360 }
361 }
362 }
363 ParserState::ReadingWitnesses(
364 mut remaining_inputs,
365 mut remaining_witnesses,
366 mut remaining_witness_len,
367 ) => {
368 if remaining_witness_len > 0 {
369 if self.buffer.is_empty() {
370 break;
371 }
372 let to_read = usize::min(remaining_witness_len, self.buffer.len());
373 self.buffer.drain(..to_read);
374 remaining_witness_len -= to_read;
375 self.parser_state = ParserState::ReadingWitnesses(
376 remaining_inputs,
377 remaining_witnesses,
378 remaining_witness_len,
379 );
380 } else if remaining_witnesses > 0 {
381 if self.buffer.len() < 5 {
382 break;
383 }
384 let witness_length = VarInt::consensus_decode(&mut self.buffer)?.0 as usize;
385 remaining_witnesses -= 1;
386 self.parser_state = ParserState::ReadingWitnesses(
387 remaining_inputs,
388 remaining_witnesses,
389 witness_length,
390 );
391 } else if remaining_inputs > 0 {
392 if self.buffer.len() < 5 {
393 break;
394 }
395 let witnesses = VarInt::consensus_decode(&mut self.buffer)?.0 as usize;
396 remaining_inputs -= 1;
397 self.parser_state =
398 ParserState::ReadingWitnesses(remaining_inputs, witnesses, 0);
399 } else {
400 self.parser_state = ParserState::ReadingLockTime;
401 }
402 }
403 ParserState::BeforeOutputs => {
404 if self.buffer.len() >= 5 {
406 let output_count = VarInt::consensus_decode(&mut self.buffer)?;
407 output_count.consensus_encode(&mut self.hasher)?;
408 self.parser_state = ParserState::ReadingOutputs(output_count.0 as usize);
409 } else {
410 break;
411 }
412 }
413 ParserState::ReadingOutputs(remaining_outputs) => {
414 if self.buffer.len() >= 8 + 3 {
416 let value = u64::consensus_decode(&mut self.buffer)?;
417 value.consensus_encode(&mut self.hasher)?;
418
419 let script_len = VarInt::consensus_decode(&mut self.buffer)?;
420 script_len.consensus_encode(&mut self.hasher)?;
421 self.script = if script_len.0 > self.max_script_size as u64 {
422 None
423 } else {
424 Some(Vec::with_capacity(script_len.0 as usize))
425 };
426 self.parser_state = ParserState::ReadingOutputScript(
427 remaining_outputs,
428 value,
429 script_len.0 as usize,
430 );
431 } else {
432 break;
433 }
434 }
435 ParserState::ReadingOutputScript(
436 mut remaining_outputs,
437 value,
438 mut remaining_script_len,
439 ) => {
440 if self.buffer.is_empty() {
441 break;
442 }
443 let to_read = usize::min(remaining_script_len, self.buffer.len());
444 if let Some(ref mut script) = self.script {
445 script.extend(self.buffer.range(..to_read));
446 }
447 for byte in self.buffer.drain(..to_read) {
448 self.hasher.input(&[byte]);
449 }
450 remaining_script_len -= to_read;
451 if remaining_script_len > 0 {
452 self.parser_state = ParserState::ReadingOutputScript(
453 remaining_outputs,
454 value,
455 remaining_script_len,
456 );
457 } else {
458 let script = self.script.take().unwrap_or(Vec::new());
459 let txout = TxOut {
460 value: Amount::from_sat(value),
461 script_pubkey: ScriptBuf::from(script),
462 };
463 listener.on_transaction_output(&txout);
464 remaining_outputs -= 1;
465
466 if remaining_outputs == 0 {
467 if let Some(segwit_inputs) = self.segwit_inputs {
468 self.parser_state =
469 ParserState::ReadingWitnesses(segwit_inputs, 0, 0);
470 } else {
471 self.parser_state = ParserState::ReadingLockTime;
472 }
473 } else {
474 self.parser_state = ParserState::ReadingOutputs(remaining_outputs);
475 }
476 }
477 }
478 ParserState::ReadingLockTime => {
479 if self.buffer.len() >= 4 {
480 let locktime = LockTime::consensus_decode(&mut self.buffer)?;
481 locktime.consensus_encode(&mut self.hasher)?;
482 let engine = mem::take(&mut self.hasher);
484 let txid = Txid::from_engine(engine);
485 let txid_hash = txid.as_raw_hash();
486 self.merkle.add(TxMerkleNode::from_raw_hash(txid_hash.clone()));
487 listener.on_transaction_end(locktime, txid);
488 self.remaining_txs -= 1;
489 if self.remaining_txs == 0 {
490 self.parser_state = ParserState::FinishedBlock;
491 listener.on_block_end();
492 } else {
493 self.parser_state = ParserState::ReadingTransactionHeader;
494 }
495 } else {
496 break;
497 }
498 }
499 ParserState::FinishedBlock => {
500 if self.buffer.is_empty() {
502 break;
503 } else {
504 return Err(Error::TrailingData);
505 }
506 }
507 }
508 }
509
510 Ok(self.buffer.len() != initial_buffer_len)
511 }
512}
513
514#[cfg(feature = "std")]
516#[allow(missing_docs)]
517pub mod test_util {
518 use super::*;
519
520 pub struct MockListener {
521 pub block_headers: Vec<BlockHeader>,
522 pub transaction_versions: Vec<i32>,
523 pub transaction_inputs: Vec<TxIn>,
524 pub transaction_outputs: Vec<TxOut>,
525 pub transaction_locktimes: Vec<LockTime>,
526 pub transaction_ids: Vec<Txid>,
527 pub output_index: usize,
528 }
529
530 impl MockListener {
531 pub fn new() -> Self {
532 Self {
533 block_headers: Vec::new(),
534 transaction_versions: Vec::new(),
535 transaction_inputs: Vec::new(),
536 transaction_outputs: Vec::new(),
537 transaction_locktimes: Vec::new(),
538 transaction_ids: Vec::new(),
539 output_index: 0,
540 }
541 }
542 }
543
544 impl Listener for MockListener {
545 fn on_block_start(&mut self, header: &BlockHeader) {
546 self.block_headers.push(header.clone());
547 }
548
549 fn on_transaction_start(&mut self, version: i32) {
550 trace!("on_transaction_start({})", version);
551 self.output_index = 0;
552 self.transaction_versions.push(version);
553 }
554
555 fn on_transaction_input(&mut self, txin: &TxIn) {
556 trace!("on_transaction_input: {:?}", txin);
557 assert_eq!(txin.sequence, Sequence::default());
559 self.transaction_inputs.push(txin.clone());
560 }
561
562 fn on_transaction_output(&mut self, txout: &TxOut) {
563 trace!("on_transaction_output: {:?}", txout);
564 assert_eq!(txout.value.to_sat(), self.output_index as u64);
566
567 self.output_index += 1;
568 self.transaction_outputs.push(txout.clone());
569 }
570
571 fn on_transaction_end(&mut self, locktime: LockTime, txid: Txid) {
572 self.transaction_locktimes.push(locktime);
573 self.transaction_ids.push(txid);
574 }
575
576 fn on_block_end(&mut self) {}
577 }
578}
579
580#[cfg(test)]
581mod tests {
582 use alloc::vec::Vec;
583 use bitcoin::block::Version as BlockVersion;
584 use bitcoin::transaction::Version;
585 use bitcoin::consensus::{serialize, Encodable};
586 use bitcoin::hashes::Hash;
587 use bitcoin::{Block, BlockHash, CompactTarget, Transaction, Witness};
588 use test_log::test;
589
590 use super::test_util::MockListener;
591 use super::*;
592
593 #[test]
594 fn test_decode_block_with_no_inputs() {
595 let mut listener = MockListener::new();
596 let mut decoder = BlockDecoder::new();
597 let mut block = Block {
599 header: BlockHeader {
600 version: BlockVersion::ONE,
601 prev_blockhash: BlockHash::all_zeros(),
602 merkle_root: TxMerkleNode::all_zeros(),
603 time: 0,
604 bits: CompactTarget::from_consensus(0),
605 nonce: 0,
606 },
607 txdata: vec![Transaction {
608 version: Version::ONE,
609 lock_time: LockTime::from_consensus(0),
610 input: vec![],
611 output: vec![TxOut {
612 value: Amount::ZERO,
613 script_pubkey: ScriptBuf::from(vec![0x33, 0x44]),
614 }],
615 }],
616 };
617 block.header.merkle_root = block.compute_merkle_root().unwrap();
618 let mut block_bytes = Vec::new();
619 block.consensus_encode(&mut block_bytes).unwrap();
620 trace!("block: {}\n{:#?}", hex::encode(block_bytes.clone()), block);
621 decoder.decode_next(&block_bytes, &mut listener).unwrap();
622 decoder.finish().unwrap();
623 assert_eq!(listener.transaction_ids.len(), 1);
624 assert_eq!(listener.transaction_inputs.len(), 0);
625 }
626
627 #[test]
628 fn test_decode_block() {
629 let mut listener = MockListener::new();
630 let mut decoder = BlockDecoder::new();
631 let mut block = Block {
633 header: BlockHeader {
634 version: BlockVersion::ONE,
635 prev_blockhash: BlockHash::all_zeros(),
636 merkle_root: TxMerkleNode::all_zeros(),
637 time: 0,
638 bits: CompactTarget::from_consensus(0),
639 nonce: 0,
640 },
641 txdata: vec![Transaction {
642 version: Version::ONE,
643 lock_time: LockTime::from_consensus(0),
644 input: vec![TxIn {
645 previous_output: OutPoint {
646 txid: Txid::from_slice(&[0x33u8; 32]).unwrap(),
647 vout: 0x44,
648 },
649 script_sig: ScriptBuf::from(vec![0x11, 0x22]),
650 sequence: Default::default(),
651 witness: Default::default(),
652 }],
653 output: vec![TxOut {
654 value: Amount::ZERO,
655 script_pubkey: ScriptBuf::from(vec![0x33, 0x44]),
656 }],
657 }],
658 };
659 block.header.merkle_root = block.compute_merkle_root().unwrap();
660
661 let mut block_bytes = Vec::new();
662 block.consensus_encode(&mut block_bytes).unwrap();
663 trace!("block: {}\n{:#?}", hex::encode(block_bytes.clone()), block);
664 decoder.decode_next(&block_bytes, &mut listener).unwrap();
665 decoder.finish().unwrap();
666 assert_eq!(listener.block_headers.len(), 1);
667 assert_eq!(listener.block_headers[0], block.header);
668
669 assert_eq!(listener.transaction_versions.len(), 1);
670 assert_eq!(listener.transaction_inputs.len(), 1);
671 assert_eq!(
672 listener.transaction_inputs[0].script_sig.as_bytes(),
673 &[0x11, 0x22]
674 );
675 assert_eq!(listener.transaction_outputs.len(), 1);
676 assert_eq!(
677 listener.transaction_outputs[0].script_pubkey.as_bytes(),
678 &[0x33, 0x44]
679 );
680 assert_eq!(listener.transaction_locktimes.len(), 1);
681
682 assert_eq!(listener.transaction_ids.len(), 1);
683 assert_eq!(listener.transaction_ids[0], block.txdata[0].compute_txid());
684
685 let mut listener = MockListener::new();
687 let mut decoder = BlockDecoder::new();
688 block.txdata[0].input[0].witness =
689 Witness::from_slice(&vec![vec![0x11, 0x22], vec![], vec![0x33, 0x44]]);
690 let mut block_bytes = Vec::new();
691 block.consensus_encode(&mut block_bytes).unwrap();
692 trace!("block: {}\n{:#?}", hex::encode(block_bytes.clone()), block);
693 let ser = serialize(&block.txdata[0]);
694 Transaction::consensus_decode(&mut &ser[..]).unwrap();
695 trace!("tx: {}\n{:#?}", hex::encode(ser), block.txdata[0]);
696
697 decoder.decode_next(&block_bytes, &mut listener).unwrap();
698 decoder.finish().unwrap();
699 assert_eq!(listener.transaction_ids.len(), 1);
700 assert_eq!(listener.transaction_ids[0], block.txdata[0].compute_txid());
701 }
702}