use blvm_consensus::*;
use blvm_consensus::transaction::*;
use blvm_consensus::types::*;
#[test]
fn test_check_transaction_valid() {
let tx = Transaction {
version: 1,
inputs: vec![TransactionInput {
prevout: OutPoint { hash: [1; 32].into(), index: 0 },
script_sig: vec![0x51],
sequence: 0xffffffff,
}].into(),
outputs: vec![TransactionOutput {
value: 1000,
script_pubkey: vec![0x51].into(),
}].into(),
lock_time: 0,
};
let result = check_transaction(&tx).unwrap();
assert!(matches!(result, ValidationResult::Valid));
}
#[test]
fn test_check_transaction_empty_inputs() {
let tx = Transaction {
version: 1,
inputs: vec![].into(),
outputs: vec![TransactionOutput {
value: 1000,
script_pubkey: vec![0x51].into(),
}].into(),
lock_time: 0,
};
let result = check_transaction(&tx).unwrap();
assert!(matches!(result, ValidationResult::Invalid(_)));
}
#[test]
fn test_check_transaction_too_many_inputs() {
let mut inputs = Vec::new();
for i in 0..=MAX_INPUTS {
inputs.push(TransactionInput {
prevout: OutPoint { hash: [i as u8; 32], index: 0 },
script_sig: vec![0x51],
sequence: 0xffffffff,
});
}
let tx = Transaction {
version: 1,
inputs: inputs.into(),
outputs: vec![TransactionOutput {
value: 1000,
script_pubkey: vec![0x51].into(),
}].into(),
lock_time: 0,
};
let result = check_transaction(&tx).unwrap();
assert!(matches!(result, ValidationResult::Invalid(_)));
}
#[test]
fn test_check_transaction_too_many_outputs() {
let mut outputs = Vec::new();
for _ in 0..=MAX_OUTPUTS {
outputs.push(TransactionOutput {
value: 1000,
script_pubkey: vec![0x51],
});
}
let tx = Transaction {
version: 1,
inputs: vec![TransactionInput {
prevout: OutPoint { hash: [1; 32].into(), index: 0 },
script_sig: vec![0x51],
sequence: 0xffffffff,
}].into(),
outputs: outputs.into(),
lock_time: 0,
};
let result = check_transaction(&tx).unwrap();
assert!(matches!(result, ValidationResult::Invalid(_)));
}
#[test]
fn test_check_transaction_negative_output() {
let tx = Transaction {
version: 1,
inputs: vec![TransactionInput {
prevout: OutPoint { hash: [1; 32].into(), index: 0 },
script_sig: vec![0x51],
sequence: 0xffffffff,
}].into(),
outputs: vec![TransactionOutput {
value: -1000, script_pubkey: vec![0x51].into(),
}].into(),
lock_time: 0,
};
let result = check_transaction(&tx).unwrap();
assert!(matches!(result, ValidationResult::Invalid(_)));
}
#[test]
fn test_check_transaction_excessive_output() {
let tx = Transaction {
version: 1,
inputs: vec![TransactionInput {
prevout: OutPoint { hash: [1; 32].into(), index: 0 },
script_sig: vec![0x51],
sequence: 0xffffffff,
}].into(),
outputs: vec![TransactionOutput {
value: MAX_MONEY + 1, script_pubkey: vec![0x51].into(),
}].into(),
lock_time: 0,
};
let result = check_transaction(&tx).unwrap();
assert!(matches!(result, ValidationResult::Invalid(_)));
}
#[test]
fn test_is_coinbase() {
let coinbase_tx = Transaction {
version: 1,
inputs: vec![TransactionInput {
prevout: OutPoint { hash: [0; 32].into(), index: 0xffffffff },
script_sig: vec![0x51],
sequence: 0xffffffff,
}].into(),
outputs: vec![TransactionOutput {
value: 5000000000,
script_pubkey: vec![0x51].into(),
}].into(),
lock_time: 0,
};
assert!(is_coinbase(&coinbase_tx));
let regular_tx = Transaction {
version: 1,
inputs: vec![TransactionInput {
prevout: OutPoint { hash: [1; 32].into(), index: 0 },
script_sig: vec![0x51],
sequence: 0xffffffff,
}].into(),
outputs: vec![TransactionOutput {
value: 1000,
script_pubkey: vec![0x51].into(),
}].into(),
lock_time: 0,
};
assert!(!is_coinbase(®ular_tx));
}
#[test]
fn test_calculate_transaction_size() {
let tx = Transaction {
version: 1,
inputs: vec![TransactionInput {
prevout: OutPoint { hash: [1; 32].into(), index: 0 },
script_sig: vec![0x51, 0x52],
sequence: 0xffffffff,
}].into(),
outputs: vec![TransactionOutput {
value: 1000,
script_pubkey: vec![0x51, 0x52, 0x53].into(),
}].into(),
lock_time: 0,
};
let size = calculate_transaction_size(&tx);
assert!(size > 0);
assert!(size <= MAX_TX_SIZE);
}