Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/engine no std #595

Merged
merged 11 commits into from
Nov 22, 2022
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ jobs:
- name: Run tests
run: cargo test
working-directory: radix-engine
- name: Run tests (no_std)
run: cargo test --no-default-features --features alloc
working-directory: radix-engine
radix-engine-wasmer:
name: Run Radix Engine tests with Wasmer
runs-on: ${{ matrix.os }}
Expand Down
4 changes: 0 additions & 4 deletions radix-engine-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ proc-macro2 = { version = "1.0.38" }
syn = { version = "1.0.93", features = ["full", "extra-traits"] }
quote = { version = "1.0.18" }
uuid = { version = "1.0.0", features = ["v4"] }
serde = { version = "1.0.137", default-features = false }
serde_json = { version = "1.0.81", default-features = false }
sbor = { path = "../sbor", default-features = false }
scrypto-abi = { path = "../scrypto-abi", default-features = false }

Expand All @@ -29,12 +27,10 @@ scrypto-abi = { path = "../scrypto-abi", default-features = false }
#
default = ["std"]
std = [
"serde/std", "serde_json/std",
"sbor/std", "sbor/serde",
"scrypto-abi/std", "scrypto-abi/serde"
]
alloc = [
"serde/alloc", "serde_json/alloc",
"sbor/alloc", "sbor/serde",
"scrypto-abi/alloc", "scrypto-abi/serde"
]
Expand Down
10 changes: 9 additions & 1 deletion radix-engine-stores/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@ version = "0.7.0"
edition = "2021"

[dependencies]
sbor = { path = "../sbor", default-features = false }
radix-engine = { path = "../radix-engine" }
radix-engine-interface = { path = "../radix-engine-interface", default-features = false }
sbor = { path = "../sbor" }
rocksdb = { version = "0.19.0", optional = true }

[features]
default = ["std"]
std = [
"sbor/std", "radix-engine-interface/std",
]
alloc = [
"sbor/alloc","radix-engine-interface/alloc",
]

rocksdb = ["dep:rocksdb"]
14 changes: 9 additions & 5 deletions radix-engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ utils = { path = "../utils", default-features = false }
radix-engine-constants = { path = "../radix-engine-constants" }
colored = { version = "2.0.0", default-features = false }
hex = { version = "0.4.3", default-features = false }
bitflags = "1.3"
bitflags = { version = "1.3" }
indexmap = { version = "1.8.1" }
moka = { version = "0.9.4", features = ["sync"], default-features = false }
lru = { version = "0.8.1", default-features = false }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we put lru behind optional too, and only enable it in the alloc case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, we don't gain much from this (tiny compile time of a small crate) by coupling lru and alloc. A slightly better approach is to make it a feature if we really care. But, will punt on this for now. :)

moka = { version = "0.9.4", features = ["sync"], default-features = false, optional = true }

# WASM de-/serialization
parity-wasm = { version = "0.42.2" }
Expand All @@ -35,7 +36,7 @@ wasmer-compiler-singlepass = { version = "2.2.1", optional = true }
[dev-dependencies]
wabt = { version = "0.10.0" }
criterion = { version = "0.3", features = ["html_reports"] }
scrypto-unit = { path = "../scrypto-unit" }
scrypto-unit = { path = "../scrypto-unit", default-features = false }
rand = { version = "0.8.5" }
rand_chacha = { version = "0.3.1" }
rayon = "1.5.3"
Expand All @@ -55,8 +56,11 @@ harness = false
[features]
# You should enable either `std` or `alloc`
default = ["std"]
std = ["sbor/std", "scrypto/std", "wasmi/std", "transaction/std"]
alloc = ["sbor/alloc", "scrypto/alloc", "transaction/alloc"]
std = ["sbor/std", "scrypto/std", "scrypto-unit/std", "wasmi/std", "transaction/std", "radix-engine-interface/std", "utils/std", "moka"]
alloc = ["sbor/alloc", "scrypto/alloc", "scrypto-unit/alloc", "transaction/alloc", "radix-engine-interface/alloc", "utils/alloc", "lru/hashbrown"]

# Use `wasmer` as WASM engine, otherwise `wasmi`
wasmer = ["dep:wasmer", "dep:wasmer-compiler-singlepass"]

# Use moka for caching
moka = ["dep:moka"]
3 changes: 1 addition & 2 deletions radix-engine/benches/wasm.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use std::sync::Arc;

use criterion::{criterion_group, criterion_main, Criterion};
use radix_engine::model::extract_abi;
use radix_engine::wasm::DefaultWasmEngine;
use radix_engine::wasm::InstrumentedCode;
use radix_engine::wasm::WasmEngine;
use radix_engine::wasm::WasmValidator;
use radix_engine_interface::crypto::hash;
use sbor::rust::sync::Arc;

