Skip to content

Commit bef871b

Browse files
committed
Price oracle.
1 parent 4d50c7c commit bef871b

14 files changed

Lines changed: 114 additions & 6 deletions

File tree

Cargo.lock

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

language/move-lang/src/expansion/translate.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,6 @@ fn module_(
238238
name: name.clone(),
239239
};
240240
let current_module = ModuleIdent(sp(name_loc, mident_));
241-
let is_source_module = is_source_module && !fake_natives::is_fake_native(&current_module);
242241
let self_aliases = module_self_aliases(&current_module);
243242
context.set_and_shadow_aliases(self_aliases);
244243
let alias_map = aliases(context, uses);

language/move-vm/natives/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ move-core-types = { path = "../../move-core/types", version = "0.1.0" }
2525
move-vm-types = { path = "../types", version = "0.1.0" }
2626
vm = { path = "../../vm", version = "0.1.0" }
2727

28+
byteorder = "1.3.4"
29+
2830
[features]
2931
default = []
3032
debug_module = []

language/move-vm/natives/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ pub mod event;
99
pub mod hash;
1010
pub mod lcs;
1111
pub mod signature;
12+
pub mod oracle;

language/move-vm/natives/src/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ pub mod event;
99
pub mod hash;
1010
pub mod lcs;
1111
pub mod signature;
12+
pub mod oracle;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use move_vm_types::natives::function::{NativeContext, NativeResult};
2+
use move_vm_types::loaded_data::runtime_types::Type;
3+
use move_vm_types::values::Value;
4+
use libra_types::access_path::AccessPath;
5+
use libra_types::account_address::AccountAddress;
6+
use libra_types::vm_error::{VMStatus, StatusCode};
7+
use libra_crypto::hash::{DefaultHasher, CryptoHasher};
8+
use std::collections::VecDeque;
9+
use vm::errors::VMResult;
10+
use byteorder::{LittleEndian, ByteOrder};
11+
use move_core_types::{
12+
gas_schedule::{GasUnits, GasAlgebra},
13+
};
14+
15+
const COST: u64 = 929;
16+
const PRICE_ORACLE_TAG: u8 = 255;
17+
18+
pub fn native_oracle_get_price(
19+
context: &impl NativeContext,
20+
_ty_args: Vec<Type>,
21+
mut arguments: VecDeque<Value>,
22+
) -> VMResult<NativeResult> {
23+
if arguments.len() != 1 {
24+
let msg = format!(
25+
"wrong number of arguments for get_price expected 1 found {}",
26+
arguments.len()
27+
);
28+
return Err(status(StatusCode::UNREACHABLE, &msg));
29+
}
30+
31+
let ticker = pop_arg!(arguments, u64);
32+
let price =
33+
make_path(ticker)
34+
.and_then(|path| {
35+
let value = context.raw_load(&path).map_err(|err| {
36+
status(
37+
StatusCode::STORAGE_ERROR,
38+
&format!("Failed to load ticker [{}]", err),
39+
)
40+
})?;
41+
42+
if let Some(price) = value {
43+
if price.len() != 8 {
44+
Err(status(StatusCode::TYPE_MISMATCH, "Invalid prise size"))
45+
} else {
46+
Ok(LittleEndian::read_u64(&price))
47+
}
48+
} else {
49+
Err(status(StatusCode::STORAGE_ERROR, "Price is not found"))
50+
}
51+
});
52+
53+
let cost = GasUnits::new(COST);
54+
Ok(match price {
55+
Ok(price) => NativeResult::ok(cost, vec![Value::u64(price)]),
56+
Err(status) => NativeResult::err(cost, status),
57+
})
58+
}
59+
60+
fn status(code: StatusCode, msg: &str) -> VMStatus {
61+
VMStatus::new(code).with_message(msg.to_owned())
62+
}
63+
64+
pub fn make_path(ticker_pair: u64) -> Result<AccessPath, VMStatus> {
65+
let mut hasher = DefaultHasher::default();
66+
let mut buf = [0; 8];
67+
LittleEndian::write_u64(&mut buf, ticker_pair);
68+
hasher.write(&buf);
69+
let mut hash = hasher.finish().to_vec();
70+
hash.insert(0, PRICE_ORACLE_TAG);
71+
Ok(AccessPath::new(AccountAddress::DEFAULT, hash))
72+
}
73+

