use blvm_consensus::*;
use super::bip_test_helpers::*;
#[test]
fn test_csv_sequence_validation_passes() {
let input_sequence: u32 = 0x00040000; let required_sequence: u32 = 0x00030000;
let tx = create_csv_transaction(input_sequence, required_sequence, vec![0x51]);
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(), height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(result.unwrap());
}
#[test]
fn test_csv_sequence_disabled_fails() {
let input_sequence: u32 = 0x80000000; let required_sequence: u32 = 0x00030000;
let tx = create_csv_transaction(input_sequence, required_sequence, vec![0x51]);
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(!result.unwrap());
}
#[test]
fn test_csv_type_mismatch_fails() {
let input_sequence: u32 = 0x00430000; let required_sequence: u32 = 0x00040000;
let tx = create_csv_transaction(input_sequence, required_sequence, vec![0x51]);
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(!result.unwrap());
}
#[test]
fn test_csv_insufficient_locktime_fails() {
let input_sequence: u32 = 0x00030000; let required_sequence: u32 = 0x00040000;
let tx = create_csv_transaction(input_sequence, required_sequence, vec![0x51]);
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(!result.unwrap());
}
#[test]
fn test_csv_exact_locktime_passes() {
let sequence: u32 = 0x00050000;
let tx = create_csv_transaction(sequence, sequence, vec![0x51]);
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(result.unwrap());
}
#[test]
fn test_csv_block_based_locktime() {
let input_sequence: u32 = 0x000a0000; let required_sequence: u32 = 0x00050000;
let tx = create_csv_transaction(input_sequence, required_sequence, vec![0x51]);
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(result.unwrap());
}
#[test]
fn test_csv_time_based_locktime() {
let input_sequence: u32 = 0x00460000; let required_sequence: u32 = 0x00430000;
let tx = create_csv_transaction(input_sequence, required_sequence, vec![0x51]);
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(result.unwrap());
}
#[test]
fn test_csv_empty_stack_fails() {
let tx = Transaction {
version: 1,
inputs: vec![TransactionInput {
prevout: OutPoint { hash: [1; 32].into(), index: 0 },
script_sig: vec![0xb2], sequence: 0x00040000,
}].into(),
outputs: vec![TransactionOutput {
value: 1000,
script_pubkey: vec![0x51].into(),
}].into(),
lock_time: 0,
};
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(!result.unwrap());
}
#[test]
fn test_csv_invalid_encoding_fails() {
let tx = Transaction {
version: 1,
inputs: vec![TransactionInput {
prevout: OutPoint { hash: [1; 32].into(), index: 0 },
script_sig: vec![
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0xb2, ],
sequence: 0x00040000,
}].into(),
outputs: vec![TransactionOutput {
value: 1000,
script_pubkey: vec![0x51].into(),
}].into(),
lock_time: 0,
};
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(!result.unwrap());
}
#[test]
fn test_csv_max_relative_locktime() {
let input_sequence: u32 = 0x0000ffff; let required_sequence: u32 = 0x0000ffff;
let tx = create_csv_transaction(input_sequence, required_sequence, vec![0x51]);
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(result.unwrap());
}
#[test]
fn test_csv_bip68_encoding() {
let input_sequence: u32 = 0x80000000 | 0x00400000 | 0x00000010; let required_sequence: u32 = 0x00400008;
let tx = create_csv_transaction(input_sequence, required_sequence, vec![0x51]);
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(!result.unwrap());
}
#[test]
fn test_csv_multiple_inputs_context() {
let tx = Transaction {
version: 1,
inputs: vec![
TransactionInput {
prevout: OutPoint { hash: [1; 32].into(), index: 0 },
script_sig: {
let mut script = vec![0x51];
script.extend_from_slice(&encode_script_int(0x00040000));
script.push(0xb2); script
},
sequence: 0x00050000, },
TransactionInput {
prevout: OutPoint { hash: [2; 32], index: 0 },
script_sig: vec![0x51], sequence: 0xffffffff,
},
].into(),
outputs: vec![TransactionOutput {
value: 1000,
script_pubkey: vec![0x51].into(),
}].into(),
lock_time: 0,
};
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 500000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
utxo_set.insert(
OutPoint { hash: [2; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 500000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
let input = &tx.inputs[0];
let utxo = utxo_set.get(&input.prevout).unwrap();
let prevouts = vec![TransactionOutput {
value: utxo.value,
script_pubkey: utxo.script_pubkey.clone(),
}];
let result = verify_script_with_context(
&input.script_sig,
&utxo.script_pubkey,
None,
0,
&tx,
0, &prevouts,
);
assert!(result.is_ok());
assert!(result.unwrap());
}
#[test]
fn test_csv_in_script_pubkey() {
let required_sequence: u32 = 0x00040000; let mut script_pubkey = vec![0x51]; script_pubkey.extend_from_slice(&encode_script_int(required_sequence));
script_pubkey.push(0xb2);
let tx = Transaction {
version: 1,
inputs: vec![TransactionInput {
prevout: OutPoint { hash: [1; 32].into(), index: 0 },
script_sig: vec![0x51], sequence: 0x00050000, }].into(),
outputs: vec![TransactionOutput {
value: 1000,
script_pubkey,
}].into(),
lock_time: 0,
};
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(), height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(result.unwrap());
}
#[test]
fn test_csv_zero_locktime() {
let input_sequence: u32 = 0x00000000; let required_sequence: u32 = 0x00000000;
let tx = create_csv_transaction(input_sequence, required_sequence, vec![0x51]);
let mut utxo_set = UtxoSet::default();
utxo_set.insert(
OutPoint { hash: [1; 32], index: 0 },
std::sync::Arc::new(UTXO {
value: 1000000,
script_pubkey: vec![0x51].into(),
height: 0,
}),
);
let result = validate_with_context(&tx, &utxo_set, 0, 0);
assert!(result.is_ok());
assert!(result.unwrap());
}