Skip to content

Commit

Permalink
Sketch of cheaper instantiation change
Browse files Browse the repository at this point in the history
  • Loading branch information
graydon committed Mar 7, 2024
1 parent abd977d commit ecb144c
Show file tree
Hide file tree
Showing 26 changed files with 937 additions and 130 deletions.
7 changes: 2 additions & 5 deletions Cargo.lock

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

12 changes: 8 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,26 @@ soroban-env-guest = { version = "=20.2.2", path = "soroban-env-guest" }
soroban-env-host = { version = "=20.2.2", path = "soroban-env-host" }
soroban-env-macros = { version = "=20.2.2", path = "soroban-env-macros" }
soroban-builtin-sdk-macros = { version = "=20.2.2", path = "soroban-builtin-sdk-macros" }
# NB: this must match the wasmparser version wasmi is using
wasmparser = "=0.116.1"

# NB: When updating, also update the version in rs-soroban-env dev-dependencies
[workspace.dependencies.stellar-xdr]
version = "=20.1.0"
path = "/src/rs-stellar-xdr/"
# git = "https://github.com/stellar/rs-stellar-xdr"
# rev = "8b9d623ef40423a8462442b86997155f2c04d3a1"
default-features = false

[workspace.dependencies.wasmi]
package = "soroban-wasmi"
version = "=0.31.1-soroban.20.0.1"
git = "https://github.com/stellar/wasmi"
rev = "0ed3f3dee30dc41ebe21972399e0a73a41944aa0"
path = "/src/wasmi/crates/wasmi/"
#git = "https://github.com/stellar/wasmi"
#rev = "0ed3f3dee30dc41ebe21972399e0a73a41944aa0"

# [patch."https://github.com/stellar/rs-stellar-xdr"]
# stellar-xdr = { path = "../rs-stellar-xdr/" }
#[patch."https://github.com/stellar/rs-stellar-xdr"]
# stellar-xdr = { path = "/src/rs-stellar-xdr/" }
# [patch."https://github.com/stellar/wasmi"]
# soroban-wasmi = { path = "../wasmi/crates/wasmi/" }
# soroban-wasmi_core = { path = "../wasmi/crates/core/" }
Expand Down
3 changes: 2 additions & 1 deletion soroban-env-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ crate-git-revision = "=0.0.6"
soroban-env-macros = { workspace = true }
stellar-xdr = { workspace = true, default-features = false, features = [ "curr" ] }
wasmi = { workspace = true, optional = true }
wasmparser = { workspace = true, optional = true}
serde = { version = "=1.0.192", features = ["derive"], optional = true }
static_assertions = "=1.1.0"
ethnum = "=1.5.0"
Expand All @@ -34,7 +35,7 @@ num-traits = "=0.2.17"
[features]
std = ["stellar-xdr/std", "stellar-xdr/base64"]
serde = ["dep:serde", "stellar-xdr/serde"]
wasmi = ["dep:wasmi"]
wasmi = ["dep:wasmi", "dep:wasmparser"]
testutils = ["dep:arbitrary", "stellar-xdr/arbitrary"]
next = ["stellar-xdr/next", "soroban-env-macros/next"]
tracy = ["dep:tracy-client"]
Expand Down
7 changes: 7 additions & 0 deletions soroban-env-common/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,13 @@ impl From<wasmi::Error> for Error {
}
}

#[cfg(feature = "wasmi")]
impl From<wasmparser::BinaryReaderError> for Error {
fn from(_: wasmparser::BinaryReaderError) -> Self {
Error::from_type_and_code(ScErrorType::WasmVm, ScErrorCode::InvalidInput)
}
}