fn bench_wasm_validation(c: &mut Criterion) {
let code = include_bytes!("../../assets/account.wasm");
Expand Down
2 changes: 2 additions & 0 deletions radix-engine/src/engine/interpreters/scrypto_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use radix_engine_interface::api::types::{
};
use radix_engine_interface::crypto::Hash;
use radix_engine_interface::data::IndexedScryptoValue;
use sbor::rust::string::String;
use sbor::rust::vec::Vec;

impl<'g, 's, W, R, N, T> SysNativeInvokable<N, RuntimeError> for Kernel<'g, 's, W, R>
where
Expand Down
2 changes: 2 additions & 0 deletions radix-engine/src/engine/interpreters/scrypto_interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ mod tests {
// RFC 2056
fn assert_all() {
assert_send::<ScryptoInterpreter<DefaultWasmEngine>>();
// TODO: make sure engine is indeed multi-thread safe!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you say the engine, do you mean the DefaultWasmEngine? or the RadixEngine itself?

Copy link
Contributor

@dhedey dhedey Nov 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my previous comment. Do you have specific worries or things you want to check? Else I think this code comment should probably be removed.

#[cfg(not(feature = "alloc"))]
assert_sync::<ScryptoInterpreter<DefaultWasmEngine>>();
}
};
Expand Down
1 change: 1 addition & 0 deletions radix-engine/src/engine/interpreters/wasm_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use radix_engine_interface::api::wasm_input::{
ResourceManagerMethodInvocation, VaultMethodInvocation, WorktopMethodInvocation,
};
use radix_engine_interface::data::{IndexedScryptoValue, ScryptoCustomTypeId};
use sbor::rust::vec::Vec;

/// A glue between system api (call frame and track abstraction) and WASM.
///
Expand Down
4 changes: 2 additions & 2 deletions radix-engine/src/engine/kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use radix_engine_interface::api::types::{
use radix_engine_interface::crypto::Hash;
use radix_engine_interface::data::*;

use sbor::rust::fmt::Debug;
use sbor::rust::mem;
use scrypto::access_rule_node;
use scrypto::rule;
use std::fmt::Debug;
use std::mem;
use transaction::errors::IdAllocationError;
use transaction::model::AuthZoneParams;
use transaction::validation::*;
Expand Down
2 changes: 1 addition & 1 deletion radix-engine/src/engine/modules/execution_trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use radix_engine_interface::api::types::{
use radix_engine_interface::data::IndexedScryptoValue;
use radix_engine_interface::math::Decimal;
use radix_engine_interface::model::*;
use std::fmt::Debug;
use sbor::rust::fmt::Debug;

#[derive(Debug, Clone, PartialEq, Eq)]
#[scrypto(TypeId, Encode, Decode)]
Expand Down
4 changes: 2 additions & 2 deletions radix-engine/src/model/kv_store/node.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use sbor::rust::collections::HashMap;

use crate::model::KeyValueStoreEntrySubstate;
use sbor::rust::collections::HashMap;
use sbor::rust::vec::Vec;

#[derive(Debug)]
pub struct KeyValueStore {
Expand Down
1 change: 1 addition & 0 deletions radix-engine/src/model/method_authorization.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use radix_engine_interface::math::Decimal;
use radix_engine_interface::model::*;
use sbor::rust::vec::Vec;
use sbor::*;
use scrypto::scrypto;

Expand Down
2 changes: 1 addition & 1 deletion radix-engine/src/model/resources/substates/vault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::model::{
ResourceOperationError, VaultError,
};
use crate::types::*;
use std::ops::Deref;
use sbor::rust::ops::Deref;

#[derive(Debug, Clone, PartialEq, Eq)]
#[scrypto(TypeId, Encode, Decode)]
Expand Down
34 changes: 18 additions & 16 deletions radix-engine/src/transaction/preview_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,24 @@ pub fn execute_preview<S: ReadableSubstateStore, W: WasmEngine, IHM: IntentHashM

let validator = NotarizedTransactionValidator::new(validation_config);

let executable = validator
.validate_preview_intent(&preview_intent, intent_hash_manager)
.map_err(PreviewError::TransactionValidationError)?;

let mut fee_reserve = SystemLoanFeeReserve::default();
if preview_intent.flags.unlimited_loan {
fee_reserve.credit(PREVIEW_CREDIT);
}

let receipt = execute_transaction_with_fee_reserve(
substate_store,
scrypto_interpreter,
SystemLoanFeeReserve::default(),
&ExecutionConfig::default(),
&executable,
);
let receipt = {
let executable = validator
.validate_preview_intent(&preview_intent, intent_hash_manager)
.map_err(PreviewError::TransactionValidationError)?;

let mut fee_reserve = SystemLoanFeeReserve::default();
if preview_intent.flags.unlimited_loan {
fee_reserve.credit(PREVIEW_CREDIT);
}

execute_transaction_with_fee_reserve(
substate_store,
scrypto_interpreter,
SystemLoanFeeReserve::default(),
&ExecutionConfig::default(),
&executable,
)
};

Ok(PreviewResult {
intent: preview_intent,
Expand Down
3 changes: 1 addition & 2 deletions radix-engine/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub use sbor::rust::collections::*;
pub use sbor::rust::fmt;
pub use sbor::rust::format;
pub use sbor::rust::marker::PhantomData;
pub use sbor::rust::num::NonZeroUsize;
pub use sbor::rust::ops::AddAssign;
pub use sbor::rust::ptr;
pub use sbor::rust::rc::Rc;
Expand All @@ -33,8 +34,6 @@ pub use sbor::{Decode, DecodeError, Encode, SborPath, SborPathBuf, SborTypeId, S

pub use scrypto::abi::{BlueprintAbi, Fields, Fn, Type, Variant};

use std::fmt::Debug;

// methods and macros
use crate::engine::Invocation;

Expand Down
3 changes: 1 addition & 2 deletions radix-engine/src/wasm/cost_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ impl Rules for InstructionCostRules {
mod tests {
use super::*;
use crate::wasm::WasmModule;
use wabt::{wasm2wat, wat2wasm};
use wabt::wat2wasm;

#[test]
fn test_cost_rules() {
Expand Down Expand Up @@ -271,7 +271,6 @@ mod tests {
.to_bytes()
.unwrap()
.0;
println!("{}", wasm2wat(&transformed).unwrap());

// Costs:
// 12 = 10 (local.get) + 1 (i32.const) + 1 (i32.mul)
Expand Down
7 changes: 3 additions & 4 deletions radix-engine/src/wasm/traits.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use super::InstrumentedCode;
use crate::model::InvokeError;
use crate::wasm::errors::*;
use radix_engine_interface::data::IndexedScryptoValue;
use sbor::rust::boxed::Box;

use crate::wasm::errors::*;

use super::InstrumentedCode;
use sbor::rust::vec::Vec;

/// Represents the runtime that can be invoked by Scrypto modules.
pub trait WasmRuntime {
Expand Down
34 changes: 28 additions & 6 deletions radix-engine/src/wasm/wasm_instrumenter.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
use moka::sync::Cache;
use radix_engine_interface::crypto::hash;
use std::sync::Arc;
use sbor::rust::sync::Arc;

use crate::types::*;
use crate::wasm::{WasmMeteringConfig, WasmModule};

pub struct WasmInstrumenter {
cache: Cache<(Hash, Hash), Arc<Vec<u8>>>,
#[cfg(not(feature = "moka"))]
cache: RefCell<lru::LruCache<(Hash, Hash), Arc<Vec<u8>>>>,
#[cfg(feature = "moka")]
cache: moka::sync::Cache<(Hash, Hash), Arc<Vec<u8>>>,
}

#[derive(Debug, Clone)]
pub struct InstrumenterOptions {
max_cache_size_bytes: u64,
max_cache_size_bytes: usize,
}

impl Default for WasmInstrumenter {
Expand All @@ -29,15 +31,20 @@ pub struct InstrumentedCode {

impl WasmInstrumenter {
pub fn new(options: InstrumenterOptions) -> Self {
let cache = Cache::builder()
#[cfg(not(feature = "moka"))]
let cache = RefCell::new(lru::LruCache::new(
NonZeroUsize::new(options.max_cache_size_bytes / (1024 * 1024)).unwrap(),
));
#[cfg(feature = "moka")]
let cache = moka::sync::Cache::builder()
.weigher(|_key: &(Hash, Hash), value: &Arc<Vec<u8>>| -> u32 {
value
.len()
.checked_add(Hash::LENGTH * 2)
.and_then(|total| total.try_into().ok())
.unwrap_or(u32::MAX)
})
.max_capacity(options.max_cache_size_bytes)
.max_capacity(options.max_cache_size_bytes as u64)
.build();

Self { cache }
Expand All @@ -51,6 +58,16 @@ impl WasmInstrumenter {
let code_hash = hash(code);
let cache_key = (code_hash, *wasm_metering_config.identifier());

#[cfg(not(feature = "moka"))]
{
if let Some(cached) = self.cache.borrow_mut().get(&cache_key) {
return InstrumentedCode {
code: cached.clone(),
code_hash,
};
}
}
#[cfg(feature = "moka")]
if let Some(cached) = self.cache.get(&cache_key) {
return InstrumentedCode {
code: cached.clone(),
Expand All @@ -60,6 +77,11 @@ impl WasmInstrumenter {

let instrumented_ref = Arc::new(self.instrument_no_cache(code, wasm_metering_config));

#[cfg(not(feature = "moka"))]
self.cache
.borrow_mut()
.put(cache_key, instrumented_ref.clone());
#[cfg(feature = "moka")]
self.cache.insert(cache_key, instrumented_ref.clone());

InstrumentedCode {
Expand Down
Loading