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

feat: Implement MockApi::new_with_gas_cost #89

Merged
merged 1 commit into from
Mar 25, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 51 additions & 4 deletions packages/vm/src/testing/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use super::storage::MockStorage;
use crate::{Api, Backend, BackendError, BackendResult, GasInfo};

pub const MOCK_CONTRACT_ADDR: &str = "cosmos2contract";
const GAS_COST_HUMANIZE: u64 = 44;
const GAS_COST_CANONICALIZE: u64 = 55;
const DEFAULT_GAS_COST_HUMANIZE: u64 = 44;
const DEFAULT_GAS_COST_CANONICALIZE: u64 = 55;

/// All external requirements that can be injected for unit tests.
/// It sets the given balance for the contract itself, nothing else
Expand Down Expand Up @@ -40,6 +40,10 @@ pub struct MockApi {
/// Length of canonical addresses created with this API. Contracts should not make any assumtions
/// what this value is.
pub canonical_length: usize,
/// `canonicalize_cost` is consumed gas value when the contract all api `canonical_address`
pub canonicalize_cost: u64,
/// `humanize_cost` is consumed gas value when the contract all api `human_address`
pub humanize_cost: u64,
/// When set, all calls to the API fail with BackendError::Unknown containing this message
backend_error: Option<&'static str>,
}
Expand All @@ -53,6 +57,15 @@ impl MockApi {
MockApi::default()
}

/// create a `MockApi` instance with specified gas costs to call api
pub fn new_with_gas_cost(canonicalize_cost: u64, humanize_cost: u64) -> Self {
MockApi {
canonicalize_cost,
humanize_cost,
..MockApi::default()
}
}

pub fn new_failing(backend_error: &'static str) -> Self {
MockApi {
backend_error: Some(backend_error),
Expand All @@ -65,14 +78,16 @@ impl Default for MockApi {
fn default() -> Self {
MockApi {
canonical_length: 24,
canonicalize_cost: DEFAULT_GAS_COST_CANONICALIZE,
humanize_cost: DEFAULT_GAS_COST_HUMANIZE,
backend_error: None,
}
}
}

impl Api for MockApi {
fn canonical_address(&self, human: &HumanAddr) -> BackendResult<CanonicalAddr> {
let gas_info = GasInfo::with_cost(GAS_COST_CANONICALIZE);
let gas_info = GasInfo::with_cost(self.canonicalize_cost);

if let Some(backend_error) = self.backend_error {
return (Err(BackendError::unknown(backend_error)), gas_info);
Expand Down Expand Up @@ -110,7 +125,7 @@ impl Api for MockApi {
}

fn human_address(&self, canonical: &CanonicalAddr) -> BackendResult<HumanAddr> {
let gas_info = GasInfo::with_cost(GAS_COST_HUMANIZE);
let gas_info = GasInfo::with_cost(self.humanize_cost);

if let Some(backend_error) = self.backend_error {
return (Err(BackendError::unknown(backend_error)), gas_info);
Expand Down Expand Up @@ -232,4 +247,36 @@ mod test {
err => panic!("Unexpected error: {:?}", err),
}
}

#[test]
fn test_default_gas_cost() {
let api = MockApi::default();

let original = HumanAddr::from("alice");
let (canonical_res, gas_cost) = api.canonical_address(&original);
assert_eq!(gas_cost.cost, DEFAULT_GAS_COST_CANONICALIZE);
assert_eq!(gas_cost.externally_used, 0);
let canonical = canonical_res.unwrap();
let (_recovered, gas_cost) = api.human_address(&canonical);
assert_eq!(gas_cost.cost, DEFAULT_GAS_COST_HUMANIZE);
assert_eq!(gas_cost.externally_used, 0);
}

#[test]
fn test_specified_gas_cost() {
let canonicalize_cost: u64 = 42;
let humanize_cost: u64 = 10101010;
assert_ne!(canonicalize_cost, DEFAULT_GAS_COST_CANONICALIZE);
assert_ne!(humanize_cost, DEFAULT_GAS_COST_HUMANIZE);
let api = MockApi::new_with_gas_cost(canonicalize_cost, humanize_cost);

let original = HumanAddr::from("bob");
let (canonical_res, gas_cost) = api.canonical_address(&original);
assert_eq!(gas_cost.cost, canonicalize_cost);
assert_eq!(gas_cost.externally_used, 0);
let canonical = canonical_res.unwrap();
let (_recovered, gas_cost) = api.human_address(&canonical);
assert_eq!(gas_cost.cost, humanize_cost);
assert_eq!(gas_cost.externally_used, 0);
}
}