Skip to content

Commit

Permalink
Charge for cached-module instantiation even in coarse model, fix cali…
Browse files Browse the repository at this point in the history
…bration
  • Loading branch information
graydon committed Mar 15, 2024
1 parent d5eee5c commit c9a01b1
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 107 deletions.
73 changes: 17 additions & 56 deletions soroban-env-host/benches/common/cost_types/vm_ops.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::wasm_insn_exec::wasm_module_with_n_internal_funcs;
use crate::common::{util, HostCostMeasurement};
use rand::{rngs::StdRng, Rng};
use crate::common::HostCostMeasurement;
use rand::rngs::StdRng;
use soroban_env_host::{
cost_runner::{VmInstantiationRun, VmInstantiationSample},
vm::{ParsedModule, VersionedContractCodeCostInputs},
Expand All @@ -18,24 +18,7 @@ macro_rules! impl_measurement_for_instantiation_cost_type {
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();
let cost_inputs = VersionedContractCodeCostInputs::V0 {
wasm_bytes: wasm.len(),
};
let module = Rc::new(
ParsedModule::new_with_isolated_engine(_host, &wasm, cost_inputs.clone())
.unwrap(),
);
VmInstantiationSample {
id: Some(id),
wasm,
module,
}
}

fn new_worst_case(
fn new_random_case(
_host: &Host,
_rng: &mut StdRng,
input: u64,
Expand Down Expand Up @@ -67,44 +50,11 @@ macro_rules! impl_measurement_for_instantiation_cost_type {
module,
}
}

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();
#[allow(unused_mut)]
let mut cost_inputs = VersionedContractCodeCostInputs::V0 {
wasm_bytes: wasm.len(),
};
#[cfg(feature = "next")]
if $USE_REFINED_INPUTS {
cost_inputs = VersionedContractCodeCostInputs::V1(
soroban_env_host::vm::ParsedModule::extract_refined_contract_cost_inputs(
_host,
&wasm[..],
)
.unwrap(),
);
}
let module = Rc::new(
ParsedModule::new_with_isolated_engine(_host, &wasm, cost_inputs.clone())
.unwrap(),
);
VmInstantiationSample {
id: Some(id),
wasm,
module,
}
}
}
};
}

// Protocol 20 coarse cost model
// Protocol 20 coarse unified, or protocol 21 coarse parse-phase cost model
impl_measurement_for_instantiation_cost_type!(
VmInstantiationRun,
VmInstantiationMeasure,
Expand All @@ -113,7 +63,7 @@ impl_measurement_for_instantiation_cost_type!(
30
);

// Protocol 21 refined cost model.
// Protocol 21 cost models.
#[cfg(feature = "next")]
pub(crate) use v21::*;
#[cfg(feature = "next")]
Expand All @@ -135,11 +85,13 @@ mod v21 {
ParseWasmDataSegmentsRun, ParseWasmElemSegmentsRun, ParseWasmExportsRun,
ParseWasmFunctionsRun, ParseWasmGlobalsRun, ParseWasmImportsRun,
ParseWasmInstructionsRun, ParseWasmMemoryPagesRun, ParseWasmTableEntriesRun,
ParseWasmTypesRun, VmInstantiationSample,
ParseWasmTypesRun, VmCachedInstantiationRun, VmInstantiationSample,
},
xdr, Host,
};

pub(crate) struct VmCachedInstantiationMeasure;

