Skip to content

Commit

Permalink
Feat(tests): Mock touching trie nodes (#408)
Browse files Browse the repository at this point in the history
  • Loading branch information
birchmd committed Jan 6, 2022
1 parent 47ce48f commit f8ea05c
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 18 deletions.
176 changes: 176 additions & 0 deletions engine-tests/src/test_utils/mocked_external.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
use near_vm_logic::mocks::mock_external::MockedExternal;

pub(crate) struct MockedExternalWithTrie<'a> {
underlying: &'a mut MockedExternal,
trie_node_count: std::cell::Cell<u64>,
}

impl<'a> MockedExternalWithTrie<'a> {
pub fn new(ext: &'a mut MockedExternal) -> Self {
Self {
underlying: ext,
trie_node_count: std::cell::Cell::new(0),
}
}

fn increment_trie_node_count(&self, amount: u64) {
let cell_value = self.trie_node_count.get();
self.trie_node_count.set(cell_value + amount);
}
}

impl<'b> near_vm_logic::External for MockedExternalWithTrie<'b> {
fn storage_set(&mut self, key: &[u8], value: &[u8]) -> Result<(), near_vm_logic::VMLogicError> {
self.increment_trie_node_count(10);
self.underlying.storage_set(key, value)
}

fn storage_get<'a>(
&'a self,
key: &[u8],
) -> Result<Option<Box<dyn near_vm_logic::ValuePtr + 'a>>, near_vm_logic::VMLogicError> {
self.increment_trie_node_count(10);
self.underlying.storage_get(key)
}

fn storage_remove(&mut self, key: &[u8]) -> Result<(), near_vm_logic::VMLogicError> {
self.increment_trie_node_count(10);
self.underlying.storage_remove(key)
}

fn storage_remove_subtree(&mut self, prefix: &[u8]) -> Result<(), near_vm_logic::VMLogicError> {
self.underlying.storage_remove_subtree(prefix)
}

fn storage_has_key(&mut self, key: &[u8]) -> Result<bool, near_vm_logic::VMLogicError> {
self.underlying.storage_has_key(key)
}

fn create_receipt(
&mut self,
receipt_indices: Vec<near_vm_logic::types::ReceiptIndex>,
receiver_id: near_primitives::types::AccountId,
) -> Result<near_vm_logic::types::ReceiptIndex, near_vm_logic::VMLogicError> {
self.underlying.create_receipt(receipt_indices, receiver_id)
}

fn append_action_create_account(
&mut self,
receipt_index: near_vm_logic::types::ReceiptIndex,
) -> Result<(), near_vm_logic::VMLogicError> {
self.underlying.append_action_create_account(receipt_index)
}

fn append_action_deploy_contract(
&mut self,
receipt_index: near_vm_logic::types::ReceiptIndex,
code: Vec<u8>,
) -> Result<(), near_vm_logic::VMLogicError> {
self.underlying
.append_action_deploy_contract(receipt_index, code)
}

fn append_action_function_call(
&mut self,
receipt_index: near_vm_logic::types::ReceiptIndex,
method_name: Vec<u8>,
arguments: Vec<u8>,
attached_deposit: near_primitives::types::Balance,
prepaid_gas: near_primitives::types::Gas,
) -> Result<(), near_vm_logic::VMLogicError> {
self.underlying.append_action_function_call(
receipt_index,
method_name,
arguments,
attached_deposit,
prepaid_gas,
)
}

fn append_action_transfer(
&mut self,
receipt_index: near_vm_logic::types::ReceiptIndex,
amount: near_primitives::types::Balance,
) -> Result<(), near_vm_logic::VMLogicError> {
self.underlying
.append_action_transfer(receipt_index, amount)
}

fn append_action_stake(
&mut self,
receipt_index: near_vm_logic::types::ReceiptIndex,
stake: near_primitives::types::Balance,
public_key: near_vm_logic::types::PublicKey,
) -> Result<(), near_vm_logic::VMLogicError> {
self.underlying
.append_action_stake(receipt_index, stake, public_key)
}

fn append_action_add_key_with_full_access(
&mut self,
receipt_index: near_vm_logic::types::ReceiptIndex,
public_key: near_vm_logic::types::PublicKey,
nonce: u64,
) -> Result<(), near_vm_logic::VMLogicError> {
self.underlying
.append_action_add_key_with_full_access(receipt_index, public_key, nonce)
}

fn append_action_add_key_with_function_call(
&mut self,
receipt_index: near_vm_logic::types::ReceiptIndex,
public_key: near_vm_logic::types::PublicKey,
nonce: u64,
allowance: Option<near_primitives::types::Balance>,
receiver_id: near_primitives::types::AccountId,
method_names: Vec<Vec<u8>>,
) -> Result<(), near_vm_logic::VMLogicError> {
self.underlying.append_action_add_key_with_function_call(
receipt_index,
public_key,
nonce,
allowance,
receiver_id,
method_names,
)
}