language/move-vm/runtime/src/native_functions.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use libra_types::{
77
contract_event::ContractEvent, language_storage::ModuleId,
88
};
99
use move_core_types::{gas_schedule::CostTable, identifier::IdentStr};
10-
use move_vm_natives::{account, event, hash, lcs, signature};
10+
use move_vm_natives::{account, event, hash, lcs, signature, oracle};
1111
use move_vm_types::{
1212
interpreter_context::InterpreterContext,
1313
loaded_data::{runtime_types::Type, types::FatType},
@@ -43,6 +43,7 @@ pub(crate) enum NativeFunction {
4343
AccountSaveBalance,
4444
DebugPrint,
4545
DebugPrintStackTrace,
46+
OraclePrice,
4647
}
4748

4849
impl NativeFunction {
@@ -75,6 +76,7 @@ impl NativeFunction {
7576
(&CORE_CODE_ADDRESS, "Account", "save_balance") => AccountSaveBalance,
7677
(&CORE_CODE_ADDRESS, "Debug", "print") => DebugPrint,
7778
(&CORE_CODE_ADDRESS, "Debug", "print_stack_trace") => DebugPrintStackTrace,
79+
(&CORE_CODE_ADDRESS, "Oracle", "get_price") => OraclePrice,
7880
_ => return None,
7981
})
8082
}
@@ -108,6 +110,7 @@ impl NativeFunction {
108110
Self::LCSToBytes => lcs::native_to_bytes(ctx, t, v),
109111
Self::DebugPrint => debug::native_print(ctx, t, v),
110112
Self::DebugPrintStackTrace => debug::native_print_stack_trace(ctx, t, v),
113+
Self::OraclePrice => oracle::native_oracle_get_price(ctx, t, v),
111114
}
112115
}
113116
}
@@ -160,7 +163,9 @@ impl<'a, 'txn> NativeContext for FunctionContext<'a, 'txn> {
160163
self.interpreter_context
161164
.move_resource_to(&ap, libra_type.fat_type(), resource_to_save)
162165
}
163-
166+
fn raw_load(&self, path: &AccessPath) -> VMResult<Option<Vec<u8>>> {
167+
self.interpreter_context.raw_load(path)
168+
}
164169
fn save_event(&mut self, event: ContractEvent) -> VMResult<()> {
165170
Ok(self.interpreter_context.push_event(event))
166171
}

language/move-vm/state/src/data_cache.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ pub struct TransactionDataCache<'txn> {
116116
// Also need to relate this to a ResourceKey.
117117
data_map: BTreeMap<AccessPath, Option<(FatStructType, GlobalValue)>>,
118118
module_map: BTreeMap<ModuleId, Vec<u8>>,
119-
data_cache: &'txn dyn RemoteCache,
119+
pub data_cache: &'txn dyn RemoteCache,
120120
}
121121

122122
impl<'txn> TransactionDataCache<'txn> {

language/move-vm/state/src/execution_context.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ impl<'txn> ChainState for TransactionExecutionContext<'txn> {
128128
fn emit_event(&mut self, event: ContractEvent) {
129129
self.event_data.push(event)
130130
}
131+
132+
fn raw_load(&self, path: &AccessPath) -> VMResult<Option<Vec<u8>>> {
133+
self.data_view.data_cache.get(path)
134+
}
131135
}
132136

133137
pub struct SystemExecutionContext<'txn>(TransactionExecutionContext<'txn>);
@@ -200,6 +204,10 @@ impl<'txn> ChainState for SystemExecutionContext<'txn> {
200204
fn emit_event(&mut self, event: ContractEvent) {
201205
self.0.emit_event(event)
202206
}
207+
208+
fn raw_load(&self, path: &AccessPath) -> VMResult<Option<Vec<u8>>> {
209+
self.0.raw_load(path)
210+
}
203211
}
204212

205213
impl<'txn> From<TransactionExecutionContext<'txn>> for SystemExecutionContext<'txn> {

language/move-vm/types/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ libra-workspace-hack = { path = "../../../common/workspace-hack", version = "0.1
2525
move-core-types = { path = "../../move-core/types", version = "0.1.0" }
2626
vm = { path = "../../vm", version = "0.1.0" }
2727

28+
libra-state-view = { path = "../../../storage/state-view", version = "0.1.0"}
29+
2830
[dev-dependencies]
2931
proptest = "0.9.6"
3032

0 commit comments

Comments
 (0)