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

Sylvia upgrade #188

Merged
merged 21 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
9f81b06
Upgrade Sylvia to 0.10, fix as many things as possible
Apr 28, 2024
94171cc
Attempt to fix up virtual staking, still doesn't compile
Apr 28, 2024
71dffdf
Got consumer/converter to compile (but not tests)
ethanfrey May 6, 2024
437fcc4
Remove codecov as we only get errors (seems it needs a paid API key?)
ethanfrey May 6, 2024
528c6e1
Use `sylvia::types::Proxy` in consumer converter tests
jawoznia May 6, 2024
a34baf2
Clippy also happy for converter contract
ethanfrey May 9, 2024
12605d3
Virtual-staking compiles
ethanfrey May 9, 2024
1d3772e
Lost in a message of custom msg/query types
ethanfrey May 9, 2024
632ee1b
External and native staking compile, some tests fail
ethanfrey May 9, 2024
9b2be17
Everything runs minus virtual-staking, some tests fail
ethanfrey May 9, 2024
180aa1e
Clean up obvious errors in virtual-staking
ethanfrey May 9, 2024
3fa51d7
More virtual staking cleanup
ethanfrey May 9, 2024
19b17c2
Restore original jailing logic
ethanfrey May 10, 2024
c4c34f6
Native-staking* and vault tests pass
ethanfrey May 10, 2024
3db923e
Workaround to enable communication between `Empty` and `Custom`
jawoznia May 10, 2024
07fb1ca
More generic, simple-price and converter pass tests
ethanfrey May 13, 2024
1009590
virtual-staking tests work
ethanfrey May 13, 2024
4938265
Test pass, clippy happy :)
ethanfrey May 13, 2024
3092f95
Wasm compilation proper again
ethanfrey May 13, 2024
c5bbcc4
More clippy fixes
ethanfrey May 13, 2024
19e50b2
Merge pull request #189 from osmosis-labs/sylvia-upgrade-custom-empty
ethanfrey May 13, 2024
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
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>>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, this is a lot of non-intuitive changes, but happy to use this as an example to fix others.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is because we moved out of generating Proxy type per contract macro.

Instead we have a sylvia::multitest::Proxy type that is generic over MtApp on which the SimplePriceFeedContract is deployed. So the idea was to link via proxy some contract to the chain.

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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usage actually looks simpler

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!()
}
}
Loading