Skip to content

Commit 1212949

Browse files
Juhyung Parkmergify[bot]
authored andcommitted
Read the timelock type from the script
1 parent 35c86ac commit 1212949

File tree

4 files changed

+40
-18
lines changed

4 files changed

+40
-18
lines changed

vm/src/decoder.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::opcode;
2121
pub enum DecoderError {
2222
ScriptTooShort,
2323
InvalidOpCode(u8),
24+
InvalidImmediateValue(u8),
2425
}
2526

2627
pub fn decode(bytes: &[u8]) -> Result<Vec<Instruction>, DecoderError> {
@@ -77,7 +78,13 @@ pub fn decode(bytes: &[u8]) -> Result<Vec<Instruction>, DecoderError> {
7778
opcode::RIPEMD160 => result.push(Instruction::Ripemd160),
7879
opcode::KECCAK256 => result.push(Instruction::Keccak256),
7980
opcode::BLAKE160 => result.push(Instruction::Blake160),
80-
opcode::CHKTIMELOCK => result.push(Instruction::ChkTimelock),
81+
opcode::CHKTIMELOCK => {
82+
let val = *iter.next().ok_or(DecoderError::ScriptTooShort)?;
83+
if val < 1 || val > 4 {
84+
return Err(DecoderError::InvalidImmediateValue(val))
85+
}
86+
result.push(Instruction::ChkTimelock(val));
87+
}
8188
invalid_opcode => return Err(DecoderError::InvalidOpCode(invalid_opcode)),
8289
}
8390
}
@@ -141,7 +148,6 @@ mod tests {
141148
test_no_argument_opcode!(RIPEMD160, Ripemd160);
142149
test_no_argument_opcode!(KECCAK256, Keccak256);
143150
test_no_argument_opcode!(BLAKE160, Blake160);
144-
test_no_argument_opcode!(CHKTIMELOCK, ChkTimelock);
145151

146152
#[test]
147153
#[allow(non_snake_case)]
@@ -153,4 +159,21 @@ mod tests {
153159
);
154160
assert_eq!(decode([&[opcode::PUSHB, 4], &blobs[0][..]].concat().as_slice()), Err(DecoderError::ScriptTooShort));
155161
}
162+
163+
#[test]
164+
#[allow(non_snake_case)]
165+
fn ChkTimelock() {
166+
assert_eq!(decode(&[opcode::CHKTIMELOCK]), Err(DecoderError::ScriptTooShort));
167+
assert_eq!(decode(&[opcode::CHKTIMELOCK, 0]), Err(DecoderError::InvalidImmediateValue(0)));
168+
assert_eq!(decode(&[opcode::CHKTIMELOCK, 5]), Err(DecoderError::InvalidImmediateValue(5)));
169+
assert_eq!(decode(&[opcode::CHKTIMELOCK, 1]), Ok(vec![Instruction::ChkTimelock(1)]));
170+
assert_eq!(decode(&[opcode::CHKTIMELOCK, 2]), Ok(vec![Instruction::ChkTimelock(2)]));
171+
assert_eq!(decode(&[opcode::CHKTIMELOCK, 3]), Ok(vec![Instruction::ChkTimelock(3)]));
172+
assert_eq!(decode(&[opcode::CHKTIMELOCK, 4]), Ok(vec![Instruction::ChkTimelock(4)]));
173+
assert_eq!(decode(&[opcode::CHKTIMELOCK, 1, opcode::CHKTIMELOCK]), Err(DecoderError::ScriptTooShort));
174+
assert_eq!(
175+
decode(&[opcode::CHKTIMELOCK, 1, opcode::CHKTIMELOCK, 2]),
176+
Ok(vec![Instruction::ChkTimelock(1), Instruction::ChkTimelock(2)])
177+
);
178+
}
156179
}

