From 5fe717cd996cf1b6c92760aef4e2ee6270d5a46c Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Fri, 22 May 2020 13:48:32 +0300 Subject: [PATCH] move some executor-only code to executor.rs --- crates/dialects/lang/src/dfina/executor.rs | 121 +++++++++++++++++++-- crates/dialects/lang/src/dfina/mod.rs | 116 +------------------- crates/dialects/lang/src/libra/executor.rs | 121 +++++++++++++++++++-- crates/dialects/lang/src/libra/mod.rs | 116 +------------------- 4 files changed, 232 insertions(+), 242 deletions(-) diff --git a/crates/dialects/lang/src/dfina/executor.rs b/crates/dialects/lang/src/dfina/executor.rs index 15f2771b..6f2f1bd7 100644 --- a/crates/dialects/lang/src/dfina/executor.rs +++ b/crates/dialects/lang/src/dfina/executor.rs @@ -1,19 +1,125 @@ +use std::collections::BTreeMap; + use anyhow::{Context, Result}; +use dfin_language_e2e_tests::data_store::FakeDataStore; +use dfin_libra_types::access_path::AccessPath; use dfin_libra_types::{ transaction::{parse_as_transaction_argument, TransactionArgument}, - vm_error::StatusCode, + vm_error::{StatusCode, VMStatus}, write_set::{WriteOp, WriteSet}, }; use dfin_move_core_types::account_address::AccountAddress; +use dfin_move_core_types::gas_schedule::{GasAlgebra, GasUnits}; +use dfin_move_lang::{compiled_unit::CompiledUnit, errors::Error, shared::Address, to_bytecode}; +use dfin_move_vm_runtime::MoveVM; +use dfin_move_vm_state::execution_context::SystemExecutionContext; use dfin_move_vm_types::loaded_data::types::FatStructType; +use dfin_move_vm_types::{ + gas_schedule::zero_cost_schedule, transaction_metadata::TransactionMetadata, +}; use dfin_move_vm_types::{values::GlobalValue, values::Value}; use dfin_vm::errors::{vm_error, Location, VMResult}; +use dfin_vm::file_format::CompiledScript; +use dfin_vm::CompiledModule; -use shared::results::ResourceChange; +use shared::errors::ExecCompilerError; +use shared::results::{ExecResult, ExecutionError, ResourceChange}; use utils::FilePath; use crate::dfina::resources::{ResourceStructType, ResourceWriteOp}; -use crate::dfina::vm_status_into_exec_status; +use crate::dfina::{check_defs, into_exec_compiler_error, parse_files, PreBytecodeProgram}; + +type ResourcesBTreeMap = BTreeMap>; + +fn vm_status_into_exec_status(vm_status: VMStatus) -> ExecutionError { + ExecutionError { + status: format!("{:?}", vm_status.major_status), + sub_status: vm_status.sub_status, + message: vm_status.message, + } +} + +pub fn generate_bytecode( + program: PreBytecodeProgram, +) -> Result<(CompiledScript, Vec), Vec> { + let mut units = to_bytecode::translate::program(program)?; + let script = match units.remove(units.len() - 1) { + CompiledUnit::Script { script, .. } => script, + CompiledUnit::Module { .. } => unreachable!(), + }; + let modules = units + .into_iter() + .map(|unit| match unit { + CompiledUnit::Module { module, .. } => module, + CompiledUnit::Script { .. } => unreachable!(), + }) + .collect(); + Ok((script, modules)) +} + +pub fn check_and_generate_bytecode( + fname: FilePath, + text: &str, + deps: &[(FilePath, String)], + sender: AccountAddress, +) -> Result<(CompiledScript, Vec), ExecCompilerError> { + let (mut script_defs, modules_defs, project_offsets_map) = + parse_files((fname, text.to_owned()), deps, format!("0x{}", sender))?; + script_defs.extend(modules_defs); + + let sender = Address::new(sender.into()); + let program = check_defs(script_defs, vec![], sender) + .map_err(|errors| into_exec_compiler_error(errors, project_offsets_map.clone()))?; + generate_bytecode(program) + .map_err(|errors| into_exec_compiler_error(errors, project_offsets_map)) +} + +pub fn serialize_script(script: CompiledScript) -> Result> { + let mut serialized = vec![]; + script.serialize(&mut serialized)?; + Ok(serialized) +} + +pub fn prepare_fake_network_state( + modules: Vec, + genesis_write_set: WriteSet, +) -> FakeDataStore { + let mut network_state = FakeDataStore::default(); + for module in modules { + network_state.add_module(&module.self_id(), &module); + } + network_state.add_write_set(&genesis_write_set); + network_state +} + +fn get_transaction_metadata(sender_address: AccountAddress) -> TransactionMetadata { + let mut metadata = TransactionMetadata::default(); + metadata.sender = sender_address; + metadata +} + +pub fn execute_script( + sender_address: AccountAddress, + data_store: &FakeDataStore, + script: Vec, + args: Vec, +) -> ExecResult { + let mut exec_context = SystemExecutionContext::new(data_store, GasUnits::new(1_000_000)); + let zero_cost_table = zero_cost_schedule(); + let txn_metadata = get_transaction_metadata(sender_address); + + let vm = MoveVM::new(); + vm.execute_script( + script, + &zero_cost_table, + &mut exec_context, + &txn_metadata, + vec![], + args, + ) + .map_err(vm_status_into_exec_status)?; + Ok(exec_context.data_map()) +} fn convert_set_value(struct_type: FatStructType, val: GlobalValue) -> VMResult { // into_owned_struct will check if all references are properly released at the end of a transaction @@ -54,13 +160,12 @@ pub fn compile_and_run( let (fname, script_text) = script; let (compiled_script, compiled_modules) = - crate::dfina::check_and_generate_bytecode(fname, &script_text, deps, sender)?; + check_and_generate_bytecode(fname, &script_text, deps, sender)?; - let network_state = - crate::dfina::prepare_fake_network_state(compiled_modules, genesis_write_set); + let network_state = prepare_fake_network_state(compiled_modules, genesis_write_set); let serialized_script = - crate::dfina::serialize_script(compiled_script).context("Script serialization error")?; + serialize_script(compiled_script).context("Script serialization error")?; let mut script_args = Vec::with_capacity(args.len()); for passed_arg in args { @@ -69,7 +174,7 @@ pub fn compile_and_run( script_args.push(script_arg); } let changed_resources = - crate::dfina::execute_script(sender, &network_state, serialized_script, script_args)?; + execute_script(sender, &network_state, serialized_script, script_args)?; let mut changes = vec![]; for (_, global_val) in changed_resources { diff --git a/crates/dialects/lang/src/dfina/mod.rs b/crates/dialects/lang/src/dfina/mod.rs index 22a10465..80fb3005 100644 --- a/crates/dialects/lang/src/dfina/mod.rs +++ b/crates/dialects/lang/src/dfina/mod.rs @@ -1,41 +1,23 @@ -use std::collections::BTreeMap; +use std::path::PathBuf; use anyhow::Result; use codespan::ByteIndex; -use dfin_language_e2e_tests::data_store::FakeDataStore; -use dfin_libra_types::{ - access_path::AccessPath, account_address::AccountAddress, vm_error::VMStatus, - write_set::WriteSet, -}; -use dfin_move_core_types::gas_schedule::{GasAlgebra, GasUnits}; +use dfin_libra_types::account_address::AccountAddress; use dfin_move_ir_types::location::Loc; use dfin_move_lang::{ cfgir, - compiled_unit::CompiledUnit, errors::{Error, FilesSourceText}, parser, parser::ast::Definition, parser::syntax, shared::Address, - strip_comments_and_verify, to_bytecode, + strip_comments_and_verify, }; -use dfin_move_vm_runtime::MoveVM; -use dfin_move_vm_state::execution_context::SystemExecutionContext; -use dfin_move_vm_types::{ - gas_schedule::zero_cost_schedule, - loaded_data::types::FatStructType, - transaction_metadata::TransactionMetadata, - values::{GlobalValue, Value}, -}; -use dfin_vm::file_format::CompiledScript; -use dfin_vm::CompiledModule; use shared::bech32; use shared::errors::{ CompilerError, CompilerErrorPart, ExecCompilerError, Location, OffsetsMap, ProjectOffsetsMap, }; -use shared::results::{ExecResult, ExecutionError}; -use std::path::PathBuf; use utils::FilePath; pub mod executor; @@ -190,80 +172,6 @@ pub fn parse_files( Ok((script_defs, dep_defs, project_offsets_map)) } -pub fn check_and_generate_bytecode( - fname: FilePath, - text: &str, - deps: &[(FilePath, String)], - sender: AccountAddress, -) -> Result<(CompiledScript, Vec), ExecCompilerError> { - let (mut script_defs, modules_defs, project_offsets_map) = - parse_files((fname, text.to_owned()), deps, format!("0x{}", sender))?; - script_defs.extend(modules_defs); - - let sender = Address::new(sender.into()); - let program = check_defs(script_defs, vec![], sender) - .map_err(|errors| into_exec_compiler_error(errors, project_offsets_map.clone()))?; - generate_bytecode(program) - .map_err(|errors| into_exec_compiler_error(errors, project_offsets_map)) -} - -pub fn serialize_script(script: CompiledScript) -> Result> { - let mut serialized = vec![]; - script.serialize(&mut serialized)?; - Ok(serialized) -} - -pub fn prepare_fake_network_state( - modules: Vec, - genesis_write_set: WriteSet, -) -> FakeDataStore { - let mut network_state = FakeDataStore::default(); - for module in modules { - network_state.add_module(&module.self_id(), &module); - } - network_state.add_write_set(&genesis_write_set); - network_state -} - -fn get_transaction_metadata(sender_address: AccountAddress) -> TransactionMetadata { - let mut metadata = TransactionMetadata::default(); - metadata.sender = sender_address; - metadata -} - -type ChangedMoveResources = BTreeMap>; - -fn vm_status_into_exec_status(vm_status: VMStatus) -> ExecutionError { - ExecutionError { - status: format!("{:?}", vm_status.major_status), - sub_status: vm_status.sub_status, - message: vm_status.message, - } -} - -pub fn execute_script( - sender_address: AccountAddress, - data_store: &FakeDataStore, - script: Vec, - args: Vec, -) -> ExecResult { - let mut exec_context = SystemExecutionContext::new(data_store, GasUnits::new(1_000_000)); - let zero_cost_table = zero_cost_schedule(); - let txn_metadata = get_transaction_metadata(sender_address); - - let vm = MoveVM::new(); - vm.execute_script( - script, - &zero_cost_table, - &mut exec_context, - &txn_metadata, - vec![], - args, - ) - .map_err(vm_status_into_exec_status)?; - Ok(exec_context.data_map()) -} - type PreBytecodeProgram = cfgir::ast::Program; pub fn check_defs( @@ -278,24 +186,6 @@ pub fn check_defs( dfin_move_lang::check_program(Ok(ast_program), Some(sender)) } -pub fn generate_bytecode( - program: PreBytecodeProgram, -) -> Result<(CompiledScript, Vec), Vec> { - let mut units = to_bytecode::translate::program(program)?; - let script = match units.remove(units.len() - 1) { - CompiledUnit::Script { script, .. } => script, - CompiledUnit::Module { .. } => unreachable!(), - }; - let modules = units - .into_iter() - .map(|unit| match unit { - CompiledUnit::Module { module, .. } => module, - CompiledUnit::Script { .. } => unreachable!(), - }) - .collect(); - Ok((script, modules)) -} - pub fn parse_account_address(s: &str) -> Result { AccountAddress::from_hex_literal(s) } diff --git a/crates/dialects/lang/src/libra/executor.rs b/crates/dialects/lang/src/libra/executor.rs index dec63975..203e63e7 100644 --- a/crates/dialects/lang/src/libra/executor.rs +++ b/crates/dialects/lang/src/libra/executor.rs @@ -1,19 +1,125 @@ +use std::collections::BTreeMap; + use anyhow::{Context, Result}; +use orig_language_e2e_tests::data_store::FakeDataStore; +use orig_libra_types::access_path::AccessPath; use orig_libra_types::{ transaction::{parse_as_transaction_argument, TransactionArgument}, - vm_error::StatusCode, + vm_error::{StatusCode, VMStatus}, write_set::{WriteOp, WriteSet}, }; use orig_move_core_types::account_address::AccountAddress; +use orig_move_core_types::gas_schedule::{GasAlgebra, GasUnits}; +use orig_move_lang::{compiled_unit::CompiledUnit, errors::Error, shared::Address, to_bytecode}; +use orig_move_vm_runtime::MoveVM; +use orig_move_vm_state::execution_context::SystemExecutionContext; use orig_move_vm_types::loaded_data::types::FatStructType; +use orig_move_vm_types::{ + gas_schedule::zero_cost_schedule, transaction_metadata::TransactionMetadata, +}; use orig_move_vm_types::{values::GlobalValue, values::Value}; use orig_vm::errors::{vm_error, Location, VMResult}; +use orig_vm::file_format::CompiledScript; +use orig_vm::CompiledModule; -use shared::results::ResourceChange; +use shared::errors::ExecCompilerError; +use shared::results::{ExecResult, ExecutionError, ResourceChange}; use utils::FilePath; use crate::libra::resources::{ResourceStructType, ResourceWriteOp}; -use crate::libra::vm_status_into_exec_status; +use crate::libra::{check_defs, into_exec_compiler_error, parse_files, PreBytecodeProgram}; + +type ResourcesBTreeMap = BTreeMap>; + +fn vm_status_into_exec_status(vm_status: VMStatus) -> ExecutionError { + ExecutionError { + status: format!("{:?}", vm_status.major_status), + sub_status: vm_status.sub_status, + message: vm_status.message, + } +} + +pub fn generate_bytecode( + program: PreBytecodeProgram, +) -> Result<(CompiledScript, Vec), Vec> { + let mut units = to_bytecode::translate::program(program)?; + let script = match units.remove(units.len() - 1) { + CompiledUnit::Script { script, .. } => script, + CompiledUnit::Module { .. } => unreachable!(), + }; + let modules = units + .into_iter() + .map(|unit| match unit { + CompiledUnit::Module { module, .. } => module, + CompiledUnit::Script { .. } => unreachable!(), + }) + .collect(); + Ok((script, modules)) +} + +pub fn check_and_generate_bytecode( + fname: FilePath, + text: &str, + deps: &[(FilePath, String)], + sender: AccountAddress, +) -> Result<(CompiledScript, Vec), ExecCompilerError> { + let (mut script_defs, modules_defs, project_offsets_map) = + parse_files((fname, text.to_owned()), deps, format!("0x{}", sender))?; + script_defs.extend(modules_defs); + + let sender = Address::new(sender.into()); + let program = check_defs(script_defs, vec![], sender) + .map_err(|errors| into_exec_compiler_error(errors, project_offsets_map.clone()))?; + generate_bytecode(program) + .map_err(|errors| into_exec_compiler_error(errors, project_offsets_map)) +} + +pub fn serialize_script(script: CompiledScript) -> Result> { + let mut serialized = vec![]; + script.serialize(&mut serialized)?; + Ok(serialized) +} + +pub fn prepare_fake_network_state( + modules: Vec, + genesis_write_set: WriteSet, +) -> FakeDataStore { + let mut network_state = FakeDataStore::default(); + for module in modules { + network_state.add_module(&module.self_id(), &module); + } + network_state.add_write_set(&genesis_write_set); + network_state +} + +fn get_transaction_metadata(sender_address: AccountAddress) -> TransactionMetadata { + let mut metadata = TransactionMetadata::default(); + metadata.sender = sender_address; + metadata +} + +pub fn execute_script( + sender_address: AccountAddress, + data_store: &FakeDataStore, + script: Vec, + args: Vec, +) -> ExecResult { + let mut exec_context = SystemExecutionContext::new(data_store, GasUnits::new(1_000_000)); + let zero_cost_table = zero_cost_schedule(); + let txn_metadata = get_transaction_metadata(sender_address); + + let vm = MoveVM::new(); + vm.execute_script( + script, + &zero_cost_table, + &mut exec_context, + &txn_metadata, + vec![], + args, + ) + .map_err(vm_status_into_exec_status)?; + Ok(exec_context.data_map()) +} fn convert_set_value(struct_type: FatStructType, val: GlobalValue) -> VMResult { // into_owned_struct will check if all references are properly released at the end of a transaction @@ -54,13 +160,12 @@ pub fn compile_and_run( let (fname, script_text) = script; let (compiled_script, compiled_modules) = - crate::libra::check_and_generate_bytecode(fname, &script_text, deps, sender)?; + check_and_generate_bytecode(fname, &script_text, deps, sender)?; - let network_state = - crate::libra::prepare_fake_network_state(compiled_modules, genesis_write_set); + let network_state = prepare_fake_network_state(compiled_modules, genesis_write_set); let serialized_script = - crate::libra::serialize_script(compiled_script).context("Script serialization error")?; + serialize_script(compiled_script).context("Script serialization error")?; let mut script_args = Vec::with_capacity(args.len()); for passed_arg in args { @@ -69,7 +174,7 @@ pub fn compile_and_run( script_args.push(script_arg); } let changed_resources = - crate::libra::execute_script(sender, &network_state, serialized_script, script_args)?; + execute_script(sender, &network_state, serialized_script, script_args)?; let mut changes = vec![]; for (_, global_val) in changed_resources { diff --git a/crates/dialects/lang/src/libra/mod.rs b/crates/dialects/lang/src/libra/mod.rs index 4c9e18bc..45b4b7b6 100644 --- a/crates/dialects/lang/src/libra/mod.rs +++ b/crates/dialects/lang/src/libra/mod.rs @@ -1,41 +1,23 @@ -use std::collections::BTreeMap; +use std::path::PathBuf; use anyhow::Result; use codespan::ByteIndex; -use orig_language_e2e_tests::data_store::FakeDataStore; -use orig_libra_types::{ - access_path::AccessPath, account_address::AccountAddress, vm_error::VMStatus, - write_set::WriteSet, -}; -use orig_move_core_types::gas_schedule::{GasAlgebra, GasUnits}; +use orig_libra_types::account_address::AccountAddress; use orig_move_ir_types::location::Loc; use orig_move_lang::{ cfgir, - compiled_unit::CompiledUnit, errors::{Error, FilesSourceText}, parser, parser::ast::Definition, parser::syntax, shared::Address, - strip_comments_and_verify, to_bytecode, + strip_comments_and_verify, }; -use orig_move_vm_runtime::MoveVM; -use orig_move_vm_state::execution_context::SystemExecutionContext; -use orig_move_vm_types::{ - gas_schedule::zero_cost_schedule, - loaded_data::types::FatStructType, - transaction_metadata::TransactionMetadata, - values::{GlobalValue, Value}, -}; -use orig_vm::file_format::CompiledScript; -use orig_vm::CompiledModule; use shared::bech32; use shared::errors::{ CompilerError, CompilerErrorPart, ExecCompilerError, Location, OffsetsMap, ProjectOffsetsMap, }; -use shared::results::{ExecResult, ExecutionError}; -use std::path::PathBuf; use utils::FilePath; pub mod executor; @@ -190,80 +172,6 @@ pub fn parse_files( Ok((script_defs, dep_defs, project_offsets_map)) } -pub fn check_and_generate_bytecode( - fname: FilePath, - text: &str, - deps: &[(FilePath, String)], - sender: AccountAddress, -) -> Result<(CompiledScript, Vec), ExecCompilerError> { - let (mut script_defs, modules_defs, project_offsets_map) = - parse_files((fname, text.to_owned()), deps, format!("0x{}", sender))?; - script_defs.extend(modules_defs); - - let sender = Address::new(sender.into()); - let program = check_defs(script_defs, vec![], sender) - .map_err(|errors| into_exec_compiler_error(errors, project_offsets_map.clone()))?; - generate_bytecode(program) - .map_err(|errors| into_exec_compiler_error(errors, project_offsets_map)) -} - -pub fn serialize_script(script: CompiledScript) -> Result> { - let mut serialized = vec![]; - script.serialize(&mut serialized)?; - Ok(serialized) -} - -pub fn prepare_fake_network_state( - modules: Vec, - genesis_write_set: WriteSet, -) -> FakeDataStore { - let mut network_state = FakeDataStore::default(); - for module in modules { - network_state.add_module(&module.self_id(), &module); - } - network_state.add_write_set(&genesis_write_set); - network_state -} - -fn get_transaction_metadata(sender_address: AccountAddress) -> TransactionMetadata { - let mut metadata = TransactionMetadata::default(); - metadata.sender = sender_address; - metadata -} - -type ChangedMoveResources = BTreeMap>; - -fn vm_status_into_exec_status(vm_status: VMStatus) -> ExecutionError { - ExecutionError { - status: format!("{:?}", vm_status.major_status), - sub_status: vm_status.sub_status, - message: vm_status.message, - } -} - -pub fn execute_script( - sender_address: AccountAddress, - data_store: &FakeDataStore, - script: Vec, - args: Vec, -) -> ExecResult { - let mut exec_context = SystemExecutionContext::new(data_store, GasUnits::new(1_000_000)); - let zero_cost_table = zero_cost_schedule(); - let txn_metadata = get_transaction_metadata(sender_address); - - let vm = MoveVM::new(); - vm.execute_script( - script, - &zero_cost_table, - &mut exec_context, - &txn_metadata, - vec![], - args, - ) - .map_err(vm_status_into_exec_status)?; - Ok(exec_context.data_map()) -} - type PreBytecodeProgram = cfgir::ast::Program; pub fn check_defs( @@ -278,24 +186,6 @@ pub fn check_defs( orig_move_lang::check_program(Ok(ast_program), Some(sender)) } -pub fn generate_bytecode( - program: PreBytecodeProgram, -) -> Result<(CompiledScript, Vec), Vec> { - let mut units = to_bytecode::translate::program(program)?; - let script = match units.remove(units.len() - 1) { - CompiledUnit::Script { script, .. } => script, - CompiledUnit::Module { .. } => unreachable!(), - }; - let modules = units - .into_iter() - .map(|unit| match unit { - CompiledUnit::Module { module, .. } => module, - CompiledUnit::Script { .. } => unreachable!(), - }) - .collect(); - Ok((script, modules)) -} - pub fn parse_account_address(s: &str) -> Result { AccountAddress::from_hex_literal(s) }