11#![ no_main]
22
3- use bitcoinkernel:: Block ;
3+ use bitcoinkernel:: { prelude :: * , Block , Transaction } ;
44use libfuzzer_sys:: fuzz_target;
55
66fuzz_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} ) ;
0 commit comments