Cap Move program's execution (#5259)

This commit is contained in:
Jack May 2019-07-24 08:06:03 -07:00 committed by GitHub
parent d4d9bec2a9
commit 7afc61e0b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 54 additions and 11 deletions

View File

@ -10,10 +10,13 @@ use solana_sdk::{
};
use types::{
account_address::AccountAddress,
transaction::{TransactionArgument, TransactionOutput, TransactionStatus},
transaction::{TransactionArgument, TransactionOutput},
};
use vm::{
access::ModuleAccess, file_format::CompiledScript, transaction_metadata::TransactionMetadata,
access::ModuleAccess,
file_format::CompiledScript,
gas_schedule::{MAXIMUM_NUMBER_OF_GAS_UNITS, MAX_PRICE_PER_GAS_UNIT},
transaction_metadata::TransactionMetadata,
};
use vm_cache_map::Arena;
use vm_runtime::{
@ -71,11 +74,18 @@ pub struct MoveProcessor {}
impl MoveProcessor {
#[allow(clippy::needless_pass_by_value)]
fn map_vm_runtime_error(err: vm::errors::VMRuntimeError) -> InstructionError {
error!("Move VM Error: {:?}", err);
error!("Execution failed: {:?}", err);
match err.err {
vm::errors::VMErrorKind::OutOfGasError => InstructionError::InsufficientFunds,
_ => InstructionError::GenericError,
}
}
fn map_vm_invariant_violation_error(err: vm::errors::VMInvariantViolation) -> InstructionError {
error!("Execution failed: {:?}", err);
InstructionError::GenericError
}
fn map_vm_binary_error(err: vm::errors::BinaryError) -> InstructionError {
error!("Move VM Error: {:?}", err);
error!("Script deserialize failed: {:?}", err);
InstructionError::GenericError
}
#[allow(clippy::needless_pass_by_value)]
@ -120,15 +130,21 @@ impl MoveProcessor {
let mut txn_metadata = TransactionMetadata::default();
txn_metadata.sender = invoke_info.sender_address;
// Caps execution to the Libra prescribed 10 milliseconds
txn_metadata.max_gas_amount = *MAXIMUM_NUMBER_OF_GAS_UNITS;
txn_metadata.gas_unit_price = *MAX_PRICE_PER_GAS_UNIT;
let mut vm = TransactionExecutor::new(&module_cache, data_store, txn_metadata);
let result = vm.execute_function(
vm.execute_function(
&module_id,
&invoke_info.function_name,
Self::arguments_to_locals(invoke_info.args),
);
)
.map_err(Self::map_vm_invariant_violation_error)?
.map_err(Self::map_vm_runtime_error)?;
Ok(vm
.make_write_set(vec![], result)
.make_write_set(vec![], Ok(Ok(())))
.map_err(Self::map_vm_runtime_error)?)
}
@ -229,10 +245,6 @@ impl MoveProcessor {
for event in output.events() {
debug!("Event: {:?}", event);
}
if let TransactionStatus::Discard(status) = output.status() {
error!("Execution failed: {:?}", status);
return Err(InstructionError::GenericError);
}
data_store.apply_write_set(&output.write_set());
// Break data store into a list of address keyed WriteSets
@ -295,6 +307,37 @@ mod tests {
.unwrap();
}
#[test]
fn test_invoke_endless_loop() {
solana_logger::setup();
let code = "
main() {
loop {}
return;
}
";
let mut program = LibraAccount::create_program(&AccountAddress::default(), code);
let mut genesis = LibraAccount::create_genesis();
let mut keyed_accounts = vec![
KeyedAccount::new(&program.key, false, &mut program.account),
KeyedAccount::new(&genesis.key, false, &mut genesis.account),
];
let invoke_info = InvokeInfo {
sender_address: AccountAddress::default(),
function_name: "main".to_string(),
args: vec![],
};
assert_eq!(
MoveProcessor::do_invoke_main(
&mut keyed_accounts,
bincode::serialize(&invoke_info).unwrap(),
),
Err(InstructionError::InsufficientFunds)
);
}
#[test]
fn test_invoke_mint_to_address() {
solana_logger::setup();