Skip to content

Commit

Permalink
Price oracle.
Browse files Browse the repository at this point in the history
  • Loading branch information
RIg410 committed May 12, 2020
1 parent 4d50c7c commit bef871b
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 6 deletions.
4 changes: 3 additions & 1 deletion Cargo.lock

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

1 change: 0 additions & 1 deletion language/move-lang/src/expansion/translate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,6 @@ fn module_(
name: name.clone(),
};
let current_module = ModuleIdent(sp(name_loc, mident_));
let is_source_module = is_source_module && !fake_natives::is_fake_native(&current_module);
let self_aliases = module_self_aliases(&current_module);
context.set_and_shadow_aliases(self_aliases);
let alias_map = aliases(context, uses);
Expand Down
2 changes: 2 additions & 0 deletions language/move-vm/natives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ 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" }

byteorder = "1.3.4"

[features]
default = []
debug_module = []
1 change: 1 addition & 0 deletions language/move-vm/natives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ pub mod event;
pub mod hash;
pub mod lcs;
pub mod signature;
pub mod oracle;
1 change: 1 addition & 0 deletions language/move-vm/natives/src/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ pub mod event;
pub mod hash;
pub mod lcs;
pub mod signature;
pub mod oracle;
73 changes: 73 additions & 0 deletions language/move-vm/natives/src/oracle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
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},
};

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>,
) -> VMResult<NativeResult> {
if arguments.len() != 1 {
let msg = format!(
"wrong number of arguments for get_price expected 1 found {}",
arguments.len()
);
return Err(status(StatusCode::UNREACHABLE, &msg));
}

let ticker = pop_arg!(arguments, u64);
let price =
make_path(ticker)
.and_then(|path| {
let value = context.raw_load(&path).map_err(|err| {
status(
StatusCode::STORAGE_ERROR,
&format!("Failed to load ticker [{}]", err),
)
})?;

if let Some(price) = value {
if price.len() != 8 {
Err(status(StatusCode::TYPE_MISMATCH, "Invalid prise size"))
} else {
Ok(LittleEndian::read_u64(&price))
}
} else {
Err(status(StatusCode::STORAGE_ERROR, "Price is not found"))
}
});

let cost = GasUnits::new(COST);
Ok(match price {
Ok(price) => NativeResult::ok(cost, vec![Value::u64(price)]),
Err(status) => NativeResult::err(cost, status),
})
}

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 buf = [0; 8];
LittleEndian::write_u64(&mut buf, ticker_pair);
hasher.write(&buf);
let mut hash = hasher.finish().to_vec();
hash.insert(0, PRICE_ORACLE_TAG);
Ok(AccessPath::new(AccountAddress::DEFAULT, hash))
}

9 changes: 7 additions & 2 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, language_storage::ModuleId,
};
use move_core_types::{gas_schedule::CostTable, identifier::IdentStr};
use move_vm_natives::{account, event, hash, lcs, signature};
use move_vm_natives::{account, event, hash, lcs, signature, oracle};
use move_vm_types::{
interpreter_context::InterpreterContext,
loaded_data::{runtime_types::Type, types::FatType},
Expand Down Expand Up @@ -43,6 +43,7 @@ pub(crate) enum NativeFunction {
AccountSaveBalance,
DebugPrint,
DebugPrintStackTrace,
OraclePrice,
}

impl NativeFunction {
Expand Down Expand Up @@ -75,6 +76,7 @@ impl NativeFunction {
(&CORE_CODE_ADDRESS, "Account", "save_balance") => AccountSaveBalance,
(&CORE_CODE_ADDRESS, "Debug", "print") => DebugPrint,
(&CORE_CODE_ADDRESS, "Debug", "print_stack_trace") => DebugPrintStackTrace,
(&CORE_CODE_ADDRESS, "Oracle", "get_price") => OraclePrice,
_ => return None,
})
}
Expand Down Expand Up @@ -108,6 +110,7 @@ impl NativeFunction {
Self::LCSToBytes => lcs::native_to_bytes(ctx, t, v),
Self::DebugPrint => debug::native_print(ctx, t, v),
Self::DebugPrintStackTrace => debug::native_print_stack_trace(ctx, t, v),
Self::OraclePrice => oracle::native_oracle_get_price(ctx, t, v),
}
}
}
Expand Down Expand Up @@ -160,7 +163,9 @@ impl<'a, 'txn> NativeContext for FunctionContext<'a, 'txn> {
self.interpreter_context
.move_resource_to(&ap, libra_type.fat_type(), resource_to_save)
}

