astroport_emissions_controller/
sudo.rs

1#[cfg(not(feature = "library"))]
2use cosmwasm_std::entry_point;
3use cosmwasm_std::{ensure, DepsMut, Env, Response, StdError, StdResult, Storage};
4use neutron_sdk::sudo::msg::{RequestPacket, TransferSudoMsg};
5
6use astroport_governance::emissions_controller::hub::OutpostStatus;
7
8use crate::state::TUNE_INFO;
9use crate::utils::get_outpost_from_hub_channel;
10
11#[cfg_attr(not(feature = "library"), entry_point)]
12pub fn sudo(deps: DepsMut, env: Env, msg: TransferSudoMsg) -> StdResult<Response> {
13    match msg {
14        TransferSudoMsg::Response { request, .. } => {
15            process_ibc_reply(deps.storage, env, request, false)
16        }
17        TransferSudoMsg::Error { request, .. } | TransferSudoMsg::Timeout { request } => {
18            process_ibc_reply(deps.storage, env, request, true)
19        }
20    }
21}
22
23/// Process outcome of an ics20 IBC packet with IBC hook.
24/// If a packet was successful, it marks the outpost as done.
25/// If a packet failed or timed out, it marks the outpost as failed, so it can be retried.
26pub fn process_ibc_reply(
27    storage: &mut dyn Storage,
28    env: Env,
29    packet: RequestPacket,
30    failed: bool,
31) -> StdResult<Response> {
32    let source_channel = packet
33        .source_channel
34        .ok_or_else(|| StdError::generic_err("Missing source_channel in IBC ack packet"))?;
35    let outpost =
36        get_outpost_from_hub_channel(storage, source_channel, |params| &params.ics20_channel)?;
37
38    let mut tune_info = TUNE_INFO.load(storage)?;
39    tune_info
40        .outpost_emissions_statuses
41        .get_mut(&outpost)
42        .ok_or_else(|| StdError::generic_err("Outpost status for {outpost} not found"))
43        .and_then(|status| {
44            ensure!(
45                *status == OutpostStatus::InProgress,
46                StdError::generic_err(format!("Outpost {outpost} is not in progress"))
47            );
48            *status = if failed {
49                OutpostStatus::Failed
50            } else {
51                OutpostStatus::Done
52            };
53            Ok(())
54        })?;
55    TUNE_INFO.save(storage, &tune_info, env.block.time.seconds())?;
56
57    let mut attrs = if failed {
58        vec![("action", "ibc_failed")]
59    } else {
60        vec![("action", "ibc_transfer_ack")]
61    };
62    attrs.push(("outpost", &outpost));
63
64    Ok(Response::default().add_attributes(attrs))
65}