Skip to content

Commit

Permalink
Documentation for data-source, lang and runtime crates (#153)
Browse files Browse the repository at this point in the history
* docs / imports reorganization for the data-source/grpc.rs

* docs for data-source

* docs for lang crate

* docs for gas_schedule.rs

* docs for runtime crate

* improve docs for grpc services

* add docs for bech32 utils
  • Loading branch information
mkurnikov authored Jun 30, 2020
1 parent 81195d7 commit 2117e84
Show file tree
Hide file tree
Showing 18 changed files with 178 additions and 69 deletions.
7 changes: 7 additions & 0 deletions compiler/src/mv/bech32.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#![warn(missing_docs)]

use anyhow::Result;
use bech32::u5;
use lazy_static::lazy_static;
use regex::Regex;

/// Fixed prefix of all dfinance bech32 addresses.
pub static HRP: &str = "wallet";

lazy_static! {
Expand All @@ -12,12 +15,15 @@ lazy_static! {
.unwrap();
}

/// Convert bech32 wallet1 prefixed address into 20 bytes libra address.
/// Will fail, if bech32 is invalid.
pub fn bech32_into_libra(address: &str) -> Result<String> {
let (_, data_bytes) = bech32::decode(address)?;
let data = bech32::convert_bits(&data_bytes, 5, 8, true)?;
Ok(hex::encode(&data))
}

/// Convert libra 20 byte address into bech32 form.
pub fn libra_into_bech32(libra_address: &str) -> Result<String> {
ensure!(
libra_address.starts_with("0x"),
Expand All @@ -33,6 +39,7 @@ pub fn libra_into_bech32(libra_address: &str) -> Result<String> {
Ok(bech32::encode(&HRP, data)?)
}

/// Replace all occurrences of bech32 addresses in the `source` string.
pub fn replace_bech32_addresses(source: &str) -> String {
let mut transformed_source = source.to_string();
for mat in BECH32_REGEX.captures_iter(source).into_iter() {
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/mv/disassembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ mod tests {

#[test]
pub fn test_module_signature() {
let ds = MockDataSource::default();
let ds = MockDataSource::new();
let compiler = Compiler::new(ds.clone());
ds.publish_module(
compiler
Expand Down
1 change: 1 addition & 0 deletions compiler/src/mv/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/// bech32 -> libra related utils
pub mod bech32;
pub mod builder;
pub mod dependence;
Expand Down
28 changes: 18 additions & 10 deletions data-source/src/grpc.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,39 @@
use std::convert::TryInto;
use std::thread::{self, JoinHandle};
use std::sync::Arc;
use std::thread::{self, JoinHandle};
use std::time::Duration;
use libra::{libra_types, libra_state_view, move_vm_runtime};
use libra_state_view::StateView;
use libra_types::access_path::AccessPath;

use anyhow::Error;
use api::grpc::ds_grpc::{ds_raw_response::ErrorCode, ds_service_client::DsServiceClient, DsAccessPath};
use crossbeam::channel::{bounded, Receiver, Sender};
use http::Uri;
use libra_state_view::StateView;
use libra_types::access_path::AccessPath;
use libra_types::vm_error::{StatusCode, VMStatus};
use move_vm_runtime::data_cache::RemoteCache;
use tokio::runtime::Runtime;
use crossbeam::channel::{Sender, Receiver, bounded};

use dvm_net::api;
use dvm_net::tonic;
use dvm_net::prelude::*;
use api::grpc::ds_grpc::{ds_service_client::DsServiceClient, DsAccessPath, ds_raw_response::ErrorCode};
use dvm_net::tonic;
use libra::{libra_state_view, libra_types, move_vm_runtime};
use libra::libra_vm::errors::VMResult;
use libra_types::vm_error::{VMStatus, StatusCode};
use crate::{DataSource, Clear};
use move_vm_runtime::data_cache::RemoteCache;

use crate::{Clear, DataSource};

/// Receiver for a channel that handles shutdown signals.
pub type ShutdownSig = tokio::sync::oneshot::Receiver<()>;

/// Wrapper around gRPC-based interface to dnode. Used for the resource resolution inside the VM.
#[derive(Clone)]
pub struct GrpcDataSource {
handler: Arc<JoinHandle<()>>,
sender: Sender<Request>,
}

impl GrpcDataSource {
/// Create an instance of gRPC based data source for VM.
/// `shutdown_signal` is a oneshot `crossbeam_channel::Sender` to shutdown the service.
pub fn new(uri: Uri, shutdown_signal: Option<ShutdownSig>) -> Result<GrpcDataSource, Error> {
let rt = Runtime::new()?;
let (sender, receiver) = bounded(10);
Expand Down Expand Up @@ -152,6 +159,7 @@ impl StateView for GrpcDataSource {
}
}

/// Convert Libra's `AccessPath` into gRPC `DsAccessPath`.
pub fn access_path_into_ds(ap: AccessPath) -> DsAccessPath {
DsAccessPath::new(ap.address.to_vec(), ap.path)
}
Expand Down
24 changes: 19 additions & 5 deletions data-source/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
//! Interface between MoveVM `StateView` implementation and gRPC API for `dnode`.
#![warn(missing_docs)]

#[macro_use]
extern crate anyhow;
#[macro_use]
extern crate log;

/// `GrpcDataSource` to wrap all gRPC calls to `dnode`.
pub mod grpc;

/// Defines `DsMeter` which implements `StateView` and adds metric recording for all `StateView` method calls.
pub mod metrics;

/// `MockDataSource` to be used in test_kit.
pub mod mock;

/// Defines `ModuleCache` which implements caching for fetching modules from `dnode`.
pub mod module_cache;

use libra::{libra_types, libra_state_view, move_vm_runtime};
use libra_types::write_set::WriteSet;
use libra::move_core_types::language_storage::ModuleId;
use libra_types::transaction::Module;
use libra_types::access_path::AccessPath;
Expand All @@ -22,17 +32,21 @@ pub use metrics::DsMeter;
pub use grpc::GrpcDataSource;
use move_vm_runtime::data_cache::RemoteCache;

/// Thread-safe `StateView`.
pub trait DataSource: StateView + RemoteCache + Clear + Clone + Send + Sync + 'static {}

pub trait MergeWriteSet {
fn merge_write_set(&self, write_set: WriteSet);
}

/// Used to automatically implement `get_module` which calls `StateView.get()`
/// internally and automatically wraps result with `Module`.
pub trait DataAccess {
/// See autoimplementation of the trait for all `StateView` objects.
fn get_module(&self, module_id: &ModuleId) -> Result<Option<Module>, Error>;
}

/// Trait to `clear()` internal data structure.
pub trait Clear {
/// No-op in default implementation.
/// Called on internal `DataSource` object to remove all entries from internal cache.
/// Used when `sender` is the built-in 0x0 / 0x1 address.
fn clear(&self) {
//no-op
}
Expand Down
13 changes: 8 additions & 5 deletions data-source/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use anyhow::Error;

use dvm_info::metrics::execution::ExecutionResult;
use dvm_info::metrics::meter::ScopeMeter;
use libra::libra_state_view::StateView;
use libra::libra_types::access_path::AccessPath;
use anyhow::Error;
use libra::move_vm_runtime::data_cache::RemoteCache;
use libra::libra_vm::errors::VMResult;
use crate::{DataSource, Clear};
use dvm_info::metrics::meter::ScopeMeter;
use dvm_info::metrics::execution::ExecutionResult;
use libra::move_vm_runtime::data_cache::RemoteCache;

use crate::{Clear, DataSource};

/// Wrapper for data source which collects metrics queries.
#[derive(Debug, Clone)]
Expand All @@ -20,6 +22,7 @@ impl<D> DsMeter<D>
where
D: DataSource,
{
/// Contructor
pub fn new(inner: D) -> DsMeter<D> {
DsMeter { inner }
}
Expand Down
29 changes: 20 additions & 9 deletions data-source/src/mock.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,41 @@
use std::collections::HashMap;
use std::sync::{Mutex, Arc};
use std::sync::{Arc, Mutex};

use anyhow::Error;
use libra::{libra_types, libra_state_view, libra_vm, move_vm_runtime};
use libra_state_view::StateView;
use libra_types::access_path::AccessPath;
use libra_types::write_set::{WriteSet, WriteOp, WriteSetMut};
use libra_vm::errors::VMResult;
use crate::{MergeWriteSet, DataSource, Clear};
use libra_types::write_set::{WriteOp, WriteSet, WriteSetMut};
use libra_vm::CompiledModule;
use libra::move_core_types::language_storage::ModuleId;
use libra_vm::errors::VMResult;
use move_vm_runtime::data_cache::RemoteCache;

use libra::{libra_state_view, libra_types, libra_vm, move_vm_runtime};
use libra::move_core_types::language_storage::ModuleId;

use crate::{Clear, DataSource};

/// `StateView` implementation to be used in test_kit.
#[derive(Debug, Clone, Default)]
pub struct MockDataSource {
data: Arc<Mutex<HashMap<AccessPath, Vec<u8>>>>,
}

impl MockDataSource {
/// Proxy to default() constructor.
pub fn new() -> MockDataSource {
MockDataSource {
data: Arc::new(Mutex::new(Default::default())),
}
}

/// Create `MockDataSource` with `write_set` applied.
pub fn with_write_set(write_set: WriteSet) -> MockDataSource {
let ds = MockDataSource::new();
ds.merge_write_set(write_set);
ds
}

/// Extract `WriteSet` from internal state.
pub fn to_write_set(&self) -> Result<WriteSet, Error> {
let data = self.data.lock().unwrap();
let ws = data
Expand All @@ -38,17 +45,20 @@ impl MockDataSource {
WriteSetMut::new(ws).freeze()
}

/// Add module to internal state.
pub fn publish_module(&self, module: Vec<u8>) -> Result<ModuleId, Error> {
let id = CompiledModule::deserialize(&module)?.self_id();
self.publish_module_with_id(id.clone(), module)?;
Ok(id)
}

/// Add module with `ModuleId` to internal state.
pub fn publish_module_with_id(&self, id: ModuleId, module: Vec<u8>) -> Result<(), Error> {
self.insert((&id).into(), module);
Ok(())
}

/// Clear internal chain data.
pub fn clear(&self) {
let mut data = self.data.lock().unwrap();
data.clear();
Expand Down Expand Up @@ -77,19 +87,20 @@ impl StateView for MockDataSource {
}

impl MockDataSource {
/// Wrapper around internal `HashMap.insert()`.
pub fn insert(&self, access_path: AccessPath, blob: Vec<u8>) {
let data = &mut self.data.lock().unwrap();
data.insert(access_path, blob);
}

/// Wrapper around internal `HashMap.delete()`.
pub fn delete(&self, access_path: AccessPath) {
let data = &mut self.data.lock().unwrap();
data.remove(&access_path);
}
}

impl MergeWriteSet for MockDataSource {
fn merge_write_set(&self, write_set: WriteSet) {
/// Merge `WriteSet` into internal chain state.
pub fn merge_write_set(&self, write_set: WriteSet) {
let data = &mut self.data.lock().unwrap();
for (access_path, write_op) in write_set {
match write_op {
Expand Down
14 changes: 10 additions & 4 deletions data-source/src/module_cache.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
use lru::LruCache;
use std::sync::{Arc, Mutex};

use anyhow::Error;
use lru::LruCache;

use libra::libra_state_view::StateView;
use libra::libra_types::access_path::AccessPath;
use anyhow::Error;
use libra::move_vm_runtime::data_cache::RemoteCache;
use libra::libra_vm::errors::VMResult;
use crate::{DataSource, Clear};
use libra::move_vm_runtime::data_cache::RemoteCache;

use crate::{Clear, DataSource};

/// Value of the first byte in serialized representation of the `Module` for `lcs`.
const CODE_TAG: u8 = 0;

/// Cached `DataSource`.
#[derive(Debug, Clone)]
pub struct ModuleCache<D>
where
Expand All @@ -22,6 +27,7 @@ impl<D> ModuleCache<D>
where
D: DataSource,
{
/// Create new cached data source with `cache_size` max number of entries in cache.
pub fn new(inner: D, cache_size: usize) -> ModuleCache<D> {
ModuleCache {
inner,
Expand Down
5 changes: 4 additions & 1 deletion lang/src/bytecode/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use anyhow::Error;
use libra::libra_vm::file_format::{SignatureToken, CompiledScript};

use libra::libra_vm::access::ScriptAccess;
use libra::libra_vm::file_format::{CompiledScript, SignatureToken};

/// Procedures for verification of bytecode (restricted set of instructions and modules).
pub mod verification;

/// Get script signature.
pub fn extract_script_params(bytecode: &[u8]) -> Result<Vec<SignatureToken>, Error> {
let script = CompiledScript::deserialize(bytecode).map_err(|err| {
anyhow!(
Expand Down
1 change: 1 addition & 0 deletions lang/src/bytecode/verification/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use anyhow::Result;
use libra::libra_vm::access::ScriptAccess;
use libra::libra_vm::file_format::{Bytecode, CompiledScript};

/// Validate that script contains only allowed bytecode instructions (load variables, move, copy and method calls).
pub fn validate_bytecode_instructions(script: &CompiledScript) -> Result<()> {
let instructions = &script.code().code;
for inst in instructions {
Expand Down
3 changes: 3 additions & 0 deletions lang/src/bytecode/verification/whitelist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ fn get_imported_module(script: &CompiledScript, handle: &ModuleHandle) -> Import
ImportedModule { address, name }
}

/// Restricts set of modules allowed to use in script.
pub struct WhitelistVerifier {
allowed_modules: HashMap<AccountAddress, HashSet<String>>,
}

impl WhitelistVerifier {
/// Only modules allowed to use are modules from whitelist and owner's modules.
pub fn new(
sender_address: AccountAddress,
sender_modules: Vec<String>,
Expand All @@ -50,6 +52,7 @@ impl WhitelistVerifier {
WhitelistVerifier { allowed_modules }
}

/// Verify whether all `use` statements in script importing only modules from whitelist.
pub fn verify_only_whitelisted_modules(&self, script: &CompiledScript) -> Result<()> {
let deps: HashSet<ImportedModule> = script
.module_handles()
Expand Down
6 changes: 6 additions & 0 deletions lang/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
//! Stores `stdlib` export and bytecode verification procedures.
#![warn(missing_docs)]

#[macro_use]
extern crate anyhow;
extern crate libra;
extern crate include_dir;

// simply reexport stdlib for compatibility
pub extern crate stdlib;

/// Procedures to work with bytecode.
pub mod bytecode;
1 change: 1 addition & 0 deletions runtime/src/gas_schedule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use libra::libra_vm::{
};
use libra::move_vm_types::gas_schedule::*;

/// Specific gas per instruction configuration for dvm.
pub fn cost_table() -> CostTable {
use Bytecode::*;
let mut instrs = vec![
Expand Down
7 changes: 7 additions & 0 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
//! Integration with MoveVM.
#![warn(missing_docs)]

#[macro_use]
pub extern crate log;

/// Defines dvm `CostTable`.
pub mod gas_schedule;

/// Defines structures for script execution inside VM.
pub mod move_vm;
Loading

0 comments on commit 2117e84

Please sign in to comment.