Update libra to new fork (#6523) (#6601)

automerge
This commit is contained in:
mergify[bot]
2019-10-29 14:04:02 -07:00
committed by Grimes
parent 22d60d496b
commit c5a98a5b57
11 changed files with 838 additions and 978 deletions

1532
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -76,7 +76,7 @@ fn test_bench_tps_local_cluster_solana() {
fn test_bench_tps_local_cluster_move() { fn test_bench_tps_local_cluster_move() {
let mut config = Config::default(); let mut config = Config::default();
config.tx_count = 100; config.tx_count = 100;
config.duration = Duration::from_secs(20); config.duration = Duration::from_secs(30);
config.use_move = true; config.use_move = true;
test_bench_tps_local_cluster(config); test_bench_tps_local_cluster(config);

View File

@ -14,8 +14,8 @@ log = "0.4.8"
solana-logger = { path = "../../logger", version = "0.20.1" } solana-logger = { path = "../../logger", version = "0.20.1" }
solana-sdk = { path = "../../sdk", version = "0.20.1" } solana-sdk = { path = "../../sdk", version = "0.20.1" }
solana-runtime = { path = "../../runtime", version = "0.20.1" } solana-runtime = { path = "../../runtime", version = "0.20.1" }
types = { version = "0.0.0", package = "solana_libra_types" } types = { version = "0.0.1-sol4", package = "solana_libra_types" }
language_e2e_tests = { version = "0.0.0", package = "solana_libra_language_e2e_tests" } language_e2e_tests = { version = "0.0.1-sol4", package = "solana_libra_language_e2e_tests" }
solana-move-loader-api = { path = "../move_loader_api", version = "0.20.1" } solana-move-loader-api = { path = "../move_loader_api", version = "0.20.1" }
[lib] [lib]

View File

@ -23,7 +23,7 @@ use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction; use solana_sdk::system_instruction;
use types::account_address::AccountAddress; use types::account_config;
pub fn create_genesis<T: Client>(from_key: &Keypair, client: &T, amount: u64) -> Keypair { pub fn create_genesis<T: Client>(from_key: &Keypair, client: &T, amount: u64) -> Keypair {
let libra_genesis_key = Keypair::new(); let libra_genesis_key = Keypair::new();
@ -48,7 +48,7 @@ pub fn create_genesis<T: Client>(from_key: &Keypair, client: &T, amount: u64) ->
} }
pub fn upload_move_program<T: Client>(from: &Keypair, client: &T, code: &str) -> Pubkey { pub fn upload_move_program<T: Client>(from: &Keypair, client: &T, code: &str) -> Pubkey {
let address = AccountAddress::default(); let address = account_config::association_address();
let account_state = LibraAccountState::create_program(&address, code, vec![]); let account_state = LibraAccountState::create_program(&address, code, vec![]);
let program_bytes = bincode::serialize(&account_state).unwrap(); let program_bytes = bincode::serialize(&account_state).unwrap();

View File

@ -4,7 +4,7 @@ use solana_move_loader_api::processor::InvokeCommand;
use solana_sdk::instruction::{AccountMeta, Instruction}; use solana_sdk::instruction::{AccountMeta, Instruction};
use solana_sdk::loader_instruction::LoaderInstruction; use solana_sdk::loader_instruction::LoaderInstruction;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use types::account_address::AccountAddress; use types::account_config;
use types::transaction::TransactionArgument; use types::transaction::TransactionArgument;
pub fn genesis(genesis_pubkey: &Pubkey, microlibras: u64) -> Instruction { pub fn genesis(genesis_pubkey: &Pubkey, microlibras: u64) -> Instruction {
@ -28,7 +28,7 @@ pub fn mint(
]; ];
let data = bincode::serialize(&InvokeCommand::RunProgram { let data = bincode::serialize(&InvokeCommand::RunProgram {
sender_address: AccountAddress::default(), sender_address: account_config::association_address(),
function_name: "main".to_string(), function_name: "main".to_string(),
args, args,
}) })

View File

@ -1,5 +1,4 @@
use crate::librapay_instruction; use crate::librapay_instruction;
use language_e2e_tests::account::AccountResource;
use log::*; use log::*;
use solana_move_loader_api::account_state::{pubkey_to_address, LibraAccountState}; use solana_move_loader_api::account_state::{pubkey_to_address, LibraAccountState};
use solana_move_loader_api::data_store::DataStore; use solana_move_loader_api::data_store::DataStore;
@ -75,7 +74,7 @@ pub fn create_accounts(
&from.pubkey(), &from.pubkey(),
to, to,
lamports, lamports,
200, 400,
&solana_move_loader_api::id(), &solana_move_loader_api::id(),
) )
}) })
@ -128,7 +127,7 @@ pub fn get_libra_balance<T: Client>(
.read_account_resource(&pubkey_to_address(account_address)) .read_account_resource(&pubkey_to_address(account_address))
.unwrap(); .unwrap();
let res = AccountResource::read_balance(&resource); let res = resource.balance();
Ok(res) Ok(res)
} else { } else {
Ok(0) Ok(0)

View File

@ -21,16 +21,18 @@ serde_json = "1.0.41"
solana-logger = { path = "../../logger", version = "0.20.1" } solana-logger = { path = "../../logger", version = "0.20.1" }
solana-sdk = { path = "../../sdk", version = "0.20.1" } solana-sdk = { path = "../../sdk", version = "0.20.1" }
bytecode_verifier = { version = "0.0.0", package = "solana_libra_bytecode_verifier" } bytecode_verifier = { version = "0.0.1-sol4", package = "solana_libra_bytecode_verifier" }
compiler = { version = "0.0.0", package = "solana_libra_compiler" } canonical_serialization = { version = "0.0.1-sol4", package = "solana_libra_canonical_serialization" }
failure = { version = "0.0.0", package = "solana_libra_failure_ext" } compiler = { version = "0.0.1-sol4", package = "solana_libra_compiler" }
language_e2e_tests = { version = "0.0.0", package = "solana_libra_language_e2e_tests" } failure = { version = "0.0.1-sol4", package = "solana_libra_failure_ext" }
state_view = { version = "0.0.0", package = "solana_libra_state_view" } language_e2e_tests = { version = "0.0.1-sol4", package = "solana_libra_language_e2e_tests" }
stdlib = { version = "0.0.0", package = "solana_libra_stdlib" } state_view = { version = "0.0.1-sol4", package = "solana_libra_state_view" }
types = { version = "0.0.0", package = "solana_libra_types" } stdlib = { version = "0.0.1-sol4", package = "solana_libra_stdlib" }
vm = { version = "0.0.0", package = "solana_libra_vm" } types = { version = "0.0.1-sol4", package = "solana_libra_types" }
vm_cache_map = { version = "0.0.0", package = "solana_libra_vm_cache_map" } vm = { version = "0.0.1-sol4", package = "solana_libra_vm" }
vm_runtime = { version = "0.0.0", package = "solana_libra_vm_runtime" } vm_cache_map = { version = "0.0.1-sol4", package = "solana_libra_vm_cache_map" }
vm_runtime = { version = "0.0.1-sol4", package = "solana_libra_vm_runtime" }
vm_runtime_types = { version = "0.0.1-sol4", package = "solana_libra_vm_runtime_types" }
[lib] [lib]
crate-type = ["lib"] crate-type = ["lib"]

View File

@ -8,7 +8,9 @@ use std::convert::TryInto;
use stdlib::stdlib_modules; use stdlib::stdlib_modules;
use types::{ use types::{
account_address::AccountAddress, account_address::AccountAddress,
account_config,
byte_array::ByteArray, byte_array::ByteArray,
identifier::Identifier,
transaction::Program, transaction::Program,
write_set::{WriteOp, WriteSet}, write_set::{WriteOp, WriteSet},
}; };
@ -22,9 +24,9 @@ use vm_runtime::{
module_cache::{BlockModuleCache, VMModuleCache}, module_cache::{BlockModuleCache, VMModuleCache},
}, },
data_cache::BlockDataCache, data_cache::BlockDataCache,
txn_executor::{TransactionExecutor, ACCOUNT_MODULE, COIN_MODULE}, txn_executor::{TransactionExecutor, ACCOUNT_MODULE, BLOCK_MODULE, COIN_MODULE},
value::Local,
}; };
use vm_runtime_types::value::Value;
// Helper function that converts a Solana Pubkey to a Libra AccountAddress (WIP) // Helper function that converts a Solana Pubkey to a Libra AccountAddress (WIP)
pub fn pubkey_to_address(key: &Pubkey) -> AccountAddress { pub fn pubkey_to_address(key: &Pubkey) -> AccountAddress {
@ -87,11 +89,12 @@ impl LibraAccountState {
let compiler = Compiler { let compiler = Compiler {
address: *sender_address, address: *sender_address,
code,
extra_deps, extra_deps,
..Compiler::default() ..Compiler::default()
}; };
let compiled_program = compiler.into_compiled_program().expect("Failed to compile"); let compiled_program = compiler
.into_compiled_program(code)
.expect("Failed to compile");
let mut script_bytes = vec![]; let mut script_bytes = vec![];
compiled_program compiled_program
@ -120,10 +123,9 @@ impl LibraAccountState {
let arena = Arena::new(); let arena = Arena::new();
let state_view = DataStore::default(); let state_view = DataStore::default();
let vm_cache = VMModuleCache::new(&arena); let vm_cache = VMModuleCache::new(&arena);
// Libra enforces the mint address to be 0x0 (see Libra's `mint_to_address` function) let genesis_addr = account_config::association_address();
let mint_address = AccountAddress::default();
// TODO: Need this? // TODO: Need this?
let genesis_auth_key = ByteArray::new(mint_address.to_vec()); let genesis_auth_key = ByteArray::new(genesis_addr.to_vec());
let write_set = { let write_set = {
let fake_fetcher = let fake_fetcher =
@ -132,35 +134,55 @@ impl LibraAccountState {
let block_cache = BlockModuleCache::new(&vm_cache, fake_fetcher); let block_cache = BlockModuleCache::new(&vm_cache, fake_fetcher);
let mut txn_data = TransactionMetadata::default(); let mut txn_data = TransactionMetadata::default();
txn_data.sender = mint_address; txn_data.sender = genesis_addr;
let mut txn_executor = TransactionExecutor::new(&block_cache, &data_cache, txn_data); let mut txn_executor = TransactionExecutor::new(&block_cache, &data_cache, txn_data);
txn_executor.create_account(genesis_addr).unwrap();
txn_executor txn_executor
.create_account(mint_address) .create_account(account_config::core_code_address())
.map_err(map_vm_invariant_violation_error)? .map_err(map_err_vm_status)?;
.map_err(map_vm_runtime_error)?;
txn_executor txn_executor
.execute_function(&COIN_MODULE, "initialize", vec![]) .execute_function(
.map_err(map_vm_invariant_violation_error)? &BLOCK_MODULE,
.map_err(map_vm_runtime_error)?; &Identifier::new("initialize").unwrap(),
vec![],
)
.map_err(map_err_vm_status)?;
txn_executor
.execute_function(
&COIN_MODULE,
&Identifier::new("initialize").unwrap(),
vec![],
)
.map_err(map_err_vm_status)?;
txn_executor txn_executor
.execute_function( .execute_function(
&ACCOUNT_MODULE, &ACCOUNT_MODULE,
"mint_to_address", &Identifier::new("mint_to_address").unwrap(),
vec![Local::address(mint_address), Local::u64(mint_balance)], vec![Value::address(genesis_addr), Value::u64(mint_balance)],
) )
.map_err(map_vm_invariant_violation_error)? .map_err(map_err_vm_status)?;
.map_err(map_vm_runtime_error)?;
txn_executor txn_executor
.execute_function( .execute_function(
&ACCOUNT_MODULE, &ACCOUNT_MODULE,
"rotate_authentication_key", &Identifier::new("rotate_authentication_key").unwrap(),
vec![Local::bytearray(genesis_auth_key)], vec![Value::byte_array(genesis_auth_key)],
) )
.map_err(map_vm_invariant_violation_error)? .map_err(map_err_vm_status)?;
.map_err(map_vm_runtime_error)?;
// Bump the sequence number for the Association account. If we don't do this and a
// subsequent transaction (e.g., minting) is sent from the Association account, a problem
// arises: both the genesis transaction and the subsequent transaction have sequence
// number 0
txn_executor
.execute_function(
&ACCOUNT_MODULE,
&Identifier::new("epilogue").unwrap(),
vec![],
)
.map_err(map_err_vm_status)?;
let mut stdlib_modules = vec![]; let mut stdlib_modules = vec![];
for module in modules.iter() { for module in modules.iter() {
@ -170,8 +192,8 @@ impl LibraAccountState {
} }
txn_executor txn_executor
.make_write_set(stdlib_modules, Ok(Ok(()))) .make_write_set(stdlib_modules, Ok(()))
.map_err(map_vm_runtime_error)? .map_err(map_err_vm_status)?
.write_set() .write_set()
.clone() .clone()
.into_mut() .into_mut()

View File

@ -1,3 +1,4 @@
use canonical_serialization::SimpleDeserializer;
use failure::prelude::*; use failure::prelude::*;
use indexmap::IndexMap; use indexmap::IndexMap;
use log::*; use log::*;
@ -5,17 +6,12 @@ use state_view::StateView;
use types::{ use types::{
access_path::AccessPath, access_path::AccessPath,
account_address::AccountAddress, account_address::AccountAddress,
account_config, account_config::{self, AccountResource},
language_storage::ModuleId, language_storage::ModuleId,
write_set::{WriteOp, WriteSet, WriteSetMut}, write_set::{WriteOp, WriteSet, WriteSetMut},
}; };
use vm::{errors::VMInvariantViolation, CompiledModule}; use vm::{errors::VMResult, CompiledModule};
use vm_runtime::{ use vm_runtime::{data_cache::RemoteCache, identifier::create_access_path};
data_cache::RemoteCache,
identifier::create_access_path,
loaded_data::{struct_def::StructDef, types::Type},
value::Value,
};
/// An in-memory implementation of [`StateView`] and [`RemoteCache`] for the VM. /// An in-memory implementation of [`StateView`] and [`RemoteCache`] for the VM.
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -66,17 +62,11 @@ impl DataStore {
} }
/// Read an account's resource /// Read an account's resource
pub fn read_account_resource(&self, addr: &AccountAddress) -> Option<Value> { pub fn read_account_resource(&self, addr: &AccountAddress) -> Option<AccountResource> {
let access_path = create_access_path(&addr, account_config::account_struct_tag()); let access_path = create_access_path(&addr, account_config::account_struct_tag());
match self.data.get(&access_path) { match self.data.get(&access_path) {
None => None, None => None,
Some(blob) => { Some(blob) => SimpleDeserializer::deserialize(blob).ok(),
let account_type = get_account_struct_def();
match Value::simple_deserialize(blob, account_type) {
Ok(account) => Some(account),
Err(_) => None,
}
}
} }
} }
@ -134,32 +124,11 @@ impl StateView for DataStore {
} }
impl RemoteCache for DataStore { impl RemoteCache for DataStore {
fn get( fn get(&self, access_path: &AccessPath) -> VMResult<Option<Vec<u8>>> {
&self,
access_path: &AccessPath,
) -> ::std::result::Result<Option<Vec<u8>>, VMInvariantViolation> {
Ok(StateView::get(self, access_path).expect("it should not error")) Ok(StateView::get(self, access_path).expect("it should not error"))
} }
} }
// TODO: internal Libra function and very likely to break soon, need something better
fn get_account_struct_def() -> StructDef {
// STRUCT DEF StructDef(StructDefInner { field_definitions: [ByteArray,
// Struct(StructDef(StructDefInner { field_definitions: [U64] })), U64, U64,
// U64] }) let coin = StructDef(StructDefInner { field_definitions:
// [Type::U64] })
let int_type = Type::U64;
let byte_array_type = Type::ByteArray;
let coin = Type::Struct(StructDef::new(vec![int_type.clone()]));
StructDef::new(vec![
byte_array_type,
coin,
int_type.clone(),
int_type.clone(),
int_type.clone(),
])
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -2,24 +2,10 @@
use log::*; use log::*;
use solana_sdk::instruction::InstructionError; use solana_sdk::instruction::InstructionError;
use std::convert::TryInto;
use types::vm_error::{StatusCode, VMStatus};
use vm::file_format::CompiledModule; use vm::file_format::CompiledModule;
#[allow(clippy::needless_pass_by_value)]
pub fn map_vm_runtime_error(err: vm::errors::VMRuntimeError) -> InstructionError {
debug!("Execution failed: {:?}", err);
match err.err {
vm::errors::VMErrorKind::OutOfGasError => InstructionError::InsufficientFunds,
_ => InstructionError::GenericError,
}
}
pub fn map_vm_invariant_violation_error(err: vm::errors::VMInvariantViolation) -> InstructionError {
debug!("Error: Execution failed: {:?}", err);
InstructionError::GenericError
}
pub fn map_vm_binary_error(err: vm::errors::BinaryError) -> InstructionError {
debug!("Error: Script deserialize failed: {:?}", err);
InstructionError::InvalidInstructionData
}
#[allow(clippy::needless_pass_by_value)] #[allow(clippy::needless_pass_by_value)]
pub fn map_data_error(err: std::boxed::Box<bincode::ErrorKind>) -> InstructionError { pub fn map_data_error(err: std::boxed::Box<bincode::ErrorKind>) -> InstructionError {
debug!("Error: Account data: {:?}", err); debug!("Error: Account data: {:?}", err);
@ -28,23 +14,34 @@ pub fn map_data_error(err: std::boxed::Box<bincode::ErrorKind>) -> InstructionEr
_ => InstructionError::InvalidAccountData, _ => InstructionError::InvalidAccountData,
} }
} }
#[allow(clippy::needless_pass_by_value)] #[allow(clippy::needless_pass_by_value)]
pub fn map_json_error(err: serde_json::error::Error) -> InstructionError { pub fn map_json_error(err: serde_json::error::Error) -> InstructionError {
debug!("Error: serde_json: {:?}", err); debug!("Error: serde_json: {:?}", err);
InstructionError::InvalidAccountData InstructionError::InvalidAccountData
} }
pub fn map_vm_verification_error(
err: (CompiledModule, Vec<vm::errors::VerificationError>), pub fn map_vm_verification_error(err: (CompiledModule, Vec<VMStatus>)) -> InstructionError {
) -> InstructionError {
debug!("Error: Script verification failed: {:?}", err.1); debug!("Error: Script verification failed: {:?}", err.1);
InstructionError::InvalidInstructionData InstructionError::InvalidInstructionData
} }
pub fn map_failure_error(err: failure::Error) -> InstructionError {
debug!("Error: Script verification failed: {:?}", err);
InstructionError::InvalidInstructionData
}
#[allow(clippy::needless_pass_by_value)] #[allow(clippy::needless_pass_by_value)]
pub fn missing_account() -> InstructionError { pub fn missing_account() -> InstructionError {
debug!("Error: Missing account"); debug!("Error: Missing account");
InstructionError::InvalidAccountData InstructionError::InvalidAccountData
} }
pub fn map_failure_error(err: failure::Error) -> InstructionError {
debug!("Error: Script verification failed: {:?}", err);
InstructionError::InvalidInstructionData
}
pub fn map_err_vm_status(status: VMStatus) -> InstructionError {
// Attempt to map the StatusCode (repr(u64)) to a u32 for CustomError.
// The only defined StatusCode that fails is StatusCode::UNKNOWN_ERROR
match <StatusCode as Into<u64>>::into(status.major_status).try_into() {
Ok(u) => InstructionError::CustomError(u),
Err(_) => InstructionError::GenericError,
}
}

View File

@ -2,7 +2,7 @@ use crate::account_state::{pubkey_to_address, LibraAccountState, ModuleBytes};
use crate::data_store::DataStore; use crate::data_store::DataStore;
use crate::error_mappers::*; use crate::error_mappers::*;
use crate::id; use crate::id;
use bytecode_verifier::{VerifiedModule, VerifiedScript}; use bytecode_verifier::verifier::{VerifiedModule, VerifiedScript};
use log::*; use log::*;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use solana_sdk::{ use solana_sdk::{
@ -12,6 +12,8 @@ use solana_sdk::{
}; };
use types::{ use types::{
account_address::AccountAddress, account_address::AccountAddress,
account_config,
identifier::Identifier,
transaction::{Program, TransactionArgument, TransactionOutput}, transaction::{Program, TransactionArgument, TransactionOutput},
}; };
use vm::{ use vm::{
@ -19,6 +21,7 @@ use vm::{
file_format::{CompiledModule, CompiledScript}, file_format::{CompiledModule, CompiledScript},
gas_schedule::{MAXIMUM_NUMBER_OF_GAS_UNITS, MAX_PRICE_PER_GAS_UNIT}, gas_schedule::{MAXIMUM_NUMBER_OF_GAS_UNITS, MAX_PRICE_PER_GAS_UNIT},
transaction_metadata::TransactionMetadata, transaction_metadata::TransactionMetadata,
vm_string::VMString,
}; };
use vm_cache_map::Arena; use vm_cache_map::Arena;
use vm_runtime::{ use vm_runtime::{
@ -27,8 +30,8 @@ use vm_runtime::{
module_cache::{BlockModuleCache, ModuleCache, VMModuleCache}, module_cache::{BlockModuleCache, ModuleCache, VMModuleCache},
}, },
txn_executor::TransactionExecutor, txn_executor::TransactionExecutor,
value::Local,
}; };
use vm_runtime_types::value::Value;
pub fn process_instruction( pub fn process_instruction(
_program_id: &Pubkey, _program_id: &Pubkey,
@ -76,14 +79,14 @@ impl MoveProcessor {
InstructionError::InvalidAccountData InstructionError::InvalidAccountData
} }
fn arguments_to_locals(args: Vec<TransactionArgument>) -> Vec<Local> { fn arguments_to_values(args: Vec<TransactionArgument>) -> Vec<Value> {
let mut locals = vec![]; let mut locals = vec![];
for arg in args { for arg in args {
locals.push(match arg { locals.push(match arg {
TransactionArgument::U64(i) => Local::u64(i), TransactionArgument::U64(i) => Value::u64(i),
TransactionArgument::Address(a) => Local::address(a), TransactionArgument::Address(a) => Value::address(a),
TransactionArgument::ByteArray(b) => Local::bytearray(b), TransactionArgument::ByteArray(b) => Value::byte_array(b),
TransactionArgument::String(s) => Local::string(s), TransactionArgument::String(s) => Value::string(VMString::new(s)),
}); });
} }
locals locals
@ -137,13 +140,13 @@ impl MoveProcessor {
let program: Program = serde_json::from_str(&string).map_err(map_json_error)?; let program: Program = serde_json::from_str(&string).map_err(map_json_error)?;
let script = let script =
CompiledScript::deserialize(&program.code()).map_err(map_vm_binary_error)?; CompiledScript::deserialize(&program.code()).map_err(map_err_vm_status)?;
let modules = program let modules = program
.modules() .modules()
.iter() .iter()
.map(|bytes| CompiledModule::deserialize(&bytes)) .map(|bytes| CompiledModule::deserialize(&bytes))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
.map_err(map_vm_binary_error)?; .map_err(map_err_vm_status)?;
Ok((script, modules)) Ok((script, modules))
} }
@ -163,12 +166,12 @@ impl MoveProcessor {
modules_bytes, modules_bytes,
} => { } => {
let script = let script =
VerifiedScript::deserialize(&script_bytes).map_err(map_vm_binary_error)?; VerifiedScript::deserialize(&script_bytes).map_err(map_err_vm_status)?;
let modules = modules_bytes let modules = modules_bytes
.iter() .iter()
.map(|module_bytes| VerifiedModule::deserialize(&module_bytes.bytes)) .map(|module_bytes| VerifiedModule::deserialize(&module_bytes.bytes))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
.map_err(map_vm_binary_error)?; .map_err(map_err_vm_status)?;
Ok((script, modules)) Ok((script, modules))
} }
@ -213,13 +216,16 @@ impl MoveProcessor {
txn_metadata.gas_unit_price = *MAX_PRICE_PER_GAS_UNIT; txn_metadata.gas_unit_price = *MAX_PRICE_PER_GAS_UNIT;
let mut vm = TransactionExecutor::new(&module_cache, data_store, txn_metadata); let mut vm = TransactionExecutor::new(&module_cache, data_store, txn_metadata);
vm.execute_function(&module_id, &function_name, Self::arguments_to_locals(args)) vm.execute_function(
.map_err(map_vm_invariant_violation_error)? &module_id,
.map_err(map_vm_runtime_error)?; &Identifier::new(function_name).unwrap(),
Self::arguments_to_values(args),
)
.map_err(map_err_vm_status)?;
Ok(vm Ok(vm
.make_write_set(modules_to_publish, Ok(Ok(()))) .make_write_set(modules_to_publish, Ok(()))
.map_err(map_vm_runtime_error)?) .map_err(map_err_vm_status)?)
} }
fn keyed_accounts_to_data_store( fn keyed_accounts_to_data_store(
@ -251,11 +257,20 @@ impl MoveProcessor {
.into_write_sets() .into_write_sets()
.map_err(|_| InstructionError::GenericError)?; .map_err(|_| InstructionError::GenericError)?;
// Genesis account holds both mint and stdlib under address 0x0 // Genesis account holds both mint and stdlib
let genesis_key = *keyed_accounts[GENESIS_INDEX].unsigned_key(); let genesis_key = *keyed_accounts[GENESIS_INDEX].unsigned_key();
let write_set = write_sets let mut write_set = write_sets
.remove(&AccountAddress::default()) .remove(&account_config::association_address())
.ok_or_else(Self::missing_account)?; .ok_or_else(Self::missing_account)?
.into_mut();
for (access_path, write_op) in write_sets
.remove(&account_config::core_code_address())
.ok_or_else(Self::missing_account)?
.into_iter()
{
write_set.push((access_path, write_op));
}
let write_set = write_set.freeze().unwrap();
Self::serialize_and_enforce_length( Self::serialize_and_enforce_length(
&LibraAccountState::Genesis(write_set), &LibraAccountState::Genesis(write_set),
&mut keyed_accounts[GENESIS_INDEX].account.data, &mut keyed_accounts[GENESIS_INDEX].account.data,
@ -413,12 +428,11 @@ impl MoveProcessor {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use language_e2e_tests::account::AccountResource;
use solana_sdk::account::Account; use solana_sdk::account::Account;
use solana_sdk::rent_calculator::RentCalculator; use solana_sdk::rent_calculator::RentCalculator;
use solana_sdk::sysvar::rent; use solana_sdk::sysvar::rent;
const BIG_ENOUGH: usize = 6_000; const BIG_ENOUGH: usize = 10_000;
#[test] #[test]
fn test_account_size() { fn test_account_size() {
@ -564,7 +578,7 @@ mod tests {
}) })
.unwrap(), .unwrap(),
), ),
Err(InstructionError::InsufficientFunds) Err(InstructionError::CustomError(4002))
); );
} }
@ -589,8 +603,8 @@ mod tests {
.read_account_resource(&accounts[GENESIS_INDEX + 1].address) .read_account_resource(&accounts[GENESIS_INDEX + 1].address)
.unwrap(); .unwrap();
assert_eq!(amount, AccountResource::read_balance(&payee_resource)); assert_eq!(amount, payee_resource.balance());
assert_eq!(0, AccountResource::read_sequence_number(&payee_resource)); assert_eq!(0, payee_resource.sequence_number());
} }
#[test] #[test]
@ -655,13 +669,10 @@ mod tests {
let sender_resource = data_store.read_account_resource(&sender.address).unwrap(); let sender_resource = data_store.read_account_resource(&sender.address).unwrap();
let payee_resource = data_store.read_account_resource(&payee.address).unwrap(); let payee_resource = data_store.read_account_resource(&payee.address).unwrap();
assert_eq!( assert_eq!(amount_to_mint - amount, sender_resource.balance());
amount_to_mint - amount, assert_eq!(0, sender_resource.sequence_number());
AccountResource::read_balance(&sender_resource) assert_eq!(amount, payee_resource.balance());
); assert_eq!(0, payee_resource.sequence_number());
assert_eq!(0, AccountResource::read_sequence_number(&sender_resource));
assert_eq!(amount, AccountResource::read_balance(&payee_resource));
assert_eq!(0, AccountResource::read_sequence_number(&payee_resource));
} }
#[test] #[test]
@ -893,9 +904,13 @@ mod tests {
owner: id(), owner: id(),
..Account::default() ..Account::default()
}; };
let mut genesis = Self::new(Pubkey::default(), account); let mut genesis = Self::new(
genesis.account.data = Pubkey::new(&account_config::association_address().to_vec()),
bincode::serialize(&LibraAccountState::create_genesis(amount).unwrap()).unwrap(); account,
);
let pre_data = LibraAccountState::create_genesis(amount).unwrap();
let _hi = "hello";
genesis.account.data = bincode::serialize(&pre_data).unwrap();
genesis genesis
} }