Skip to content

Commit

Permalink
Heartbeat feature (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadoySV authored Aug 18, 2023
1 parent f9f4def commit e0cc213
Show file tree
Hide file tree
Showing 19 changed files with 548 additions and 92 deletions.
40 changes: 36 additions & 4 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion contracts/controller/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ibc-controller"
version = "0.3.0"
version = "1.0.0"
authors = ["Astroport"]
license = "Apache-2.0"
description = "IBC controller contract intended to be hosted on the main chain."
Expand Down
56 changes: 30 additions & 26 deletions contracts/controller/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@ use astroport_ibc::TIMEOUT_LIMITS;
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, IbcMsg, IbcTimeout, MessageInfo, Response,
StdError,
attr, to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, IbcMsg, IbcTimeout, MessageInfo,
Response, StdError, SubMsg,
};
use cw2::{get_contract_version, set_contract_version};
use ibc_controller_package::astroport_governance::assembly::ProposalStatus;

use astro_satellite_package::SatelliteMsg;
use ibc_controller_package::astroport_governance::astroport::common::{
claim_ownership, drop_ownership_proposal, propose_new_owner,
};
use ibc_controller_package::{ExecuteMsg, IbcProposal, InstantiateMsg};
use ibc_controller_package::{MigrateMsg, QueryMsg};
use ibc_controller_package::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};

use crate::error::ContractError;
use crate::migration::migrate_config;
use crate::state::{Config, CONFIG, LAST_ERROR, OWNERSHIP_PROPOSAL, PROPOSAL_STATE};

const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
Expand Down Expand Up @@ -69,7 +68,7 @@ pub fn execute(

let ibc_msg = CosmosMsg::Ibc(IbcMsg::SendPacket {
channel_id: channel_id.clone(),
data: to_binary(&IbcProposal {
data: to_binary(&SatelliteMsg::ExecuteProposal {
id: proposal_id,
messages,
})?,
Expand Down Expand Up @@ -124,6 +123,21 @@ pub fn execute(
})
.map_err(Into::into)
}
ExecuteMsg::SendHeartbeat { channels } => {
let mut res = Response::new().add_attribute("action", "send_heartbeat");

for channel in channels {
let ibc_msg = CosmosMsg::Ibc(IbcMsg::SendPacket {
channel_id: channel.clone(),
data: to_binary(&SatelliteMsg::Heartbeat {})?,
timeout: IbcTimeout::from(env.block.time.plus_seconds(config.timeout)),
});
res.messages.push(SubMsg::new(ibc_msg));
res.attributes.push(attr("channel", channel));
}

Ok(res)
}
}
}

Expand All @@ -139,26 +153,12 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result<Binary, ContractErr
}

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

match contract_version.contract.as_ref() {
"ibc-controller" => match contract_version.version.as_ref() {
"0.1.0" => migrate_config(&mut deps)?,
"0.2.0" => {
let new_timeout = msg
.new_timeout
.ok_or_else(|| StdError::generic_err("Missing new_timeout field"))?;

if !TIMEOUT_LIMITS.contains(&new_timeout) {
return Err(ContractError::TimeoutLimitsError {});
}

CONFIG.update::<_, StdError>(deps.storage, |mut config| {
config.timeout = new_timeout;
Ok(config)
})?;
}
"0.3.0" => {}
_ => return Err(ContractError::MigrationError {}),
},
_ => return Err(ContractError::MigrationError {}),
Expand Down Expand Up @@ -210,10 +210,14 @@ mod tests {
timeout,
data,
}) if channel_id == channel_id && timeout == &real_timeout => {
let proposal: IbcProposal = from_binary(&data).unwrap();
assert_eq!(proposal.id, proposal_id);
assert_eq!(proposal.messages.len(), 1);
assert_eq!(proposal.messages[0], proposal_msg);
let msg: SatelliteMsg = from_binary(&data).unwrap();
assert_eq!(
msg,
SatelliteMsg::ExecuteProposal {
id: proposal_id,
messages: vec![proposal_msg]
}
);
}
_ => panic!("Unexpected message"),
}
Expand Down
1 change: 0 additions & 1 deletion contracts/controller/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
pub mod contract;
mod error;
pub mod ibc;
mod migration;
pub mod state;
#[cfg(test)]
mod test_utils;
23 changes: 0 additions & 23 deletions contracts/controller/src/migration.rs

This file was deleted.

4 changes: 2 additions & 2 deletions contracts/satellite/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "astro-satellite"
version = "0.2.0"
version = "1.0.0"
authors = ["Astroport"]
license = "Apache-2.0"
description = "IBC enabled astroport satellite contract intended to be hosted on a remote chain."
Expand Down Expand Up @@ -31,4 +31,4 @@ itertools = "0.10"
cosmwasm-schema = "1.1"

