Skip to content

Commit

Permalink
Use sylvia::types::Proxy in consumer converter tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jawoznia committed May 6, 2024
1 parent 437fcc4 commit 528c6e1
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 33 deletions.
46 changes: 22 additions & 24 deletions contracts/consumer/converter/src/multitest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ mod virtual_staking_mock;

use cosmwasm_std::{coin, coins, Addr, Decimal, StdError, Uint128, Validator};
use cw_multi_test::App as MtApp;
use mesh_apis::converter_api::sv::mt::ConverterApiProxy;
use mesh_apis::converter_api::RewardInfo;
use sylvia::multitest::App;

use crate::contract;
use crate::contract::test_utils::ConverterApi;
use mesh_simple_price_feed::contract::sv::mt::CodeId as PriceFeedCodeId;
use mesh_simple_price_feed::contract::SimplePriceFeedContract;
use sylvia::multitest::{App, Proxy};
use virtual_staking_mock::sv::mt::CodeId as VirtualStakingCodeId;
use virtual_staking_mock::VirtualStakingMock;

use crate::contract::sv::mt::CodeId as ConverterCodeId;
use crate::contract::sv::mt::ConverterContractProxy;
use crate::contract::ConverterContract;
use crate::error::ContractError;
use crate::error::ContractError::Unauthorized;
use crate::multitest::virtual_staking_mock::sv::mt::VirtualStakingMockProxy;

const JUNO: &str = "ujuno";

Expand All @@ -20,10 +27,9 @@ struct SetupArgs<'a> {
}

struct SetupResponse<'a> {
price_feed:
mesh_simple_price_feed::contract::multitest_utils::SimplePriceFeedContractProxy<'a, MtApp>,
converter: contract::multitest_utils::ConverterContractProxy<'a, MtApp>,
virtual_staking: virtual_staking_mock::multitest_utils::VirtualStakingMockProxy<'a, MtApp>,
price_feed: Proxy<'a, MtApp, SimplePriceFeedContract<'a>>,
converter: Proxy<'a, MtApp, ConverterContract<'a>>,
virtual_staking: Proxy<'a, MtApp, VirtualStakingMock<'a>>,
}

