Skip to content

Commit

Permalink
Feat(benchmarks): update gas bounds after wasm cost reduction (#315)
Browse files Browse the repository at this point in the history
  • Loading branch information
birchmd committed Oct 21, 2021
1 parent 6b1ea7d commit 74bdf4f
Show file tree
Hide file tree
Showing 8 changed files with 655 additions and 103 deletions.
633 changes: 587 additions & 46 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions engine-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ serde_json = "1"
hex = { version = "0.4.3", default-features = false }
near-sdk = { git = "https://github.com/aurora-is-near/near-sdk-rs.git", rev = "5e58722bd61d9d24ae6293326146c751f0a814fb" }
near-sdk-sim = { git = "https://github.com/aurora-is-near/near-sdk-rs.git", rev = "5e58722bd61d9d24ae6293326146c751f0a814fb" }
near-crypto = { git = "https://github.com/near/nearcore.git", rev = "8a377fda0b4ce319385c463f1ae46e4b0b29dcd9" }
near-vm-runner = { git = "https://github.com/near/nearcore.git", rev = "8a377fda0b4ce319385c463f1ae46e4b0b29dcd9" }
near-vm-logic = { git = "https://github.com/near/nearcore.git", rev = "8a377fda0b4ce319385c463f1ae46e4b0b29dcd9" }
near-primitives-core = { git = "https://github.com/near/nearcore.git", rev = "8a377fda0b4ce319385c463f1ae46e4b0b29dcd9" }
near-primitives = { git = "https://github.com/near/nearcore.git", rev = "8a377fda0b4ce319385c463f1ae46e4b0b29dcd9" }
wasmer-runtime-core = { version = "0.18.2", package = "wasmer-runtime-core-near" }
near-crypto = { git = "https://github.com/near/nearcore.git", rev = "0c9ad79a18e431f843e6123cf4559f9c2c5dd228" }
near-vm-runner = { git = "https://github.com/near/nearcore.git", rev = "0c9ad79a18e431f843e6123cf4559f9c2c5dd228" }
near-vm-logic = { git = "https://github.com/near/nearcore.git", rev = "0c9ad79a18e431f843e6123cf4559f9c2c5dd228" }
near-primitives-core = { git = "https://github.com/near/nearcore.git", rev = "0c9ad79a18e431f843e6123cf4559f9c2c5dd228" }
near-primitives = { git = "https://github.com/near/nearcore.git", rev = "0c9ad79a18e431f843e6123cf4559f9c2c5dd228" }
wasmer = { package = "wasmer-near", version = "2.0.1", default-features = false, features = ["singlepass", "universal"] }
libsecp256k1 = "0.3.5"
rand = "0.7.3"
criterion = "0.3.4"
Expand Down
4 changes: 2 additions & 2 deletions engine-tests/src/benches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ fn measure_nft_pagination_gas_usage() {
fn uniswap_benches() {
let mut c = Criterion::default();

let mut context = UniswapTestContext::new("uniswap-wasmer0");
let mut context = UniswapTestContext::new("uniswap-wasmer2");
uniswap::uniswap_benchmark(&mut c, &mut context);

let mut context = UniswapTestContext::new("uniswap-wasmer0-no-gas");
let mut context = UniswapTestContext::new("uniswap-wasmer2-no-gas");
context.no_gas();
uniswap::uniswap_benchmark(&mut c, &mut context);

Expand Down
17 changes: 15 additions & 2 deletions engine-tests/src/test_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,9 @@ impl Default for AuroraRunner {
} else {
std::fs::read("../betanet-test.wasm").unwrap()
};
let mut wasm_config = VMConfig::default();
// See https://github.com/near/nearcore/pull/4979/
wasm_config.regular_op_cost = 2207874;

Self {
aurora_account_id: aurora_account_id.clone(),
Expand All @@ -397,8 +400,8 @@ impl Default for AuroraRunner {
view_config: None,
output_data_receivers: vec![],
},
wasm_config: Default::default(),
fees_config: Default::default(),
wasm_config,
fees_config: RuntimeFeesConfig::test(),
current_protocol_version: u32::MAX,
previous_logs: Default::default(),
}
Expand Down Expand Up @@ -649,3 +652,13 @@ pub fn panic_on_fail(status: TransactionStatus) {
other => panic!("{}", String::from_utf8_lossy(other.as_ref())),
}
}

pub fn assert_gas_bound(total_gas: u64, tgas_bound: u64) {
let bound = tgas_bound * 1_000_000_000_000;
assert!(
total_gas <= bound,
"{} Tgas is not less than {} Tgas",
total_gas / 1_000_000_000_000,
tgas_bound,
);
}
11 changes: 8 additions & 3 deletions engine-tests/src/tests/erc20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,15 @@ fn profile_erc20_get_balance() {
runner.profiled_view_call(test_utils::as_view_call(balance_tx, source_address));
assert!(result.is_ok());

// call costs less than 6 Tgas
assert!(profile.all_gas() / 1_000_000_000_000 < 6);
// call costs less than 4 Tgas
test_utils::assert_gas_bound(profile.all_gas(), 4);
// at least 70% of the cost is spent on wasm computation (as opposed to host functions)
assert!((100 * profile.wasm_gas()) / profile.all_gas() > 70);
let wasm_fraction = (100 * profile.wasm_gas()) / profile.all_gas();
assert!(
wasm_fraction > 69,
"{}% is not greater than 70%",
wasm_fraction
);
}

#[test]
Expand Down
30 changes: 15 additions & 15 deletions engine-tests/src/tests/one_inch.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::prelude::parameters::SubmitResult;
use crate::prelude::{Wei, U256};
use crate::test_utils;
use crate::test_utils::one_inch::liquidity_protocol;
use crate::test_utils::{self, assert_gas_bound};
use borsh::BorshDeserialize;
use near_vm_logic::VMOutcome;
use secp256k1::SecretKey;
Expand All @@ -23,11 +23,11 @@ fn test_1inch_liquidity_protocol() {

let (result, profile, deployer_address) = helper.create_mooniswap_deployer();
assert!(result.gas_used >= 5_100_000); // more than 5.1M EVM gas used
assert!(profile.all_gas() <= 43_000_000_000_000); // less than 43 NEAR Tgas used
assert_gas_bound(profile.all_gas(), 28); // less than 28 NEAR Tgas used

let (result, profile, pool_factory) = helper.create_pool_factory(&deployer_address);
assert!(result.gas_used >= 2_800_000); // more than 2.8M EVM gas used
assert!(profile.all_gas() <= 32_000_000_000_000); // less than 32 NEAR Tgas used
assert_gas_bound(profile.all_gas(), 22); // less than 22 NEAR Tgas used

// create some ERC-20 tokens to have a liquidity pool for
let signer_address = test_utils::address_from_secret_key(&helper.signer.secret_key);
Expand All @@ -39,12 +39,7 @@ fn test_1inch_liquidity_protocol() {
let (result, profile, pool) =
helper.create_pool(&pool_factory, token_a.0.address, token_b.0.address);
assert!(result.gas_used >= 4_500_000); // more than 4.5M EVM gas used
let total_gas = profile.all_gas();
assert!(
total_gas <= 104_000_000_000_000,
"{} is not less than 104 Tgas",
total_gas
); // less than 104 NEAR Tgas used
assert_gas_bound(profile.all_gas(), 67); // less than 67 NEAR Tgas used

// Approve giving ERC-20 tokens to the pool
helper.approve_erc20_tokens(&token_a, pool.address());
Expand All @@ -63,7 +58,7 @@ fn test_1inch_liquidity_protocol() {
},
);
assert!(result.gas_used >= 302_000); // more than 302k EVM gas used
assert!(profile.all_gas() <= 120_000_000_000_000); // less than 120 NEAR Tgas used
assert_gas_bound(profile.all_gas(), 79); // less than 79 NEAR Tgas used

// Same here
helper.runner.context.block_timestamp += 10_000_000 * 1_000_000_000;
Expand All @@ -78,7 +73,7 @@ fn test_1inch_liquidity_protocol() {
},
);
assert!(result.gas_used >= 210_000); // more than 210k EVM gas used
assert!(profile.all_gas() <= 136_000_000_000_000); // less than 136 NEAR Tgas used
assert_gas_bound(profile.all_gas(), 88); // less than 88 NEAR Tgas used

let (result, profile) = helper.pool_withdraw(
&pool,
Expand All @@ -89,7 +84,7 @@ fn test_1inch_liquidity_protocol() {
},
);
assert!(result.gas_used >= 150_000); // more than 150k EVM gas used
assert!(profile.all_gas() <= 102_000_000_000_000); // less than 102 NEAR Tgas used
assert_gas_bound(profile.all_gas(), 68); // less than 68 NEAR Tgas used
}

#[test]
Expand All @@ -105,10 +100,15 @@ fn test_1_inch_limit_order_deploy() {

// more than 3.5 million Ethereum gas used
assert!(result.gas_used > 3_500_000);
// less than 43 NEAR Tgas used
assert!(profile.all_gas() < 43_000_000_000_000);
// less than 27 NEAR Tgas used
assert_gas_bound(profile.all_gas(), 27);
// at least 70% of which is from wasm execution
assert!(100 * profile.wasm_gas() / profile.all_gas() > 70);
let wasm_fraction = 100 * profile.wasm_gas() / profile.all_gas();
assert!(
wasm_fraction > 65,
"{}% is not greater than 65%",
wasm_fraction
);
}

fn deploy_1_inch_limit_order_contract(
Expand Down
35 changes: 18 additions & 17 deletions engine-tests/src/tests/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,8 @@ fn test_deploy_largest_contract() {
result.gas_used,
);

// Less than 45 NEAR Tgas
assert!(
profile.all_gas() <= 45_000_000_000_000,
"{:?} not less than 45 Tgas",
profile.all_gas(),
);
// Less than 28 NEAR Tgas
test_utils::assert_gas_bound(profile.all_gas(), 28);
}

#[test]
Expand Down Expand Up @@ -202,7 +198,7 @@ fn test_num_wasm_functions() {
let runner = test_utils::deploy_evm();
let artifact = get_compiled_artifact(&runner);
let module_info = artifact.info();
let num_functions = module_info.func_assoc.len();
let num_functions = module_info.functions.len();
assert!(
num_functions <= 1400,
"{} is not less than 1400",
Expand Down Expand Up @@ -660,19 +656,24 @@ fn query_address_sim(
}
}

fn get_compiled_artifact(
runner: &test_utils::AuroraRunner,
) -> wasmer_runtime_core::cache::Artifact {
fn get_compiled_artifact(runner: &test_utils::AuroraRunner) -> wasmer::Module {
use near_primitives::types::CompiledContractCache;

near_vm_runner::precompile_contract(&runner.code, &runner.wasm_config, Some(&runner.cache))
.unwrap();
let cache_key = near_vm_runner::get_contract_cache_key(
let current_protocol_version = u32::MAX;
let vm_kind = near_vm_runner::VMKind::for_protocol_version(current_protocol_version);
near_vm_runner::precompile_contract(
&runner.code,
Default::default(),
&runner.wasm_config,
);
let cache_record: Vec<u8> =
current_protocol_version,
Some(&runner.cache),
)
.unwrap()
.unwrap();
let cache_key =
near_vm_runner::get_contract_cache_key(&runner.code, vm_kind, &runner.wasm_config);
let cache_record =
Vec::try_from_slice(&runner.cache.get(cache_key.as_ref()).unwrap().unwrap()[1..]).unwrap();
wasmer_runtime_core::cache::Artifact::deserialize(&cache_record).unwrap()
let store = wasmer::Store::new(&wasmer::Universal::new(wasmer::Singlepass::new()).engine());

unsafe { wasmer::Module::deserialize(&store, &cache_record).unwrap() }
}
16 changes: 4 additions & 12 deletions engine-tests/src/tests/uniswap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,15 @@ fn test_uniswap_exact_output() {

let (_result, profile) =
context.add_equal_liquidity(LIQUIDITY_AMOUNT.into(), &token_a, &token_b);
assert!(
profile.all_gas() <= 165_000_000_000_000,
"{} is not less than 165 Tgas",
profile.all_gas(),
);
test_utils::assert_gas_bound(profile.all_gas(), 107);
let wasm_fraction = 100 * profile.wasm_gas() / profile.all_gas();
assert!(wasm_fraction >= 80, "{}% not more than 80%", wasm_fraction);
assert!(wasm_fraction >= 70, "{}% not more than 70%", wasm_fraction);

let (_amount_in, profile) =
context.exact_output_single(&token_a, &token_b, OUTPUT_AMOUNT.into());
assert!(
profile.all_gas() <= 106_000_000_000_000,
"{} is not less than 106 Tgas",
profile.all_gas(),
);
test_utils::assert_gas_bound(profile.all_gas(), 68);
let wasm_fraction = 100 * profile.wasm_gas() / profile.all_gas();
assert!(wasm_fraction >= 80, "{}% not more than 80%", wasm_fraction);
assert!(wasm_fraction >= 72, "{}% not more than 72%", wasm_fraction);
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
Expand Down

0 comments on commit 74bdf4f

Please sign in to comment.