Update libra to new fork (#6523)

* Update to new libra branch

* Use core and association addresses
This commit is contained in:
TristanDebrunner 2019-10-29 10:39:10 -07:00 committed by GitHub
parent 029a2837e4
commit 489dc657c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 523 additions and 663 deletions

902
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(25);
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.21.0" } solana-logger = { path = "../../logger", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.0" } solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-runtime = { path = "../../runtime", version = "0.21.0" } solana-runtime = { path = "../../runtime", version = "0.21.0" }
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.21.0" } solana-move-loader-api = { path = "../move_loader_api", version = "0.21.0" }
[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.21.0" } solana-logger = { path = "../../logger", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.0" } solana-sdk = { path = "../../sdk", version = "0.21.0" }
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
} }