Skip to content

Commit

Permalink
Native functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
RIg410 committed Jun 10, 2020
1 parent ae28ced commit a06704d
Show file tree
Hide file tree
Showing 22 changed files with 98 additions and 43 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions client/libra-dev/include/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ extern "C" {
#define LIBRA_PUBKEY_SIZE 32
#define LIBRA_PRIVKEY_SIZE 32
#define LIBRA_SIGNATURE_SIZE 64
#define LIBRA_ADDRESS_SIZE 16
#define LIBRA_EVENT_KEY_SIZE 24
#define LIBRA_ADDRESS_SIZE 20
#define LIBRA_EVENT_KEY_SIZE 28

enum LibraStatus {
Ok = 0,
Expand Down
2 changes: 1 addition & 1 deletion client/libra-dev/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ fn test_libra_LibraEvent_from() {
let sent_event_handle = EventHandle::new(EventKey::new_from_address(&sender_address, 0), 0);
let sequence_number = sent_event_handle.count();
let event_key = sent_event_handle.key();
let module = "LibraAccount";
let module = "Account";
let name = "SentPaymentEvent";

let type_tag = Struct(StructTag {
Expand Down
2 changes: 1 addition & 1 deletion language/move-core/types/src/account_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl AccountAddress {
}

/// The number of bytes in an address.
pub const LENGTH: usize = 16;
pub const LENGTH: usize = 20;

pub const DEFAULT: Self = Self([0u8; AccountAddress::LENGTH]);

Expand Down
3 changes: 0 additions & 3 deletions language/move-lang/src/expansion/translate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,6 @@ fn module_(context: &mut Context, mdef: P::ModuleDefinition) -> (ModuleIdent, E:
};
let current_module = ModuleIdent(sp(name_loc, mident_));
let old_is_source_module = context.is_source_module;
context.is_source_module =
context.is_source_module && !fake_natives::is_fake_native(&current_module);

let mut new_scope = AliasMap::new();
module_self_aliases(&mut new_scope, &current_module);
let members = members
Expand Down
2 changes: 1 addition & 1 deletion language/move-lang/src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

pub mod ast;
pub mod lexer;
pub mod syntax;
pub mod ast;
2 changes: 1 addition & 1 deletion language/move-lang/src/shared/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub mod unique_map;
// Address
//**************************************************************************************************

pub const ADDRESS_LENGTH: usize = 16;
pub const ADDRESS_LENGTH: usize = 20;

#[derive(Ord, PartialOrd, Eq, PartialEq, Hash, Default, Clone, Copy)]
pub struct Address([u8; ADDRESS_LENGTH]);
Expand Down
3 changes: 3 additions & 0 deletions language/move-vm/natives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ libra-workspace-hack = { path = "../../../common/workspace-hack", version = "0.1
move-core-types = { path = "../../move-core/types", version = "0.1.0" }
move-vm-types = { path = "../types", version = "0.1.0" }
vm = { path = "../../vm", version = "0.1.0" }
twox-hash = "1.5.0"

byteorder = "1.3.4"

[features]
default = []
Expand Down
2 changes: 2 additions & 0 deletions language/move-vm/natives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ extern crate move_vm_types;

pub mod account;
pub mod debug;
pub mod dfinance;
pub mod event;
pub mod hash;
pub mod lcs;
pub mod oracle;
pub mod signature;
pub mod signer;
pub mod vector;
Empty file.
68 changes: 44 additions & 24 deletions language/move-vm/natives/src/oracle.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,51 @@
use move_vm_types::natives::function::{NativeContext, NativeResult};
use move_vm_types::loaded_data::runtime_types::Type;
use move_vm_types::values::Value;
use libra_types::access_path::AccessPath;
use libra_types::account_address::AccountAddress;
use libra_types::vm_error::{VMStatus, StatusCode};
use libra_crypto::hash::{DefaultHasher, CryptoHasher};
use std::collections::VecDeque;
use vm::errors::VMResult;
use byteorder::{LittleEndian, ByteOrder};
use move_core_types::{
gas_schedule::{GasUnits, GasAlgebra},
use byteorder::{ByteOrder, LittleEndian};
use libra_crypto::hash::DefaultHasher;
use libra_types::{
access_path::AccessPath,
account_address::AccountAddress,
vm_error::{StatusCode, VMStatus},
};
use move_core_types::gas_schedule::{GasAlgebra, GasUnits};
use move_vm_types::{
loaded_data::{runtime_types::Type, types::FatType},
natives::function::{NativeContext, NativeResult},
values::Value,
};
use std::io::Write;
use std::{collections::VecDeque, hash::Hasher};
use twox_hash::XxHash64;
use vm::errors::VMResult;

const COST: u64 = 929;
const PRICE_ORACLE_TAG: u8 = 255;

pub fn native_oracle_get_price(
context: &impl NativeContext,
_ty_args: Vec<Type>,
mut arguments: VecDeque<Value>,
ty_args: Vec<Type>,
_arguments: VecDeque<Value>,
) -> VMResult<NativeResult> {
if arguments.len() != 1 {
let ty_args = context.convert_to_fat_types(ty_args)?;

if ty_args.len() != 2 {
let msg = format!(
"wrong number of arguments for get_price expected 1 found {}",
arguments.len()
"wrong number of type parameters for get_price expected 2 found {}",
ty_args.len()
);
return Err(status(StatusCode::UNREACHABLE, &msg));
}

let ticker = pop_arg!(arguments, u64);
let price =
make_path(ticker)
let price = type_parameter_name(&ty_args[0])
.and_then(|ticker_part| {
type_parameter_name(&ty_args[1])
.and_then(|ticker_part_2| {
Ok(format!("{}{}", ticker_part, ticker_part_2).to_lowercase())
})
.and_then(|ticker| {
let mut hash = XxHash64::default();
Hasher::write(&mut hash, ticker.as_bytes());
Ok(Hasher::finish(&hash))
})
})
.and_then(|ticker| make_path(ticker))
.and_then(|path| {
let value = context.raw_load(&path).map_err(|err| {
status(
Expand All @@ -58,17 +72,23 @@ pub fn native_oracle_get_price(
})
}

fn type_parameter_name(ty_arg: &FatType) -> Result<String, VMStatus> {
match ty_arg {
FatType::Struct(t) => Ok(t.name.as_str().to_owned()),
_ => Err(status(StatusCode::TYPE_MISMATCH, "Expected a struct")),
}
}

fn status(code: StatusCode, msg: &str) -> VMStatus {
VMStatus::new(code).with_message(msg.to_owned())
}

pub fn make_path(ticker_pair: u64) -> Result<AccessPath, VMStatus> {
let mut hasher = DefaultHasher::default();
let mut hasher = DefaultHasher::new(&[]);
let mut buf = [0; 8];
LittleEndian::write_u64(&mut buf, ticker_pair);
hasher.write(&buf).map_err(|_| VMStatus::new(StatusCode::BAD_U64))?;
hasher.update(&buf);
let mut hash = hasher.finish().to_vec();
hash.insert(0, PRICE_ORACLE_TAG);
Ok(AccessPath::new(AccountAddress::DEFAULT, hash))
}

6 changes: 5 additions & 1 deletion language/move-vm/runtime/src/data_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub struct TransactionDataCache<'txn> {
data_map: BTreeMap<AccessPath, Option<(FatStructType, GlobalValue)>>,
module_map: BTreeMap<ModuleId, Vec<u8>>,
event_data: Vec<ContractEvent>,
data_cache: &'txn dyn RemoteCache,
pub data_cache: &'txn dyn RemoteCache,
}

impl<'txn> TransactionDataCache<'txn> {
Expand Down Expand Up @@ -197,6 +197,10 @@ impl<'a> DataStore for TransactionDataCache<'a> {
}
}

fn raw_load(&self, path: &AccessPath) -> VMResult<Option<Vec<u8>>> {
self.data_cache.get(&path)
}

fn publish_module(&mut self, m: ModuleId, bytes: Vec<u8>) -> VMResult<()> {
self.module_map.insert(m, bytes);
Ok(())
Expand Down
16 changes: 12 additions & 4 deletions language/move-vm/runtime/src/native_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use libra_types::{
contract_event::ContractEvent,
};
use move_core_types::{gas_schedule::CostTable, identifier::IdentStr, language_storage::ModuleId};
use move_vm_natives::{account, debug, event, hash, lcs, signature, signer, vector};
use move_vm_natives::{account, debug, event, hash, lcs, oracle, signature, signer, vector, dfinance};
use move_vm_types::{
data_store::DataStore,
gas_schedule::CostStrategy,
Expand Down Expand Up @@ -46,6 +46,8 @@ pub(crate) enum NativeFunction {
SignerBorrowAddress,
CreateSigner,
DestroySigner,
OraclePrice,
DfinanceSaveInfo,
}

impl NativeFunction {
Expand Down Expand Up @@ -75,11 +77,13 @@ impl NativeFunction {
(&CORE_CODE_ADDRESS, "Vector", "destroy_empty") => VectorDestroyEmpty,
(&CORE_CODE_ADDRESS, "Vector", "swap") => VectorSwap,
(&CORE_CODE_ADDRESS, "Event", "write_to_event_store") => AccountWriteEvent,
(&CORE_CODE_ADDRESS, "LibraAccount", "create_signer") => CreateSigner,
(&CORE_CODE_ADDRESS, "LibraAccount", "destroy_signer") => DestroySigner,
(&CORE_CODE_ADDRESS, "Account", "create_signer") => CreateSigner,
(&CORE_CODE_ADDRESS, "Account", "destroy_signer") => DestroySigner,
(&CORE_CODE_ADDRESS, "Debug", "print") => DebugPrint,
(&CORE_CODE_ADDRESS, "Debug", "print_stack_trace") => DebugPrintStackTrace,
(&CORE_CODE_ADDRESS, "Signer", "borrow_address") => SignerBorrowAddress,
(&CORE_CODE_ADDRESS, "Oracle", "get_price") => OraclePrice,
(&CORE_CODE_ADDRESS, "Dfinance", "register_token_info") => DfinanceSaveInfo,
_ => return None,
})
}
Expand Down Expand Up @@ -115,6 +119,8 @@ impl NativeFunction {
Self::SignerBorrowAddress => signer::native_borrow_address(ctx, t, v),
Self::CreateSigner => account::native_create_signer(ctx, t, v),
Self::DestroySigner => account::native_destroy_signer(ctx, t, v),
Self::OraclePrice => oracle::native_oracle_get_price(ctx, t, v),
Self::DfinanceSaveInfo => dfinance::native_register_token_info(ctx, t, v),
}
}
}
Expand Down Expand Up @@ -171,7 +177,9 @@ impl<'a> NativeContext for FunctionContext<'a> {
resource_to_save,
)
}

fn raw_load(&self, path: &AccessPath) -> VMResult<Option<Vec<u8>>> {
self.data_store.raw_load(path)
}
fn save_event(&mut self, event: ContractEvent) -> VMResult<()> {
Ok(self.data_store.emit_event(event))
}
Expand Down
Empty file.
2 changes: 2 additions & 0 deletions language/move-vm/types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ libra-workspace-hack = { path = "../../../common/workspace-hack", version = "0.1
move-core-types = { path = "../../move-core/types", version = "0.1.0" }
vm = { path = "../../vm", version = "0.1.0" }

libra-state-view = { path = "../../../storage/state-view", version = "0.1.0"}

[dev-dependencies]
proptest = "0.10.0"

Expand Down
Empty file.
2 changes: 2 additions & 0 deletions language/move-vm/types/src/data_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ pub trait DataStore {
/// Get the serialized format of a `CompiledModule` given a `ModuleId`.
fn load_module(&self, module: &ModuleId) -> VMResult<Vec<u8>>;

fn raw_load(&self, path: &AccessPath) -> VMResult<Option<Vec<u8>>>;

/// Publish a module.
fn publish_module(&mut self, module_id: ModuleId, module: Vec<u8>) -> VMResult<()>;

Expand Down
Empty file.
5 changes: 3 additions & 2 deletions language/move-vm/types/src/natives/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ use crate::{
values::{Struct, Value},
};
use libra_types::{
account_address::AccountAddress, contract_event::ContractEvent,
access_path::AccessPath, account_address::AccountAddress, contract_event::ContractEvent,
vm_error::VMStatus,
access_path::AccessPath
};
use move_core_types::{
gas_schedule::{AbstractMemorySize, CostTable, GasAlgebra, GasCarrier, GasUnits},
Expand Down Expand Up @@ -58,6 +57,8 @@ pub trait NativeContext {
fn save_event(&mut self, event: ContractEvent) -> VMResult<()>;
/// Converts types to fet types.
fn convert_to_fat_types(&self, types: Vec<Type>) -> VMResult<Vec<FatType>>;
/// Load from state view.
fn raw_load(&self, path: &AccessPath) -> VMResult<Option<Vec<u8>>>;
/// Whether a type is a resource or not.
fn is_resource(&self, ty: &Type) -> VMResult<bool>;
}
Expand Down
4 changes: 4 additions & 0 deletions language/tools/vm-genesis/src/genesis_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,8 @@ impl<'txn> DataStore for GenesisDataCache<'txn> {
fn emit_event(&mut self, event: ContractEvent) {
self.data_store.emit_event(event)
}

fn raw_load(&self, path: &AccessPath) -> VMResult<Option<Vec<u8>>> {
self.data_store.raw_load(path)
}
}
4 changes: 2 additions & 2 deletions types/src/account_config/constants/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use move_core_types::{
};
use once_cell::sync::Lazy;

pub const ACCOUNT_MODULE_NAME: &str = "LibraAccount";
pub const ACCOUNT_MODULE_NAME: &str = "Account";

// Account
static ACCOUNT_MODULE_IDENTIFIER: Lazy<Identifier> =
Lazy::new(|| Identifier::new("LibraAccount").unwrap());
Lazy::new(|| Identifier::new("Account").unwrap());

/// The ModuleId for the Account module.
pub static ACCOUNT_MODULE: Lazy<ModuleId> =
Expand Down
2 changes: 1 addition & 1 deletion types/src/vm_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
#![allow(clippy::unit_arg)]

use anyhow::Result;
use enum_iterator::IntoEnumIterator;
#[cfg(any(test, feature = "fuzzing"))]
use proptest::prelude::*;
#[cfg(any(test, feature = "fuzzing"))]
use proptest_derive::Arbitrary;
use serde::{de, ser, Deserialize, Serialize};
use std::{convert::TryFrom, fmt};
use enum_iterator::IntoEnumIterator;

/// The minimum status code for validation statuses
pub static VALIDATION_STATUS_MIN_CODE: u64 = 0;
Expand Down

0 comments on commit a06704d

Please sign in to comment.