From ad02ba85c17c65fbde35973c6fce424190a52883 Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Fri, 30 Nov 2018 03:32:23 +0000 Subject: [PATCH] fix: fix missing output lock hash For some reason I forgot to add logic for fetching output cell lock hash in VM syscalls, which is in fact possible to fetch. --- script/src/syscalls/fetch_script_hash.rs | 2 +- script/src/syscalls/mod.rs | 39 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/script/src/syscalls/fetch_script_hash.rs b/script/src/syscalls/fetch_script_hash.rs index 64ecc0a136..cb20a8575a 100644 --- a/script/src/syscalls/fetch_script_hash.rs +++ b/script/src/syscalls/fetch_script_hash.rs @@ -42,7 +42,7 @@ impl<'a> FetchScriptHash<'a> { .map(|contract| contract.type_hash()) }) } - (Source::OUTPUT, Category::LOCK) => None, + (Source::OUTPUT, Category::LOCK) => self.outputs.get(index).map(|output| output.lock), (Source::OUTPUT, Category::CONTRACT) => self.outputs.get(index).and_then(|output| { output .contract diff --git a/script/src/syscalls/mod.rs b/script/src/syscalls/mod.rs index 8886db48f1..e8ca2b76a3 100644 --- a/script/src/syscalls/mod.rs +++ b/script/src/syscalls/mod.rs @@ -427,6 +427,45 @@ mod tests { } } + fn _test_fetch_script_hash_output_lock(data: Vec) { + let mut machine = DefaultCoreMachine::::default(); + let size_addr = 0; + let addr = 100; + + machine.registers_mut()[A0] = addr; // addr + machine.registers_mut()[A1] = size_addr; // size_addr + machine.registers_mut()[A2] = 0; // index + machine.registers_mut()[A3] = 1; // source: 1 output + machine.registers_mut()[A4] = 0; // category: 0 lock + machine.registers_mut()[A7] = FETCH_SCRIPT_HASH_SYSCALL_NUMBER; // syscall number + + assert!(machine.memory_mut().store64(size_addr as usize, 32).is_ok()); + + let script = Script::new(0, Vec::new(), None, Some(data), Vec::new()); + let output = CellOutput::new(0, Vec::new(), script.type_hash(), None); + let inputs = Vec::new(); + let input_cells = Vec::new(); + let outputs = vec![&output]; + + let mut fetch_script_hash = + FetchScriptHash::new(&outputs, &inputs, &input_cells, H256::from(0)); + + assert!(fetch_script_hash.ecall(&mut machine).is_ok()); + assert_eq!(machine.registers()[A0], SUCCESS as u64); + + let hash = &script.type_hash(); + for (i, addr) in (addr as usize..addr as usize + hash.len()).enumerate() { + assert_eq!(machine.memory_mut().load8(addr), Ok(hash[i])) + } + } + + proptest! { + #[test] + fn test_fetch_script_hash_output_lock(data in any_with::>(size_range(1000).lift())) { + _test_fetch_script_hash_output_lock(data); + } + } + fn _test_fetch_script_hash_output_contract(data: Vec) { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0;