pub(crate) struct ParseWasmInstructionsMeasure;
pub(crate) struct ParseWasmFunctionsMeasure;
pub(crate) struct ParseWasmGlobalsMeasure;
Expand All @@ -162,6 +114,15 @@ mod v21 {
pub(crate) struct InstantiateWasmExportsMeasure;
pub(crate) struct InstantiateWasmMemoryPagesMeasure;

// Protocol 21 coarse instantiation-phase cost model
impl_measurement_for_instantiation_cost_type!(
VmCachedInstantiationRun,
VmCachedInstantiationMeasure,
wasm_module_with_n_internal_funcs,
false,
30
);

// Protocol 21 refined cost model
impl_measurement_for_instantiation_cost_type!(
ParseWasmInstructionsRun,
Expand Down
2 changes: 2 additions & 0 deletions soroban-env-host/benches/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ pub(crate) fn for_each_host_cost_measurement<B: Benchmark>(

#[cfg(feature = "next")]
{
call_bench::<B, VmCachedInstantiationMeasure>(&mut params)?;

call_bench::<B, ParseWasmInstructionsMeasure>(&mut params)?;
call_bench::<B, ParseWasmFunctionsMeasure>(&mut params)?;
call_bench::<B, ParseWasmGlobalsMeasure>(&mut params)?;
Expand Down
126 changes: 77 additions & 49 deletions soroban-env-host/src/cost_runner/cost_types/vm_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,64 +6,51 @@ use crate::{
};
use std::{hint::black_box, rc::Rc};

pub struct VmInstantiationRun;

#[derive(Clone)]
pub struct VmInstantiationSample {
pub id: Option<Hash>,
pub wasm: Vec<u8>,
pub module: Rc<ParsedModule>,
}

macro_rules! impl_costrunner_for_instantiation_cost_type {
($RUNNER:ty, $COST:ident) => {
impl CostRunner for $RUNNER {
const COST_TYPE: CostType = CostType::Contract($COST);

const RUN_ITERATIONS: u64 = 10;

type SampleType = VmInstantiationSample;

type RecycledType = (Option<Rc<Vm>>, Vec<u8>);

fn run_iter(
host: &crate::Host,
_iter: u64,
sample: Self::SampleType,
) -> Self::RecycledType {
#[cfg(feature = "next")]
let vm = black_box(
Vm::from_parsed_module(host, sample.id.unwrap(), sample.module).unwrap(),
);
#[cfg(not(feature = "next"))]
let vm = black_box(
Vm::new_with_cost_inputs(
host,
sample.id.unwrap(),
&sample.wasm[..],
sample.module.cost_inputs,
)
.unwrap(),
);
(Some(vm), sample.wasm)
}
// Protocol 20 coarse and unified cost model
#[cfg(not(feature = "next"))]
pub struct VmInstantiationRun;

fn run_baseline_iter(
host: &crate::Host,
_iter: u64,
sample: Self::SampleType,
) -> Self::RecycledType {
black_box(host.charge_budget($COST, Some(0)).unwrap());
black_box((None, sample.wasm))
}
}
};
}
#[cfg(not(feature = "next"))]
impl CostRunner for VmInstantiationRun {
const COST_TYPE: CostType = CostType::Contract(VmInstantiation);

const RUN_ITERATIONS: u64 = 10;

type SampleType = VmInstantiationSample;

type RecycledType = (Option<Rc<Vm>>, Vec<u8>);

fn run_iter(host: &crate::Host, _iter: u64, sample: Self::SampleType) -> Self::RecycledType {
let vm = black_box(
Vm::new_with_cost_inputs(
host,
sample.id.unwrap(),
&sample.wasm[..],
sample.module.cost_inputs.clone(),
)
.unwrap(),
);
(Some(vm), sample.wasm)
}

// Protocol 20 coarse cost model
impl_costrunner_for_instantiation_cost_type!(VmInstantiationRun, VmInstantiation);
fn run_baseline_iter(
host: &crate::Host,
_iter: u64,
sample: Self::SampleType,
) -> Self::RecycledType {
black_box(host.charge_budget(VmInstantiation, Some(0)).unwrap());
black_box((None, sample.wasm))
}
}

// Protocol 21 refined cost model.
// Protocol 21 refined and split/caching cost model.
#[cfg(feature = "next")]
pub use v21::*;
#[cfg(feature = "next")]
Expand All @@ -76,7 +63,7 @@ mod v21 {
InstantiateWasmInstructions, InstantiateWasmMemoryPages, InstantiateWasmTableEntries,
InstantiateWasmTypes, ParseWasmDataSegments, ParseWasmElemSegments, ParseWasmExports,
ParseWasmFunctions, ParseWasmGlobals, ParseWasmImports, ParseWasmInstructions,
ParseWasmMemoryPages, ParseWasmTableEntries, ParseWasmTypes,
ParseWasmMemoryPages, ParseWasmTableEntries, ParseWasmTypes, VmCachedInstantiation,
};

macro_rules! impl_costrunner_for_parse_cost_type {
Expand Down Expand Up @@ -119,6 +106,45 @@ mod v21 {
};
}

macro_rules! impl_costrunner_for_instantiation_cost_type {
($RUNNER:ty, $COST:ident) => {
impl CostRunner for $RUNNER {
const COST_TYPE: CostType = CostType::Contract($COST);

const RUN_ITERATIONS: u64 = 10;

type SampleType = VmInstantiationSample;

type RecycledType = (Option<Rc<Vm>>, Vec<u8>);

fn run_iter(
host: &crate::Host,
_iter: u64,
sample: Self::SampleType,
) -> Self::RecycledType {
let vm = black_box(
Vm::from_parsed_module(host, sample.id.unwrap(), sample.module).unwrap(),
);
(Some(vm), sample.wasm)
}

fn run_baseline_iter(
host: &crate::Host,
_iter: u64,
sample: Self::SampleType,
) -> Self::RecycledType {
black_box(host.charge_budget($COST, Some(0)).unwrap());
black_box((None, sample.wasm))
}
}
};
}

// This cost-type is recycled as unrefined-model, parse-only phase.
pub struct VmInstantiationRun;
// This cost-type is recycled as unrefined-model, instantiate-only phase.
pub struct VmCachedInstantiationRun;

pub struct ParseWasmInstructionsRun;
pub struct ParseWasmFunctionsRun;
pub struct ParseWasmGlobalsRun;
Expand All @@ -141,6 +167,7 @@ mod v21 {
pub struct InstantiateWasmExportsRun;
pub struct InstantiateWasmMemoryPagesRun;

impl_costrunner_for_parse_cost_type!(VmInstantiationRun, VmInstantiation);
impl_costrunner_for_parse_cost_type!(ParseWasmInstructionsRun, ParseWasmInstructions);
impl_costrunner_for_parse_cost_type!(ParseWasmFunctionsRun, ParseWasmFunctions);
impl_costrunner_for_parse_cost_type!(ParseWasmGlobalsRun, ParseWasmGlobals);
Expand All @@ -152,6 +179,7 @@ mod v21 {
impl_costrunner_for_parse_cost_type!(ParseWasmExportsRun, ParseWasmExports);
impl_costrunner_for_parse_cost_type!(ParseWasmMemoryPagesRun, ParseWasmMemoryPages);

impl_costrunner_for_instantiation_cost_type!(VmCachedInstantiationRun, VmCachedInstantiation);
impl_costrunner_for_instantiation_cost_type!(
InstantiateWasmInstructionsRun,
InstantiateWasmInstructions
Expand Down
5 changes: 5 additions & 0 deletions soroban-env-host/src/e2e_testutils.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#[cfg(feature = "next")]
use crate::xdr::ContractCodeEntryExt;
use crate::xdr::{
AccountEntry, AccountEntryExt, AccountId, ContractCodeEntry, ContractDataDurability,
ContractDataEntry, ContractExecutable, ContractIdPreimage, ContractIdPreimageFromAddress,
Expand Down Expand Up @@ -47,7 +49,10 @@ pub fn bytes_sc_val(bytes: &[u8]) -> ScVal {

pub fn wasm_entry(wasm: &[u8]) -> LedgerEntry {
ledger_entry(LedgerEntryData::ContractCode(ContractCodeEntry {
#[cfg(not(feature = "next"))]
ext: ExtensionPoint::V0,
#[cfg(feature = "next")]
ext: ContractCodeEntryExt::V0,
hash: get_wasm_hash(wasm).try_into().unwrap(),
code: wasm.try_into().unwrap(),
}))
Expand Down
7 changes: 5 additions & 2 deletions soroban-env-host/src/vm/parsed_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ impl VersionedContractCodeCostInputs {
}
pub fn charge_for_instantiation(&self, _host: &Host) -> Result<(), HostError> {
match self {
Self::V0 { .. } => {
// No-op, already charged when parsing
Self::V0 { wasm_bytes } => {
_host.charge_budget(
ContractCostType::VmCachedInstantiation,
Some(*wasm_bytes as u64),
)?;
}
#[cfg(feature = "next")]
Self::V1(inputs) => {
Expand Down

0 comments on commit c9a01b1

Please sign in to comment.