Skip to content

Commit

Permalink
feat: add contract migration system
Browse files Browse the repository at this point in the history
  • Loading branch information
gorgos committed Feb 24, 2024
1 parent f7f84e5 commit 61a2c07
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 33 deletions.
51 changes: 26 additions & 25 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions contracts/swap/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
authors = [ "Markus Waas <[email protected]>" ]
edition = "2021"
name = "injective-converter"
version = "1.0.0"
name = "swap-contract"
version = "1.1.0"

exclude = [
# Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.
Expand Down Expand Up @@ -45,6 +45,7 @@ serde-json-wasm = "0.5.1"
thiserror = { version = "1.0.31" }

[dev-dependencies]
cosmos-sdk-proto = { version = "0.19.0", default-features = false }
cosmwasm-schema = "1.5.0"
cw-multi-test = "0.16.2"
injective-std = { version = "0.1.5" }
Expand Down
2 changes: 2 additions & 0 deletions contracts/swap/src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub fn save_config(
fee_recipient,
admin,
};
config.to_owned().validate()?;

CONFIG.save(deps.storage, &config)
}

Expand Down
56 changes: 53 additions & 3 deletions contracts/swap/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ use cosmwasm_std::{
use cw2::{get_contract_version, set_contract_version};

use crate::admin::{delete_route, save_config, set_route, update_config, withdraw_support_funds};
use crate::helpers::handle_config_migration;
use crate::types::{ConfigResponse, SwapQuantityMode};
use injective_cosmwasm::{InjectiveMsgWrapper, InjectiveQueryWrapper};

use crate::error::ContractError;

use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
use crate::queries::{estimate_swap_result, SwapQuantity};
use crate::state::{get_all_swap_routes, get_config, read_swap_route};
use crate::swap::{handle_atomic_order_reply, start_swap_flow};

// version info for migration info
pub const CONTRACT_NAME: &str = "crates.io:atomic-order-example";
pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

pub const ATOMIC_ORDER_REPLY_ID: u64 = 1u64;
Expand All @@ -32,6 +32,7 @@ pub fn instantiate(
) -> Result<Response<InjectiveMsgWrapper>, ContractError> {
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
save_config(deps, env, msg.admin, msg.fee_recipient)?;

Ok(Response::new()
.add_attribute("method", "instantiate")
.add_attribute("owner", info.sender))
Expand Down Expand Up @@ -98,6 +99,55 @@ pub fn reply(
}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(
deps: DepsMut<InjectiveQueryWrapper>,
_env: Env,
_msg: MigrateMsg,
) -> Result<Response, ContractError> {
let contract_version = get_contract_version(deps.storage)?;

match contract_version.contract.as_ref() {
// old contract name
"crates.io:atomic-order-example" => match contract_version.version.as_ref() {
"0.1.0" => {
unimplemented!(
"Migration from version {} is no longer supported",
contract_version.version
);
}
"1.0.0" => {
deps.api.debug("BBB");

set_contract_version(
deps.storage,
format!("crates.io:{CONTRACT_NAME}"),
CONTRACT_VERSION,
)?;

handle_config_migration(deps)?;
}
_ => return Err(ContractError::MigrationError {}),
},
"crates.io:swap-contract" => match contract_version.version.as_ref() {
"1.0.1" => {
unimplemented!(
"Migration from version {} is no yet supported",
contract_version.version
);
}
_ => return Err(ContractError::MigrationError {}),
},
_ => return Err(ContractError::MigrationError {}),
}

Ok(Response::new()
.add_attribute("previous_contract_name", &contract_version.contract)
.add_attribute("previous_contract_version", &contract_version.version)
.add_attribute("new_contract_name", format!("crates.io:{CONTRACT_NAME}"))
.add_attribute("new_contract_version", CONTRACT_VERSION))
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps<InjectiveQueryWrapper>, env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
Expand Down
5 changes: 4 additions & 1 deletion contracts/swap/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub enum ContractError {
#[error("Failure response from submsg: {0}")]
SubMsgFailure(String),

#[error("Unrecognised reply id: {0}")]
#[error("Unrecognized reply id: {0}")]
UnrecognizedReply(u64),

#[error("Invalid reply from sub-message {id}, {err}")]
Expand All @@ -27,4 +27,7 @@ pub enum ContractError {

#[error("Provided amount of {0} is below required amount of {1}")]
InsufficientFundsProvided(FPDecimal, FPDecimal),

#[error("Contract can't be migrated")]
MigrationError {},
}
27 changes: 25 additions & 2 deletions contracts/swap/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use cosmwasm_std::{CosmosMsg, SubMsg};
use cosmwasm_std::{CosmosMsg, DepsMut, Response, SubMsg};

use injective_cosmwasm::InjectiveMsgWrapper;
use cw_storage_plus::Item;
use injective_cosmwasm::{InjectiveMsgWrapper, InjectiveQueryWrapper};
use injective_math::FPDecimal;

use crate::{state::CONFIG, types::Config, ContractError};

pub fn i32_to_dec(source: i32) -> FPDecimal {
FPDecimal::from(i128::from(source))
}
Expand Down Expand Up @@ -49,6 +52,26 @@ pub fn dec_scale_factor() -> FPDecimal {
FPDecimal::ONE.scaled(18)
}

type V100Config = Config;
const V100CONFIG: Item<V100Config> = Item::new("config");

pub fn handle_config_migration(
deps: DepsMut<InjectiveQueryWrapper>,
) -> Result<Response, ContractError> {
let v100_config = V100CONFIG.load(deps.storage)?;

let config = Config {
fee_recipient: v100_config.fee_recipient,
admin: v100_config.admin,
};

CONFIG.save(deps.storage, &config)?;

config.validate()?;

Ok(Response::default())
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
3 changes: 3 additions & 0 deletions contracts/swap/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ pub struct InstantiateMsg {
pub admin: Addr,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct MigrateMsg {}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
Expand Down
6 changes: 6 additions & 0 deletions contracts/swap/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ pub const STEP_STATE: Item<CurrentSwapStep> = Item::new("current_step_cache");
pub const SWAP_RESULTS: Item<Vec<SwapResults>> = Item::new("swap_results");
pub const CONFIG: Item<Config> = Item::new("config");

impl Config {
pub fn validate(self) -> StdResult<()> {
Ok(())
}
}

pub fn store_swap_route(storage: &mut dyn Storage, route: &SwapRoute) -> StdResult<()> {
let key = route_key(&route.source_denom, &route.target_denom);
SWAP_ROUTES.save(storage, key, route)
Expand Down

0 comments on commit 61a2c07

Please sign in to comment.