use blvm_consensus::*;
use blvm_consensus::serialization::transaction::serialize_transaction;
use blvm_consensus::serialization::block::serialize_block;
pub fn compare_transaction_validation_local(
tx: &Transaction,
) -> Result<ValidationResult, Box<dyn std::error::Error>> {
check_transaction(tx)
}
pub fn compare_block_validation_local(
block: &Block,
utxo_set: &UtxoSet,
height: u64,
network: blvm_consensus::types::Network,
) -> Result<(ValidationResult, UtxoSet), Box<dyn std::error::Error>> {
let witnesses: Vec<Vec<segwit::Witness>> = block
.transactions
.iter()
.map(|_| Vec::new())
.collect();
let ctx = blvm_consensus::block::BlockValidationContext::for_network(network);
blvm_consensus::block::connect_block(block, &witnesses, utxo_set.clone(), height, &ctx)
.map(|(result, new_utxo_set, _undo_log)| (result, new_utxo_set))
.map_err(|e| Box::new(e) as Box<dyn std::error::Error>)
}
#[cfg(test)]
mod tests {
use super::*;
#[path = "../test_helpers.rs"]
mod test_helpers;
use test_helpers::*;
#[test]
fn test_transaction_validation_comparison() {
let tx = create_test_tx(1000, None, None, None);
let result = compare_transaction_validation_local(&tx);
assert!(result.is_ok());
assert!(matches!(result.unwrap(), ValidationResult::Valid));
let invalid_tx = create_invalid_transaction();
let result = compare_transaction_validation_local(&invalid_tx);
assert!(result.is_ok());
assert!(matches!(result.unwrap(), ValidationResult::Invalid(_)));
}
#[test]
fn test_block_validation_comparison() {
let coinbase = create_coinbase_tx(50_000_000_000);
let block = Block {
header: BlockHeader {
version: 1,
prev_block_hash: [0; 32],
merkle_root: [0; 32],
timestamp: 1234567890,
bits: 0x1d00ffff,
nonce: 0,
},
transactions: vec![coinbase].into(),
};
let utxo_set = UtxoSet::default();
let result = compare_block_validation_local(&block, &utxo_set, 0, blvm_consensus::types::Network::Mainnet);
assert!(result.is_ok());
}
#[test]
fn test_serialization_round_trip() {
let tx = create_test_tx(1000, None, None, None);
let original_result = compare_transaction_validation_local(&tx).unwrap();
let serialized = serialize_transaction(&tx);
let deserialized = bincode::deserialize::<Transaction>(&serialized).unwrap();
let round_trip_result = compare_transaction_validation_local(&deserialized).unwrap();
match (original_result, round_trip_result) {
(ValidationResult::Valid, ValidationResult::Valid) => {
}
(ValidationResult::Invalid(_), ValidationResult::Invalid(_)) => {
}
_ => {
panic!("Validation results should match after round-trip");
}
}
}
}