fn raw_load(&self, path: &AccessPath) -> VMResult<Option<Vec<u8>>> {
self.interpreter_context.raw_load(path)
}
fn save_event(&mut self, event: ContractEvent) -> VMResult<()> {
Ok(self.interpreter_context.push_event(event))
}
Expand Down
2 changes: 1 addition & 1 deletion language/move-vm/state/src/data_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ pub struct TransactionDataCache<'txn> {
// Also need to relate this to a ResourceKey.
data_map: BTreeMap<AccessPath, Option<(FatStructType, GlobalValue)>>,
module_map: BTreeMap<ModuleId, Vec<u8>>,
data_cache: &'txn dyn RemoteCache,
pub data_cache: &'txn dyn RemoteCache,
}

impl<'txn> TransactionDataCache<'txn> {
Expand Down
8 changes: 8 additions & 0 deletions language/move-vm/state/src/execution_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ impl<'txn> ChainState for TransactionExecutionContext<'txn> {
fn emit_event(&mut self, event: ContractEvent) {
self.event_data.push(event)
}

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

pub struct SystemExecutionContext<'txn>(TransactionExecutionContext<'txn>);
Expand Down Expand Up @@ -200,6 +204,10 @@ impl<'txn> ChainState for SystemExecutionContext<'txn> {
fn emit_event(&mut self, event: ContractEvent) {
self.0.emit_event(event)
}

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

impl<'txn> From<TransactionExecutionContext<'txn>> for SystemExecutionContext<'txn> {
Expand Down
2 changes: 2 additions & 0 deletions language/move-vm/types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,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.9.6"

Expand Down
4 changes: 3 additions & 1 deletion language/move-vm/types/src/chain_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ pub trait ChainState {
/// Get the serialized format of a `CompiledModule` from chain given a `ModuleId`.
fn load_module(&self, module: &ModuleId) -> VMResult<Vec<u8>>;

/// Get a reference to a resource stored on chain.
fn raw_load(&self, path: &AccessPath) -> VMResult<Option<Vec<u8>>>;

/// Get a reference to a resource stored on chain.
fn borrow_resource(
&mut self,
ap: &AccessPath,
Expand Down
6 changes: 6 additions & 0 deletions language/move-vm/types/src/interpreter_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ pub trait InterpreterContext {
fn load_module(&self, module: &ModuleId) -> VMResult<Vec<u8>>;

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

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

impl<T: ChainState> InterpreterContext for T {
Expand Down Expand Up @@ -146,4 +148,8 @@ impl<T: ChainState> InterpreterContext for T {
fn publish_module(&mut self, module_id: ModuleId, module: Vec<u8>) -> VMResult<()> {
self.publish_module(module_id, module)
}

fn raw_load(&self, path: &AccessPath) -> VMResult<Option<Vec<u8>>> {
self.raw_load(path)
}
}
3 changes: 3 additions & 0 deletions language/move-vm/types/src/natives/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use crate::{
use libra_types::{
account_address::AccountAddress, contract_event::ContractEvent, language_storage::ModuleId,
vm_error::VMStatus,
access_path::AccessPath
};
use move_core_types::{
gas_schedule::{AbstractMemorySize, CostTable, GasAlgebra, GasCarrier, GasUnits},
Expand Down Expand Up @@ -52,6 +53,8 @@ pub trait NativeContext {
resource_to_save: Struct,
account_address: AccountAddress,
) -> VMResult<()>;
/// Load from state view.
fn raw_load(&self, path: &AccessPath) -> VMResult<Option<Vec<u8>>>;
/// Saves contract event.
fn save_event(&mut self, event: ContractEvent) -> VMResult<()>;
/// Converts types to fet types.
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 @@ -236,4 +236,8 @@ impl<'txn> ChainState for GenesisExecutionContext<'txn> {
fn emit_event(&mut self, event: ContractEvent) {
self.ctx.emit_event(event)
}

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

0 comments on commit bef871b

Please sign in to comment.