tidecoin_consensus_core/
verify.rs1use crate::{
4 Interpreter, ScriptError, ScriptFlags, SpendContext, TidecoinValidationError,
5 TransactionContext, VERIFY_CLEANSTACK, VERIFY_P2SH, VERIFY_WITNESS,
6};
7use primitives::Transaction;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct VerificationFailure {
12 pub error: TidecoinValidationError,
14 pub script_error: ScriptError,
16}
17
18pub fn verify_script_input(
20 tx: &Transaction,
21 input_index: usize,
22 spend: SpendContext<'_>,
23 flags: u32,
24) -> Result<(), TidecoinValidationError> {
25 verify_script_input_detailed(tx, input_index, spend, flags).map_err(|failure| failure.error)
26}
27
28pub fn validate_verification_flags(flags: u32) -> Result<(), TidecoinValidationError> {
30 let _ = ScriptFlags::from_bits(normalize_flags(flags))?;
31 Ok(())
32}
33
34pub fn verify_script_input_detailed(
36 tx: &Transaction,
37 input_index: usize,
38 spend: SpendContext<'_>,
39 flags: u32,
40) -> Result<(), VerificationFailure> {
41 let flags = ScriptFlags::from_bits(normalize_flags(flags)).map_err(simple_failure)?;
42 let tx_ctx = TransactionContext::new(tx);
43 let mut interpreter =
44 Interpreter::new(&tx_ctx, input_index, spend, flags).map_err(simple_failure)?;
45
46 interpreter.verify().map_err(|err| {
47 let script_error = interpreter.last_script_error();
48 VerificationFailure { error: normalize_script_error(err, script_error), script_error }
49 })
50}
51
52fn normalize_flags(mut flags: u32) -> u32 {
53 if flags & VERIFY_CLEANSTACK != 0 {
54 flags |= VERIFY_P2SH | VERIFY_WITNESS;
55 }
56 flags
57}
58
59fn simple_failure(error: TidecoinValidationError) -> VerificationFailure {
60 VerificationFailure { error, script_error: ScriptError::Ok }
61}
62
63fn normalize_script_error(
64 error: TidecoinValidationError,
65 script_error: ScriptError,
66) -> TidecoinValidationError {
67 match error {
68 TidecoinValidationError::Script(_) => TidecoinValidationError::Script(script_error),
69 other => other,
70 }
71}