From a07741c64554299cc1bd08e78540abf127c71a59 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 2 Dec 2016 15:07:35 +0100 Subject: [PATCH] fix verification of testnet block 542 by fixing OP_CHECKSEQENCEVERIFY and OP_CHECKLOCKTIMEVERIFY implementations --- script/src/flags.rs | 2 +- script/src/interpreter.rs | 50 +++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/script/src/flags.rs b/script/src/flags.rs index 9b7f6ca6..929fc3d4 100644 --- a/script/src/flags.rs +++ b/script/src/flags.rs @@ -57,7 +57,7 @@ pub struct VerificationFlags { /// support CHECKSEQUENCEVERIFY opcode /// /// See BIP112 for details - pub verify_chechsequenceverify: bool, + pub verify_checksequenceverify: bool, /// Support segregated witness pub verify_witness: bool, diff --git a/script/src/interpreter.rs b/script/src/interpreter.rs index 7ad62618..c73e58ec 100644 --- a/script/src/interpreter.rs +++ b/script/src/interpreter.rs @@ -454,10 +454,6 @@ pub fn eval_script( }, Opcode::OP_NOP => break, Opcode::OP_CHECKLOCKTIMEVERIFY => { - if flags.verify_discourage_upgradable_nops { - return Err(Error::DiscourageUpgradableNops); - } - if flags.verify_clocktimeverify { // Note that elsewhere numeric opcodes are limited to // operands in the range -2**31+1 to 2**31-1, however it is @@ -485,22 +481,25 @@ pub fn eval_script( if !checker.check_lock_time(lock_time) { return Err(Error::UnsatisfiedLocktime); } + } else if flags.verify_discourage_upgradable_nops { + return Err(Error::DiscourageUpgradableNops); } }, Opcode::OP_CHECKSEQUENCEVERIFY => { - if !flags.verify_chechsequenceverify && flags.verify_discourage_upgradable_nops { + if flags.verify_checksequenceverify { + let sequence = try!(Num::from_slice(try!(stack.last()), flags.verify_minimaldata, 5)); + + if sequence.is_negative() { + return Err(Error::NegativeLocktime); + } + + if (sequence & (SEQUENCE_LOCKTIME_DISABLE_FLAG as i64).into()).is_zero() && !checker.check_sequence(sequence) { + return Err(Error::UnsatisfiedLocktime); + } + + } else if flags.verify_discourage_upgradable_nops { return Err(Error::DiscourageUpgradableNops); } - - let sequence = try!(Num::from_slice(try!(stack.last()), flags.verify_minimaldata, 5)); - - if sequence.is_negative() { - return Err(Error::NegativeLocktime); - } - - if (sequence & (SEQUENCE_LOCKTIME_DISABLE_FLAG as i64).into()).is_zero() && !checker.check_sequence(sequence) { - return Err(Error::UnsatisfiedLocktime); - } }, Opcode::OP_NOP1 | Opcode::OP_NOP4 | @@ -1944,5 +1943,26 @@ mod tests { let result = Ok(true); basic_test(&script, result, vec![vec![1].into()].into()); } + + #[test] + fn test_skipping_sequencetimeverify() { + let script = Builder::default() + .push_opcode(Opcode::OP_1) + .push_opcode(Opcode::OP_NOP1) + .push_opcode(Opcode::OP_CHECKLOCKTIMEVERIFY) + .push_opcode(Opcode::OP_CHECKSEQUENCEVERIFY) + .push_opcode(Opcode::OP_NOP4) + .push_opcode(Opcode::OP_NOP5) + .push_opcode(Opcode::OP_NOP6) + .push_opcode(Opcode::OP_NOP7) + .push_opcode(Opcode::OP_NOP8) + .push_opcode(Opcode::OP_NOP9) + .push_opcode(Opcode::OP_NOP10) + .push_opcode(Opcode::OP_1) + .push_opcode(Opcode::OP_EQUAL) + .into_script(); + let result = Ok(true); + basic_test(&script, result, vec![vec![1].into()].into()); + } }