fn setup<'a>(app: &'a App<MtApp>, args: SetupArgs<'a>) -> SetupResponse<'a> {
Expand All @@ -34,10 +40,9 @@ fn setup<'a>(app: &'a App<MtApp>, args: SetupArgs<'a>) -> SetupResponse<'a> {
native_per_foreign,
} = args;

let price_feed_code =
mesh_simple_price_feed::contract::multitest_utils::CodeId::store_code(app);
let virtual_staking_code = virtual_staking_mock::multitest_utils::CodeId::store_code(app);
let converter_code = contract::multitest_utils::CodeId::store_code(app);
let price_feed_code = PriceFeedCodeId::store_code(app);
let virtual_staking_code = VirtualStakingCodeId::store_code(app);
let converter_code = ConverterCodeId::store_code(app);

let price_feed = price_feed_code
.instantiate(native_per_foreign, None)
Expand All @@ -60,10 +65,11 @@ fn setup<'a>(app: &'a App<MtApp>, args: SetupArgs<'a>) -> SetupResponse<'a> {

let config = converter.config().unwrap();
let virtual_staking_addr = Addr::unchecked(config.virtual_staking);
let virtual_staking = virtual_staking_mock::multitest_utils::VirtualStakingMockProxy::new(
virtual_staking_addr,
app,
);
// Ideally this should be initialized via `CodeId`.
// Consider bellow approach
//
// let virtual_staking = virtual_staking_code.instantiate().call(owner).unwrap();
let virtual_staking = Proxy::new(virtual_staking_addr, app);

SetupResponse {
price_feed,
Expand Down Expand Up @@ -328,13 +334,11 @@ fn valset_update_works() {

// Check that only the virtual staking contract can call this handler
let res = converter
.converter_api_proxy()
.valset_update(vec![], vec![], vec![], vec![], vec![], vec![], vec![])
.call(owner);
assert_eq!(res.unwrap_err(), Unauthorized {});

let res = converter
.converter_api_proxy()
.valset_update(
add_validators,
rem_validators,
Expand Down Expand Up @@ -374,7 +378,6 @@ fn unauthorized() {
);

let err = converter
.converter_api_proxy()
.distribute_rewards(vec![
RewardInfo {
validator: "alice".to_string(),
Expand All @@ -391,15 +394,13 @@ fn unauthorized() {
assert_eq!(err, ContractError::Unauthorized);

let err = converter
.converter_api_proxy()
.distribute_reward("validator".to_string())
.call("mallory")
.unwrap_err();

assert_eq!(err, ContractError::Unauthorized);

let err = converter
.converter_api_proxy()
.valset_update(vec![], vec![], vec![], vec![], vec![], vec![], vec![])
.call("mallory")
.unwrap_err();
Expand Down Expand Up @@ -442,7 +443,6 @@ fn distribute_rewards_invalid_amount_is_rejected() {
});

let err = converter
.converter_api_proxy()
.distribute_rewards(vec![
RewardInfo {
validator: "alice".to_string(),
Expand All @@ -466,7 +466,6 @@ fn distribute_rewards_invalid_amount_is_rejected() {
);

let err = converter
.converter_api_proxy()
.distribute_rewards(vec![
RewardInfo {
validator: "alice".to_string(),
Expand Down Expand Up @@ -526,7 +525,6 @@ fn distribute_rewards_valid_amount() {
});

converter
.converter_api_proxy()
.distribute_rewards(vec![
RewardInfo {
validator: "alice".to_string(),
Expand Down
43 changes: 34 additions & 9 deletions contracts/consumer/converter/src/multitest/virtual_staking_mock.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{ensure_eq, Addr, Coin, Response, StdError, StdResult, Uint128};
use cosmwasm_std::{ensure_eq, Addr, Coin, Response, StdError, StdResult, Uint128, Validator};

use cw_storage_plus::{Item, Map};
use cw_utils::{nonpayable, PaymentError};
use mesh_apis::virtual_staking_api::{self, VirtualStakingApi};
use mesh_apis::virtual_staking_api::{self, ValidatorSlash, VirtualStakingApi};
use sylvia::contract;
use sylvia::types::{ExecCtx, InstantiateCtx, QueryCtx};
use sylvia::types::{ExecCtx, InstantiateCtx, QueryCtx, SudoCtx};

#[cw_serde]
pub struct Config {
Expand Down Expand Up @@ -41,7 +41,7 @@ pub struct VirtualStakingMock<'a> {
}

#[contract]
#[error(ContractError)]
#[sv::error(ContractError)]
#[sv::messages(virtual_staking_api as VirtualStakingApi)]
impl VirtualStakingMock<'_> {
pub const fn new() -> Self {
Expand Down Expand Up @@ -106,15 +106,12 @@ pub struct ConfigResponse {
pub converter: String,
}

#[contract]
#[sv::messages(virtual_staking_api as VirtualStakingApi)]
impl VirtualStakingApi for VirtualStakingMock<'_> {
type Error = ContractError;

/// Requests to bond tokens to a validator. This will be actually handled at the next epoch.
/// If the virtual staking module is over the max cap, it will trigger a rebalance.
/// If the max cap is 0, then this will immediately return an error.
#[sv::msg(exec)]
fn bond(&self, ctx: ExecCtx, validator: String, amount: Coin) -> Result<Response, Self::Error> {
nonpayable(&ctx.info)?;
let cfg = self.config.load(ctx.deps.storage)?;
Expand All @@ -137,7 +134,6 @@ impl VirtualStakingApi for VirtualStakingMock<'_> {
/// Requests to unbond tokens from a validator. This will be actually handled at the next epoch.
/// If the virtual staking module is over the max cap, it will trigger a rebalance in addition to unbond.
/// If the virtual staking contract doesn't have at least amount tokens staked to the given validator, this will return an error.
#[sv::msg(exec)]
fn unbond(
&self,
ctx: ExecCtx,
Expand Down Expand Up @@ -165,7 +161,6 @@ impl VirtualStakingApi for VirtualStakingMock<'_> {
/// Requests to unbond and burn tokens from a lists of validators (one or more). This will be actually handled at the next epoch.
/// If the virtual staking module is over the max cap, it will trigger a rebalance in addition to unbond.
/// If the virtual staking contract doesn't have at least amount tokens staked over the given validators, this will return an error.
#[sv::msg(exec)]
fn burn(
&self,
ctx: ExecCtx,
Expand Down Expand Up @@ -222,4 +217,34 @@ impl VirtualStakingApi for VirtualStakingMock<'_> {

Ok(Response::new())
}

/// SudoMsg::HandleEpoch{} should be called once per epoch by the sdk (in EndBlock).
/// It allows the virtual staking contract to bond or unbond any pending requests, as well
/// as to perform a rebalance if needed (over the max cap).
///
/// It should also withdraw all pending rewards here, and send them to the converter contract.
fn handle_epoch(&self, ctx: SudoCtx) -> Result<Response, Self::Error> {
unimplemented!()
}

/// SudoMsg::ValsetUpdate{} should be called every time there's a validator set update:
/// - Addition of a new validator to the active validator set.
/// - Temporary removal of a validator from the active set. (i.e. `unbonded` state).
/// - Update of validator data.
/// - Temporary removal of a validator from the active set due to jailing. Implies slashing.
/// - Addition of an existing validator to the active validator set.
/// - Permanent removal (i.e. tombstoning) of a validator from the active set. Implies slashing
fn handle_valset_update(
&self,
ctx: SudoCtx,
additions: Option<Vec<Validator>>,
removals: Option<Vec<String>>,
updated: Option<Vec<Validator>>,
jailed: Option<Vec<String>>,
unjailed: Option<Vec<String>>,
tombstoned: Option<Vec<String>>,
slashed: Option<Vec<ValidatorSlash>>,
) -> Result<Response, Self::Error> {
unimplemented!()
}
}

0 comments on commit 528c6e1

Please sign in to comment.