[dev-dependencies]
cw-multi-test = "0.15"
astroport-mocks = { path = "../../packages/astroport_mocks" }
62 changes: 48 additions & 14 deletions contracts/satellite/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use cosmwasm_std::entry_point;
use cosmwasm_std::{
to_binary, wasm_execute, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, IbcMsg, IbcTimeout,
MessageInfo, Reply, Response, StdError,
MessageInfo, Reply, Response, StdError, WasmMsg,
};
use cw2::{get_contract_version, set_contract_version};
use cw_utils::must_pay;
Expand All @@ -11,10 +11,13 @@ use astro_satellite_package::astroport_governance::astroport::common::{
claim_ownership, drop_ownership_proposal, propose_new_owner,
};
use astro_satellite_package::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
use astroport_ibc::TIMEOUT_LIMITS;
use astroport_ibc::{SIGNAL_OUTAGE_LIMITS, TIMEOUT_LIMITS};

use crate::error::ContractError;
use crate::state::{store_proposal, Config, CONFIG, OWNERSHIP_PROPOSAL, REPLY_DATA, RESULTS};
use crate::migration::migrate_to_v100;
use crate::state::{
store_proposal, Config, CONFIG, LATEST_HUB_SIGNAL_TIME, OWNERSHIP_PROPOSAL, REPLY_DATA, RESULTS,
};

const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
Expand All @@ -24,7 +27,7 @@ pub(crate) const RECEIVE_ID: u64 = 1;
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
deps: DepsMut,
_env: Env,
env: Env,
_info: MessageInfo,
msg: InstantiateMsg,
) -> Result<Response, ContractError> {
Expand All @@ -34,6 +37,10 @@ pub fn instantiate(
return Err(ContractError::TimeoutLimitsError {});
}

if !SIGNAL_OUTAGE_LIMITS.contains(&msg.max_signal_outage) {
return Err(ContractError::SignalOutageLimitsError {});
}

CONFIG.save(
deps.storage,
&Config {
Expand All @@ -44,9 +51,13 @@ pub fn instantiate(
gov_channel: None,
transfer_channel: msg.transfer_channel,
timeout: msg.timeout,
max_signal_outage: msg.max_signal_outage,
emergency_owner: deps.api.addr_validate(&msg.emergency_owner)?,
},
)?;

LATEST_HUB_SIGNAL_TIME.save(deps.storage, &env.block.time)?;

Ok(Response::new())
}

Expand Down Expand Up @@ -87,14 +98,19 @@ pub fn execute(
.add_attribute("action", "transfer_astro"))
}
ExecuteMsg::UpdateConfig(params) => {
CONFIG.update(deps.storage, |mut config| {
if config.owner == info.sender {
config.update(params)?;
Ok(config)
} else {
Err(ContractError::Unauthorized {})
}
})?;
let mut config = CONFIG.load(deps.storage)?;
if !(info.sender == config.owner
|| LATEST_HUB_SIGNAL_TIME
.load(deps.storage)?
.plus_seconds(config.max_signal_outage)
< env.block.time
&& info.sender == config.emergency_owner)
{
return Err(ContractError::Unauthorized {});
}
config.update(deps.api, params)?;
CONFIG.save(deps.storage, &config)?;

Ok(Response::new().add_attribute("action", "update_config"))
}
ExecuteMsg::CheckMessages(proposal_messages) => check_messages(env, proposal_messages),
Expand Down Expand Up @@ -130,6 +146,22 @@ pub fn execute(
})
.map_err(Into::into)
}
ExecuteMsg::SetEmergencyOwnerAsAdmin {} => {
let config = CONFIG.load(deps.storage)?;
if LATEST_HUB_SIGNAL_TIME
.load(deps.storage)?
.plus_seconds(config.max_signal_outage)
< env.block.time
&& info.sender == config.emergency_owner
{
Ok(Response::new().add_message(WasmMsg::UpdateAdmin {
contract_addr: env.contract.address.to_string(),
admin: config.emergency_owner.to_string(),
}))
} else {
Err(ContractError::Unauthorized {})
}
}
}
}

Expand All @@ -156,12 +188,14 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result<Binary, ContractErr
}

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

match contract_version.contract.as_ref() {
"astro-satellite" => match contract_version.version.as_ref() {
"0.1.0" => {}
"0.2.0" => {
migrate_to_v100(deps.branch(), &env, &msg)?;
}
_ => return Err(ContractError::MigrationError {}),
},
_ => return Err(ContractError::MigrationError {}),
Expand Down
8 changes: 7 additions & 1 deletion contracts/satellite/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use astroport_ibc::TIMEOUT_LIMITS;
use astroport_ibc::{SIGNAL_OUTAGE_LIMITS, TIMEOUT_LIMITS};
use cosmwasm_std::StdError;
use cw_utils::PaymentError;
use thiserror::Error;
Expand Down Expand Up @@ -48,4 +48,10 @@ pub enum ContractError {
TIMEOUT_LIMITS.end()
)]
TimeoutLimitsError {},
#[error(
"Signal outage must be within limits ({0} <= outage <= {1})",
SIGNAL_OUTAGE_LIMITS.start(),
SIGNAL_OUTAGE_LIMITS.end()
)]
SignalOutageLimitsError {},
}
Loading

0 comments on commit e0cc213

Please sign in to comment.