impl Error {
// NB: we don't provide a "get_type" to avoid casting a bad bit-pattern into
// an ScErrorType. Instead we provide an "is_type" to check any specific
Expand Down
2 changes: 2 additions & 0 deletions soroban-env-host/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ exclude = ["observations/"]
soroban-builtin-sdk-macros = { workspace = true }
soroban-env-common = { workspace = true, features = ["std", "wasmi", "shallow-val-hash"] }
wasmi = { workspace = true }
wasmparser = { workspace = true }
stellar-strkey = "=0.0.8"
static_assertions = "=1.1.0"
sha2 = "=0.10.8"
Expand Down Expand Up @@ -85,6 +86,7 @@ rustversion = "1.0"

[dev-dependencies.stellar-xdr]
version = "=20.1.0"
path = "/src/rs-stellar-xdr"
# git = "https://github.com/stellar/rs-stellar-xdr"
# rev = "8b9d623ef40423a8462442b86997155f2c04d3a1"
default-features = false
Expand Down
2 changes: 1 addition & 1 deletion soroban-env-host/benches/common/cost_types/invoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl HostCostMeasurement for InvokeVmFunctionMeasure {
fn new_random_case(host: &Host, _rng: &mut StdRng, _input: u64) -> (Rc<Vm>, Vec<Value>) {
let id: Hash = [0; 32].into();
let code = wasm_module_with_empty_invoke();
let vm = Vm::new(&host, id, &code).unwrap();
let vm = Vm::new(&host, id, &code, None).unwrap();
let args = vec![Value::I64(0); MAX_VM_ARGS];
(vm, args)
}
Expand Down
173 changes: 144 additions & 29 deletions soroban-env-host/benches/common/cost_types/vm_ops.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1,160 @@
#[allow(unused)]
use super::wasm_insn_exec::{wasm_module_with_4n_insns, wasm_module_with_n_internal_funcs};
use super::wasm_insn_exec::{
wasm_module_with_n_data_segments, wasm_module_with_n_elem_segments, wasm_module_with_n_exports,
wasm_module_with_n_globals, wasm_module_with_n_imports, wasm_module_with_n_insns,
wasm_module_with_n_internal_funcs, wasm_module_with_n_table_entries, wasm_module_with_n_types,
};
use crate::common::{util, HostCostMeasurement};
use rand::{rngs::StdRng, Rng};
use soroban_env_host::{
cost_runner::{VmInstantiationRun, VmInstantiationSample},
xdr, Host,
cost_runner::{
VmInstantiationDataSegmentsRun, VmInstantiationElemSegmentsRun, VmInstantiationExportsRun,
VmInstantiationFunctionsRun, VmInstantiationGlobalsRun, VmInstantiationImportsRun,
VmInstantiationInstructionsRun, VmInstantiationRun, VmInstantiationSample,
VmInstantiationTableEntriesRun, VmInstantiationTypesRun,
},
xdr, Host, Vm,
};

pub(crate) struct VmInstantiationMeasure;
pub(crate) struct VmInstantiationInstructionsMeasure;
pub(crate) struct VmInstantiationFunctionsMeasure;
pub(crate) struct VmInstantiationGlobalsMeasure;
pub(crate) struct VmInstantiationTableEntriesMeasure;
pub(crate) struct VmInstantiationTypesMeasure;
pub(crate) struct VmInstantiationDataSegmentsMeasure;
pub(crate) struct VmInstantiationElemSegmentsMeasure;
pub(crate) struct VmInstantiationImportsMeasure;
pub(crate) struct VmInstantiationExportsMeasure;

// This measures the cost of instantiating a host::Vm on a variety of possible
// wasm modules, of different sizes. The input value should be the size of the
// module, though for now we're just selecting modules from the fixed example
// repertoire. Costs should be linear.
impl HostCostMeasurement for VmInstantiationMeasure {
type Runner = VmInstantiationRun;
macro_rules! impl_measurement_for_instantiation_cost_type {
($RUNNER:ty, $MEASURE:ty, $BUILD:ident, $HAS_INPUTS:expr, $MAGNITUDE:expr) => {
impl HostCostMeasurement for $MEASURE {
type Runner = $RUNNER;

fn new_best_case(_host: &Host, _rng: &mut StdRng) -> VmInstantiationSample {
let id: xdr::Hash = [0; 32].into();
let wasm: Vec<u8> = soroban_test_wasms::ADD_I32.into();
VmInstantiationSample { id: Some(id), wasm }
}
fn new_best_case(_host: &Host, _rng: &mut StdRng) -> VmInstantiationSample {
let id: xdr::Hash = [0; 32].into();
let wasm: Vec<u8> = soroban_test_wasms::ADD_I32.into();
VmInstantiationSample {
id: Some(id),
wasm,
cost_inputs: None,
}
}

fn new_worst_case(_host: &Host, _rng: &mut StdRng, input: u64) -> VmInstantiationSample {
let id: xdr::Hash = [0; 32].into();
// generate a test wasm contract with many trivial internal functions,
// which represents the worst case in terms of work needed for WASM parsing.
let n = (Self::INPUT_BASE_SIZE + input * 30) as usize;
let wasm = wasm_module_with_n_internal_funcs(n);
// replace the above two lines with these below to test with wasm contracts
// with a single function of many instructions. In both tests the cpu grows
// linearly with the contract size however the slopes are very different.
// let n = (input * 50) as usize;
// let wasm = wasm_module_with_4n_insns(n);
VmInstantiationSample { id: Some(id), wasm }
}
fn new_worst_case(host: &Host, _rng: &mut StdRng, input: u64) -> VmInstantiationSample {
let id: xdr::Hash = [0; 32].into();
let n = (Self::INPUT_BASE_SIZE + input * $MAGNITUDE) as usize;
let wasm = $BUILD(n);
let cost_inputs = if $HAS_INPUTS {
let vm = Vm::new(host, id.clone(), &wasm[..], None).unwrap();
Some(vm.get_contract_code_cost_inputs())
} else {
None
};
VmInstantiationSample {
id: Some(id),
wasm,
cost_inputs,
}
}

fn new_random_case(_host: &Host, rng: &mut StdRng, _input: u64) -> VmInstantiationSample {
let id: xdr::Hash = [0; 32].into();
let idx = rng.gen_range(0..=10) % util::TEST_WASMS.len();
let wasm = util::TEST_WASMS[idx].into();
VmInstantiationSample { id: Some(id), wasm }
}
fn new_random_case(
host: &Host,
rng: &mut StdRng,
_input: u64,
) -> VmInstantiationSample {
let id: xdr::Hash = [0; 32].into();
let idx = rng.gen_range(0..=10) % util::TEST_WASMS.len();
let wasm: Vec<u8> = util::TEST_WASMS[idx].into();
let cost_inputs = if $HAS_INPUTS {
let vm = Vm::new(host, id.clone(), &wasm[..], None).unwrap();
Some(vm.get_contract_code_cost_inputs())
} else {
None
};
VmInstantiationSample {
id: Some(id),
wasm,
cost_inputs,
}
}
}
};
}

impl_measurement_for_instantiation_cost_type!(
VmInstantiationRun,
VmInstantiationMeasure,
wasm_module_with_n_internal_funcs,
false,
30
);

impl_measurement_for_instantiation_cost_type!(
VmInstantiationInstructionsRun,
VmInstantiationInstructionsMeasure,
wasm_module_with_n_insns,
true,
30
);
impl_measurement_for_instantiation_cost_type!(
VmInstantiationFunctionsRun,
VmInstantiationFunctionsMeasure,
wasm_module_with_n_internal_funcs,
true,
30
);
impl_measurement_for_instantiation_cost_type!(
VmInstantiationGlobalsRun,
VmInstantiationGlobalsMeasure,
wasm_module_with_n_globals,
true,
30
);
impl_measurement_for_instantiation_cost_type!(
VmInstantiationTableEntriesRun,
VmInstantiationTableEntriesMeasure,
wasm_module_with_n_table_entries,
true,
30
);
impl_measurement_for_instantiation_cost_type!(
VmInstantiationTypesRun,
VmInstantiationTypesMeasure,
wasm_module_with_n_types,
true,
30
);
impl_measurement_for_instantiation_cost_type!(
VmInstantiationDataSegmentsRun,
VmInstantiationDataSegmentsMeasure,
wasm_module_with_n_data_segments,
true,
30
);
impl_measurement_for_instantiation_cost_type!(
VmInstantiationElemSegmentsRun,
VmInstantiationElemSegmentsMeasure,
wasm_module_with_n_elem_segments,
true,
30
);
impl_measurement_for_instantiation_cost_type!(
VmInstantiationImportsRun,
VmInstantiationImportsMeasure,
wasm_module_with_n_imports,
true,
30
);
impl_measurement_for_instantiation_cost_type!(
VmInstantiationExportsRun,
VmInstantiationExportsMeasure,
wasm_module_with_n_exports,
true,
30
);
Loading

0 comments on commit ecb144c

Please sign in to comment.