fn append_action_delete_key(
&mut self,
receipt_index: near_vm_logic::types::ReceiptIndex,
public_key: near_vm_logic::types::PublicKey,
) -> Result<(), near_vm_logic::VMLogicError> {
self.underlying
.append_action_delete_key(receipt_index, public_key)
}

fn append_action_delete_account(
&mut self,
receipt_index: near_vm_logic::types::ReceiptIndex,
beneficiary_id: near_primitives::types::AccountId,
) -> Result<(), near_vm_logic::VMLogicError> {
self.underlying
.append_action_delete_account(receipt_index, beneficiary_id)
}

fn get_touched_nodes_count(&self) -> u64 {
self.trie_node_count.get()
}

fn reset_touched_nodes_counter(&mut self) {
self.trie_node_count.set(0)
}

fn validator_stake(
&self,
account_id: &near_primitives::types::AccountId,
) -> Result<Option<near_primitives::types::Balance>, near_vm_logic::VMLogicError> {
self.underlying.validator_stake(account_id)
}

fn validator_total_stake(
&self,
) -> Result<near_primitives::types::Balance, near_vm_logic::VMLogicError> {
self.underlying.validator_total_stake()
}
}
6 changes: 4 additions & 2 deletions engine-tests/src/test_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub(crate) const DEPLOY_ERC20: &str = "deploy_erc20_token";

pub(crate) mod erc20;
pub(crate) mod exit_precompile;
pub(crate) mod mocked_external;
pub(crate) mod one_inch;
pub(crate) mod random;
pub(crate) mod rust;
Expand Down Expand Up @@ -183,10 +184,11 @@ impl AuroraRunner {
input,
);

let mut ext = mocked_external::MockedExternalWithTrie::new(&mut self.ext);
let (maybe_outcome, maybe_error) = near_vm_runner::run(
&self.code,
method_name,
&mut self.ext,
&mut ext,
self.context.clone(),
&self.wasm_config,
&self.fees_config,
Expand Down Expand Up @@ -538,7 +540,7 @@ impl Default for AuroraRunner {
/// (which was removed in https://github.com/near/nearcore/pull/4438).
#[derive(Default, Clone)]
pub(crate) struct ExecutionProfile {
host_breakdown: ProfileData,
pub host_breakdown: ProfileData,
wasm_gas: u64,
}

Expand Down
20 changes: 10 additions & 10 deletions engine-tests/src/tests/one_inch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_gas_bound(profile.all_gas(), 15); // less than 15 NEAR Tgas used
assert_gas_bound(profile.all_gas(), 20); // less than 20 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_gas_bound(profile.all_gas(), 13); // less than 22 NEAR Tgas used
assert_gas_bound(profile.all_gas(), 19); // less than 19 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,7 +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
assert_gas_bound(profile.all_gas(), 36); // less than 36 NEAR Tgas used
assert_gas_bound(profile.all_gas(), 59); // less than 59 NEAR Tgas used

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

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

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

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

// more than 3.5 million Ethereum gas used
assert!(result.gas_used > 3_500_000);
// less than 15 NEAR Tgas used
assert_gas_bound(profile.all_gas(), 15);
// less than 18 NEAR Tgas used
assert_gas_bound(profile.all_gas(), 18);
// at least 45% of which is from wasm execution
let wasm_fraction = 100 * profile.wasm_gas() / profile.all_gas();
assert!(
wasm_fraction >= 45,
"{}% is not greater than 45%",
wasm_fraction >= 33,
"{}% is not greater than 33%",
wasm_fraction
);
}
Expand Down
4 changes: 2 additions & 2 deletions engine-tests/src/tests/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ fn test_deploy_largest_contract() {
result.gas_used,
);

// Less than 28 NEAR Tgas
test_utils::assert_gas_bound(profile.all_gas(), 15);
// Less than 20 NEAR Tgas
test_utils::assert_gas_bound(profile.all_gas(), 20);
}

#[test]
Expand Down
8 changes: 4 additions & 4 deletions engine-tests/src/tests/uniswap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ fn test_uniswap_exact_output() {

let (_result, profile) =
context.add_equal_liquidity(LIQUIDITY_AMOUNT.into(), &token_a, &token_b);
test_utils::assert_gas_bound(profile.all_gas(), 64);
test_utils::assert_gas_bound(profile.all_gas(), 126);
let wasm_fraction = 100 * profile.wasm_gas() / profile.all_gas();
assert!(wasm_fraction >= 46, "{}% not more than 46%", wasm_fraction);
assert!(wasm_fraction >= 23, "{}% not more than 23%", wasm_fraction);

let (_amount_in, profile) =
context.exact_output_single(&token_a, &token_b, OUTPUT_AMOUNT.into());
test_utils::assert_gas_bound(profile.all_gas(), 36);
test_utils::assert_gas_bound(profile.all_gas(), 61);
let wasm_fraction = 100 * profile.wasm_gas() / profile.all_gas();
assert!(wasm_fraction >= 52, "{}% not more than 52%", wasm_fraction);
assert!(wasm_fraction >= 30, "{}% not more than 30%", wasm_fraction);
}

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

0 comments on commit f8ea05c

Please sign in to comment.