|
1 | 1 | #[cfg(test)] |
2 | 2 | mod tests { |
| 3 | + use bitcoinkernel::core::transaction::{TxOutPointExt, TxOutPointRef}; |
3 | 4 | use bitcoinkernel::{ |
4 | | - Block, BlockHash, BlockSpentOutputs, BlockTreeEntry, BlockValidationStateRef, ChainParams, ChainType, ChainstateManager, ChainstateManagerBuilder, Coin, Context, ContextBuilder, KernelError, Log, Logger, ScriptPubkey, ScriptVerifyError, Transaction, TransactionSpentOutputs, TxIn, TxOut, TxOutRef, VERIFY_ALL_PRE_TAPROOT, VERIFY_TAPROOT, VERIFY_WITNESS, ValidationMode, prelude::*, verify |
| 5 | + prelude::*, verify, Block, BlockHash, BlockSpentOutputs, BlockTreeEntry, |
| 6 | + BlockValidationStateRef, ChainParams, ChainType, ChainstateManager, |
| 7 | + ChainstateManagerBuilder, Coin, Context, ContextBuilder, KernelError, Log, Logger, |
| 8 | + ScriptPubkey, ScriptVerifyError, Transaction, TransactionSpentOutputs, TxIn, TxOut, |
| 9 | + TxOutRef, ValidationMode, VERIFY_ALL_PRE_TAPROOT, VERIFY_TAPROOT, VERIFY_WITNESS, |
5 | 10 | }; |
6 | 11 | use std::fs::File; |
7 | 12 | use std::io::{BufRead, BufReader}; |
@@ -371,13 +376,74 @@ mod tests { |
371 | 376 | let (context, data_dir) = testing_setup(); |
372 | 377 | let blocks_dir = data_dir.clone() + "/blocks"; |
373 | 378 | let block_data = read_block_data(); |
| 379 | + let blocks: Vec<Block> = block_data |
| 380 | + .iter() |
| 381 | + .map(|data| Block::new(data.as_slice()).unwrap()) |
| 382 | + .collect(); |
374 | 383 | let chainman = ChainstateManager::new(&context, &data_dir, &blocks_dir).unwrap(); |
375 | 384 |
|
376 | | - for raw_block in block_data.iter() { |
377 | | - let block = Block::new(raw_block.as_slice()).unwrap(); |
| 385 | + for block in blocks.iter() { |
| 386 | + let (accepted, state) = chainman.process_header(&block.header()); |
| 387 | + assert!(accepted); |
| 388 | + assert_eq!(state.mode(), ValidationMode::Valid); |
| 389 | + } |
| 390 | + } |
| 391 | + |
| 392 | + fn find_output<'a>(blocks: &'a [Block], outpoint: TxOutPointRef) -> Option<TxOut> { |
| 393 | + for block in blocks.iter() { |
| 394 | + for i in 0..block.transaction_count() { |
| 395 | + let tx = block.transaction(i).unwrap(); |
| 396 | + if tx.txid() != outpoint.txid() { |
| 397 | + continue; |
| 398 | + } |
| 399 | + return tx |
| 400 | + .output(outpoint.index() as usize) |
| 401 | + .ok() |
| 402 | + .map(|out| out.to_owned()); |
| 403 | + } |
| 404 | + } |
| 405 | + None |
| 406 | + } |
| 407 | + |
| 408 | + #[test] |
| 409 | + fn test_block_validation() { |
| 410 | + let (context, data_dir) = testing_setup(); |
| 411 | + let blocks_dir = data_dir.clone() + "/blocks"; |
| 412 | + let block_data = read_block_data(); |
| 413 | + let blocks: Vec<Block> = block_data |
| 414 | + .iter() |
| 415 | + .map(|data| Block::new(data.as_slice()).unwrap()) |
| 416 | + .collect(); |
| 417 | + let chainman = ChainstateManager::new(&context, &data_dir, &blocks_dir).unwrap(); |
| 418 | + |
| 419 | + let mut block_spent_outputs: Vec<BlockSpentOutputs> = vec![]; |
| 420 | + |
| 421 | + for block in blocks.iter() { |
| 422 | + let mut coins: Vec<Vec<Coin>> = vec![]; |
| 423 | + for i in 0..block.transaction_count() { |
| 424 | + let tx = block.transaction(i).unwrap(); |
| 425 | + if tx.is_coinbase() { |
| 426 | + println!("tx is coinbase!"); |
| 427 | + continue; |
| 428 | + } |
| 429 | + coins.push(Vec::new()); |
| 430 | + for j in 0..tx.input_count() { |
| 431 | + let output = find_output(&blocks, tx.input(j).unwrap().outpoint()).unwrap(); |
| 432 | + println!("Accessing coins i {i}"); |
| 433 | + coins[i - 1].push(Coin::new(&output)); |
| 434 | + } |
| 435 | + } |
| 436 | + block_spent_outputs.push(BlockSpentOutputs::new(&coins)); |
| 437 | + } |
| 438 | + |
| 439 | + for (block, block_spent_outputs) in blocks.iter().zip(block_spent_outputs.iter()) { |
378 | 440 | let (accepted, state) = chainman.process_header(&block.header()); |
379 | 441 | assert!(accepted); |
380 | 442 | assert_eq!(state.mode(), ValidationMode::Valid); |
| 443 | + |
| 444 | + let (result, state) = chainman.validate_block(block, &block_spent_outputs); |
| 445 | + assert!(result); |
| 446 | + assert_eq!(state.mode(), ValidationMode::Valid); |
381 | 447 | } |
382 | 448 | } |
383 | 449 |
|
|
0 commit comments