Skip to content

Commit 1767f17

Browse files
authored
Merge pull request #125 from marcofleon/primitives-fuzz-test
fuzz: Extend block and transaction round trip tests
2 parents f848260 + b7539ea commit 1767f17

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

fuzz/fuzz_targets/block_roundtrip.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![no_main]
22

3-
use bitcoinkernel::Block;
3+
use bitcoinkernel::{prelude::*, Block, Transaction};
44
use libfuzzer_sys::fuzz_target;
55

66
fuzz_target!(|data: &[u8]| {
@@ -17,4 +17,47 @@ fuzz_target!(|data: &[u8]| {
1717
serialized, reserialized,
1818
"Serialization must be stable across roundtrips"
1919
);
20+
21+
let block = Block::try_from(data).unwrap();
22+
23+
let tx_count = block.transaction_count();
24+
assert_eq!(tx_count, block.transactions().count());
25+
26+
for (i, tx) in block.transactions().enumerate().take(1000) {
27+
if let Ok(indexed_tx) = block.transaction(i) {
28+
assert_eq!(tx.txid(), indexed_tx.txid());
29+
}
30+
31+
assert_eq!(tx.inputs().count(), tx.input_count());
32+
assert_eq!(tx.outputs().count(), tx.output_count());
33+
34+
for (j, input) in tx.inputs().enumerate().take(10) {
35+
if let Ok(indexed_input) = tx.input(j) {
36+
let op1 = input.outpoint();
37+
let op2 = indexed_input.outpoint();
38+
assert_eq!(op1.txid(), op2.txid());
39+
assert_eq!(op1.index(), op2.index());
40+
assert_eq!(op1.is_null(), op2.is_null());
41+
}
42+
}
43+
44+
for (j, output) in tx.outputs().enumerate().take(10) {
45+
if let Ok(indexed_output) = tx.output(j) {
46+
assert_eq!(output.value(), indexed_output.value());
47+
assert_eq!(
48+
output.script_pubkey().to_bytes(),
49+
indexed_output.script_pubkey().to_bytes()
50+
);
51+
}
52+
}
53+
54+
// Sanity check that transactions extracted from blocks are valid on their own
55+
if let Ok(tx_bytes) = tx.consensus_encode() {
56+
let standalone_tx = Transaction::try_from(tx_bytes.as_slice())
57+
.expect("Transaction valid in block should parse standalone");
58+
assert_eq!(tx.txid(), standalone_tx.txid());
59+
assert_eq!(tx.input_count(), standalone_tx.input_count());
60+
assert_eq!(tx.output_count(), standalone_tx.output_count());
61+
}
62+
}
2063
});

fuzz/fuzz_targets/transaction_roundtrip.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![no_main]
2-
use bitcoinkernel::Transaction;
2+
use bitcoinkernel::{prelude::*, Transaction};
33
use libfuzzer_sys::fuzz_target;
44

55
fuzz_target!(|data: &[u8]| {
@@ -18,4 +18,24 @@ fuzz_target!(|data: &[u8]| {
1818
serialized, reserialized,
1919
"Serialization must be stable across roundtrips"
2020
);
21+
22+
let tx = Transaction::try_from(data).unwrap();
23+
24+
assert_eq!(tx.inputs().count(), tx.input_count());
25+
assert_eq!(tx.outputs().count(), tx.output_count());
26+
27+
for (i, input) in tx.inputs().enumerate().take(10) {
28+
if let Ok(indexed_input) = tx.input(i) {
29+
let op1 = input.outpoint();
30+
let op2 = indexed_input.outpoint();
31+
assert_eq!(op1.txid(), op2.txid());
32+
assert_eq!(op1.index(), op2.index());
33+
}
34+
}
35+
36+
for (i, output) in tx.outputs().enumerate().take(10) {
37+
if let Ok(indexed_output) = tx.output(i) {
38+
assert_eq!(output.value(), indexed_output.value());
39+
}
40+
}
2141
});

0 commit comments

Comments
 (0)