From 5ec566fb760347f06351b07316bfc13ffd2e5bd0 Mon Sep 17 00:00:00 2001 From: jun Date: Wed, 8 Aug 2018 17:50:21 +0900 Subject: [PATCH] Add logic to limit expensive operations in script --- vm/src/executor.rs | 6 +++++- vm/src/instruction.rs | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/vm/src/executor.rs b/vm/src/executor.rs index 554bccc8f2..6e38b0b619 100644 --- a/vm/src/executor.rs +++ b/vm/src/executor.rs @@ -18,7 +18,7 @@ use ccrypto::{blake256, keccak256, ripemd160, sha256}; use ckey::{verify, Public, Signature, SIGNATURE_LENGTH}; use primitives::H256; -use instruction::{is_valid_unlock_script, Instruction}; +use instruction::{has_expensive_opcodes, is_valid_unlock_script, Instruction}; const DEFAULT_MAX_MEMORY: usize = 1024; @@ -152,6 +152,10 @@ pub fn execute( return Ok(ScriptResult::Fail) } + if has_expensive_opcodes(unlock) { + return Ok(ScriptResult::Fail) + } + let param_scripts: Vec<_> = params.iter().map(|p| Instruction::PushB(p.clone())).rev().collect(); let script = [unlock, ¶m_scripts, lock].concat(); diff --git a/vm/src/instruction.rs b/vm/src/instruction.rs index d2f1b36fde..c9afa20575 100644 --- a/vm/src/instruction.rs +++ b/vm/src/instruction.rs @@ -46,3 +46,28 @@ pub fn is_valid_unlock_script(instrs: &[Instruction]) -> bool { _ => false, }) } + +pub fn has_expensive_opcodes(instrs: &[Instruction]) -> bool { + let count = instrs.iter().filter(|instr| instr == &&Instruction::ChkSig).count(); + count >= 6 +} + +#[test] +fn should_true_when_script_has_more_than_six_chksig_opcodes() { + let expensive_script = vec![ + Instruction::ChkSig, + Instruction::ChkSig, + Instruction::ChkSig, + Instruction::ChkSig, + Instruction::ChkSig, + Instruction::ChkSig, + ]; + assert_eq!(has_expensive_opcodes(&expensive_script), true); +} + +#[test] +fn should_false_when_script_has_lower_than_five_chksig_opcodes() { + let unexpensive_script = + vec![Instruction::ChkSig, Instruction::ChkSig, Instruction::ChkSig, Instruction::ChkSig, Instruction::ChkSig]; + assert_eq!(has_expensive_opcodes(&unexpensive_script), false); +}