vm/src/executor.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,10 @@ where
302302
let value = stack.pop()?;
303303
stack.push(Item(H160::blake(value).to_vec()))?;
304304
}
305-
Instruction::ChkTimelock => {
306-
let timelock_type = stack.pop()?.assert_len(1)?.as_ref()[0] as u8;
305+
Instruction::ChkTimelock(timelock_type) => {
307306
let value_item = stack.pop()?;
308307
let value = read_u64(value_item)?;
309-
match timelock_type {
308+
match *timelock_type {
310309
TIMELOCK_TYPE_BLOCK => {
311310
stack.push(Item::from(client.best_block_number() >= value))?;
312311
}

vm/src/instruction.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub enum Instruction {
3939
Ripemd160,
4040
Keccak256,
4141
Blake160,
42-
ChkTimelock,
42+
ChkTimelock(u8),
4343
}
4444

4545
pub fn is_valid_unlock_script(instrs: &[Instruction]) -> bool {

vm/tests/executor.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ fn timelock_invalid_type() {
635635
execute(
636636
&[],
637637
&[],
638-
&[Instruction::Push(0), Instruction::Push(5), Instruction::ChkTimelock],
638+
&[Instruction::Push(0), Instruction::ChkTimelock(5)],
639639
&dummy_tx(),
640640
VMConfig::default(),
641641
&dummy_input(),
@@ -652,7 +652,7 @@ fn timelock_invalid_value() {
652652
execute(
653653
&[],
654654
&[],
655-
&[Instruction::PushB(vec![0, 0, 0, 0, 0, 0, 0, 0, 0]), Instruction::Push(1), Instruction::ChkTimelock],
655+
&[Instruction::PushB(vec![0, 0, 0, 0, 0, 0, 0, 0, 0]), Instruction::ChkTimelock(1)],
656656
&dummy_tx(),
657657
VMConfig::default(),
658658
&dummy_input(),
@@ -670,7 +670,7 @@ fn timelock_block_number_success() {
670670
execute(
671671
&[],
672672
&[],
673-
&[Instruction::PushB(vec![10]), Instruction::Push(1), Instruction::ChkTimelock],
673+
&[Instruction::PushB(vec![10]), Instruction::ChkTimelock(1)],
674674
&dummy_tx(),
675675
VMConfig::default(),
676676
&dummy_input(),
@@ -688,7 +688,7 @@ fn timelock_block_number_fail() {
688688
execute(
689689
&[],
690690
&[],
691-
&[Instruction::PushB(vec![10]), Instruction::Push(1), Instruction::ChkTimelock],
691+
&[Instruction::PushB(vec![10]), Instruction::ChkTimelock(1)],
692692
&dummy_tx(),
693693
VMConfig::default(),
694694
&dummy_input(),
@@ -707,7 +707,7 @@ fn timelock_block_timestamp_success() {
707707
execute(
708708
&[],
709709
&[],
710-
&[Instruction::PushB(vec![0x00, 0x5B, 0xD0, 0x2B, 0xF2]), Instruction::Push(3), Instruction::ChkTimelock],
710+
&[Instruction::PushB(vec![0x00, 0x5B, 0xD0, 0x2B, 0xF2]), Instruction::ChkTimelock(3)],
711711
&dummy_tx(),
712712
VMConfig::default(),
713713
&dummy_input(),
@@ -726,7 +726,7 @@ fn timelock_block_timestamp_fail() {
726726
execute(
727727
&[],
728728
&[],
729-
&[Instruction::PushB(vec![0x00, 0x5B, 0xD0, 0x2B, 0xF2]), Instruction::Push(3), Instruction::ChkTimelock],
729+
&[Instruction::PushB(vec![0x00, 0x5B, 0xD0, 0x2B, 0xF2]), Instruction::ChkTimelock(3)],
730730
&dummy_tx(),
731731
VMConfig::default(),
732732
&dummy_input(),
@@ -744,7 +744,7 @@ fn timelock_block_age_fail_due_to_none() {
744744
execute(
745745
&[],
746746
&[],
747-
&[Instruction::PushB(vec![1]), Instruction::Push(2), Instruction::ChkTimelock],
747+
&[Instruction::PushB(vec![1]), Instruction::ChkTimelock(2)],
748748
&dummy_tx(),
749749
VMConfig::default(),
750750
&dummy_input(),
@@ -762,7 +762,7 @@ fn timelock_block_age_fail() {
762762
execute(
763763
&[],
764764
&[],
765-
&[Instruction::PushB(vec![5]), Instruction::Push(2), Instruction::ChkTimelock],
765+
&[Instruction::PushB(vec![5]), Instruction::ChkTimelock(2)],
766766
&dummy_tx(),
767767
VMConfig::default(),
768768
&dummy_input(),
@@ -780,7 +780,7 @@ fn timelock_block_age_success() {
780780
execute(
781781
&[],
782782
&[],
783-
&[Instruction::PushB(vec![5]), Instruction::Push(2), Instruction::ChkTimelock],
783+
&[Instruction::PushB(vec![5]), Instruction::ChkTimelock(2)],
784784
&dummy_tx(),
785785
VMConfig::default(),
786786
&dummy_input(),
@@ -798,7 +798,7 @@ fn timelock_time_age_fail_due_to_none() {
798798
execute(
799799
&[],
800800
&[],
801-
&[Instruction::PushB(vec![0x27, 0x8D, 0x00]), Instruction::Push(4), Instruction::ChkTimelock],
801+
&[Instruction::PushB(vec![0x27, 0x8D, 0x00]), Instruction::ChkTimelock(4)],
802802
&dummy_tx(),
803803
VMConfig::default(),
804804
&dummy_input(),
@@ -817,7 +817,7 @@ fn timelock_time_age_fail() {
817817
execute(
818818
&[],
819819
&[],
820-
&[Instruction::PushB(vec![0x27, 0x8D, 0x00]), Instruction::Push(4), Instruction::ChkTimelock],
820+
&[Instruction::PushB(vec![0x27, 0x8D, 0x00]), Instruction::ChkTimelock(4)],
821821
&dummy_tx(),
822822
VMConfig::default(),
823823
&dummy_input(),
@@ -835,7 +835,7 @@ fn timelock_time_age_success() {
835835
execute(
836836
&[],
837837
&[],
838-
&[Instruction::PushB(vec![0x27, 0x8D, 0x00]), Instruction::Push(4), Instruction::ChkTimelock],
838+
&[Instruction::PushB(vec![0x27, 0x8D, 0x00]), Instruction::ChkTimelock(4)],
839839
&dummy_tx(),
840840
VMConfig::default(),
841841
&dummy_input(),

0 commit comments

Comments
 (0)