@@ -7,8 +7,8 @@ mod tests {
77 BlockValidationStateRef , ChainParams , ChainType , ChainstateManager ,
88 ChainstateManagerBuilder , Coin , Context , ContextBuilder , KernelError , Log , Logger ,
99 PrecomputedTransactionData , ScriptPubkey , ScriptVerifyError , Transaction ,
10- TransactionSpentOutputs , TxIn , TxOut , ValidationMode , VERIFY_ALL , VERIFY_ALL_PRE_TAPROOT ,
11- VERIFY_TAPROOT , VERIFY_WITNESS ,
10+ TransactionSpentOutputs , TxIn , TxOut , TxOutPointRef , ValidationMode , VERIFY_ALL ,
11+ VERIFY_ALL_PRE_TAPROOT , VERIFY_TAPROOT , VERIFY_WITNESS ,
1212 } ;
1313 use libbitcoinkernel_sys:: btck_ScriptVerificationFlags;
1414 use std:: fs:: File ;
@@ -385,6 +385,68 @@ mod tests {
385385 }
386386 }
387387
388+ fn find_output < ' a > ( blocks : & ' a [ Block ] , outpoint : TxOutPointRef ) -> Option < TxOut > {
389+ for block in blocks. iter ( ) {
390+ for i in 0 ..block. transaction_count ( ) {
391+ let tx = block. transaction ( i) . unwrap ( ) ;
392+ if tx. txid ( ) != outpoint. txid ( ) {
393+ continue ;
394+ }
395+ return tx
396+ . output ( outpoint. index ( ) as usize )
397+ . ok ( )
398+ . map ( |out| out. to_owned ( ) ) ;
399+ }
400+ }
401+ None
402+ }
403+
404+ #[ test]
405+ fn test_block_validation ( ) {
406+ let ( context, data_dir) = testing_setup ( ) ;
407+ let blocks_dir = data_dir. clone ( ) + "/blocks" ;
408+ let block_data = read_block_data ( ) ;
409+ let blocks: Vec < Block > = block_data
410+ . iter ( )
411+ . map ( |data| Block :: new ( data. as_slice ( ) ) . unwrap ( ) )
412+ . collect ( ) ;
413+ let chainman = ChainstateManager :: new ( & context, & data_dir, & blocks_dir) . unwrap ( ) ;
414+
415+ let mut block_spent_outputs: Vec < BlockSpentOutputs > = vec ! [ ] ;
416+
417+ for block in blocks. iter ( ) {
418+ let mut coins: Vec < Vec < Coin > > = vec ! [ ] ;
419+ for i in 0 ..block. transaction_count ( ) {
420+ let tx = block. transaction ( i) . unwrap ( ) ;
421+ if tx. is_coinbase ( ) {
422+ println ! ( "tx is coinbase!" ) ;
423+ continue ;
424+ }
425+ coins. push ( Vec :: new ( ) ) ;
426+ for j in 0 ..tx. input_count ( ) {
427+ let output = find_output ( & blocks, tx. input ( j) . unwrap ( ) . outpoint ( ) ) . unwrap ( ) ;
428+ println ! ( "Accessing coins i {i}" ) ;
429+ coins[ i - 1 ] . push ( Coin :: new ( & output) ) ;
430+ }
431+ }
432+ block_spent_outputs. push ( BlockSpentOutputs :: new ( & coins) ) ;
433+ }
434+
435+ for ( block, block_spent_outputs) in blocks. iter ( ) . zip ( block_spent_outputs. iter ( ) ) {
436+ let result = chainman. process_block_header ( & block. header ( ) ) ;
437+ match result {
438+ ProcessBlockHeaderResult :: Success ( state) => {
439+ assert_eq ! ( state. mode( ) , ValidationMode :: Valid ) ;
440+ }
441+ _ => assert ! ( false ) ,
442+ } ;
443+
444+ let ( result, state) = chainman. validate_block ( block, & block_spent_outputs) ;
445+ assert ! ( result) ;
446+ assert_eq ! ( state. mode( ) , ValidationMode :: Valid ) ;
447+ }
448+ }
449+
388450 #[ test]
389451 fn test_chain_operations ( ) {
390452 let ( context, data_dir) = testing_setup ( ) ;
0 commit comments