From 2bf3dc7e606d73198a1dc624af81fcede8fbe927 Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Fri, 23 Oct 2020 16:13:51 +0300 Subject: [PATCH] allow to specify current time --- executor/src/execution.rs | 14 +++++++++++--- executor/src/explain.rs | 23 +++++++++++++++++------ executor/src/meta.rs | 2 ++ executor/src/oracles.rs | 9 +++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/executor/src/execution.rs b/executor/src/execution.rs index d70c8e1e..925b1fbf 100644 --- a/executor/src/execution.rs +++ b/executor/src/execution.rs @@ -16,7 +16,7 @@ use vm::file_format::{CompiledScript, FunctionDefinitionIndex}; use crate::explain::{explain_effects, explain_error, StepExecutionResult}; use crate::meta::ExecutionMeta; -use crate::oracles::oracle_coins_module; +use crate::oracles::{oracle_coins_module, time_metadata}; #[derive(Debug, Default, Clone)] pub struct FakeRemoteCache { @@ -144,6 +144,7 @@ pub fn execute_script( let ExecutionMeta { signers, oracle_prices, + current_time, .. } = meta; if !oracle_prices.is_empty() { @@ -154,10 +155,17 @@ pub fn execute_script( )); } } + let std_addr = AccountAddress::from_hex_literal("0x1").expect("Standart address"); + + if let Some(current_time) = current_time { + ds.resources.insert( + (std_addr, time_metadata()), + lcs::to_bytes(¤t_time).unwrap(), + ); + } for (price_tag, val) in oracle_prices { - let addr = AccountAddress::from_hex_literal("0x1").expect("Standart address"); ds.resources - .insert((addr, price_tag), lcs::to_bytes(&val).unwrap()); + .insert((std_addr, price_tag), lcs::to_bytes(&val).unwrap()); } let res = execute_script_with_runtime_session( diff --git a/executor/src/explain.rs b/executor/src/explain.rs index 71f7444e..16e99ca5 100644 --- a/executor/src/explain.rs +++ b/executor/src/explain.rs @@ -176,11 +176,13 @@ pub fn explain_effects( // pub const ERROR_DESCRIPTIONS: &[u8] = include_bytes!("./error_descriptions/error_descriptions.errmap"); fn explain_type_error( + text_representation: &mut String, script: &CompiledScript, signers: &[AccountAddress], txn_args: &[TransactionArgument], ) { use vm::file_format::SignatureToken::*; + let script_params = script.signature_at(script.as_inner().parameters); let expected_num_signers = script_params .0 @@ -191,30 +193,37 @@ fn explain_type_error( }) .count(); if expected_num_signers != signers.len() { - println!( + writeln!( + text_representation, "Execution failed with incorrect number of signers: script expected {:?}, but found \ {:?}", expected_num_signers, signers.len() - ); + ) + .unwrap(); return; } // TODO: printing type(s) of missing arguments could be useful let expected_num_args = script_params.len() - signers.len(); if expected_num_args != txn_args.len() { - println!( + writeln!( + text_representation, "Execution failed with incorrect number of arguments: script expected {:?}, but found \ {:?}", expected_num_args, txn_args.len() - ); + ).unwrap(); return; } // TODO: print more helpful error message pinpointing the (argument, type) // pair that didn't match - println!("Execution failed with type error when binding type arguments to type parameters") + writeln!( + text_representation, + "Execution failed with type error when binding type arguments to type parameters" + ) + .unwrap(); } /// Explain an execution error @@ -282,7 +291,9 @@ pub fn explain_error( ) .unwrap(); } - VMStatus::Error(StatusCode::TYPE_MISMATCH) => explain_type_error(script, signers, &[]), + VMStatus::Error(StatusCode::TYPE_MISMATCH) => { + explain_type_error(&mut text_representation, script, signers, &[]) + } VMStatus::Error(status_code) => write!( &mut text_representation, "Execution failed with unexpected error {:?}", diff --git a/executor/src/meta.rs b/executor/src/meta.rs index 03f48e85..2a1a0c81 100644 --- a/executor/src/meta.rs +++ b/executor/src/meta.rs @@ -15,6 +15,7 @@ pub struct ExecutionMeta { pub signers: Vec, pub max_gas: u64, pub oracle_prices: Vec<(StructTag, u128)>, + pub current_time: Option, } impl ExecutionMeta { @@ -45,6 +46,7 @@ impl ExecutionMeta { self.oracle_prices .push((price_struct_tag, value.parse().unwrap())) } + "current_time" => self.current_time = Some(val.parse().unwrap()), _ => eprintln!("Unimplemented meta key, {:?}", key), } } diff --git a/executor/src/oracles.rs b/executor/src/oracles.rs index f026b02a..03e09ad1 100644 --- a/executor/src/oracles.rs +++ b/executor/src/oracles.rs @@ -48,3 +48,12 @@ pub fn oracle_metadata(first: &str, second: &str) -> StructTag { type_params: vec![currency_type(first), currency_type(second)], } } + +pub fn time_metadata() -> StructTag { + StructTag { + address: CORE_CODE_ADDRESS, + name: Identifier::new("CurrentTimestamp").expect("Valid module name."), + module: Identifier::new("Time").expect("Valid module name."), + type_params: vec![], + } +}