use cosmrs::cosmwasm::MsgExecuteContract;
use cosmrs::tx::Msg;
use cosmwasm_std::Decimal256;
use serde::Serialize;
use crate::oracle::client::OracleAdminClient;
use crate::oracle::error::OracleError;
use crate::tx_builder::TxBuilder;
impl OracleAdminClient {
pub fn append_update_config_msg(
&self,
tx_builder: &mut TxBuilder,
price_threshold_ratio: Option<Decimal256>,
price_expire_millis: Option<u64>,
) -> Result<(), OracleError> {
let update_config = UpdateConfig {
price_threshold_ratio,
price_expire_millis,
};
let contract_msg = ExecuteMsg { update_config };
let contract_msg =
serde_json::to_vec(&contract_msg).map_err(OracleError::SerdeJsonError)?;
let msg = MsgExecuteContract {
sender: tx_builder.account_id.clone(),
contract: self.chain_config.oracle_contract_address.clone(),
msg: contract_msg,
funds: vec![],
};
let msg = msg.to_any().map_err(OracleError::EyreError)?;
tx_builder.add_msg(msg);
Ok(())
}
}
#[derive(Serialize)]
pub struct UpdateConfig {
pub price_threshold_ratio: Option<Decimal256>,
pub price_expire_millis: Option<u64>,
}
#[derive(Serialize)]
struct ExecuteMsg {
pub update_config: UpdateConfig,
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use cosmrs::tendermint::abci::Code;
use serial_test::serial;
use super::*;
use crate::test_utils::helpers::assert_event_attribute;
use crate::test_utils::test_scenario::TestScenario;
#[tokio::test]
#[serial]
async fn test_update_config() {
let test_scenario = TestScenario::new_from_config("config.json".to_string()).await;
let price_threshold_ratio = Decimal256::from_str("0.5").unwrap();
let price_expire_millis = Some(1000);
let oracle_contract_address = test_scenario
.instantiate_oracle_contract(price_threshold_ratio, price_expire_millis)
.await;
let client = OracleAdminClient::from_scenario(&test_scenario, &oracle_contract_address)
.expect("Failed to create oracle admin client");
let account = client
.public_oracle_client
.account(test_scenario.admin_address.clone())
.await
.expect("Failed to get account from public oracle client");
let mut tx_builder = TxBuilder::new(
test_scenario.admin_mnemonic.clone(),
test_scenario.chain_prefix.clone(),
test_scenario.chain_id.clone(),
test_scenario.derivation_path,
account.sequence,
account.account_number,
)
.expect("Failed to create tx builder");
let price_threshold_ratio = Decimal256::one();
let price_expire_millis = 42;
client
.append_update_config_msg(
&mut tx_builder,
Some(price_threshold_ratio),
Some(price_expire_millis),
)
.unwrap();
tx_builder.set_memo("From test_update_config".to_string());
let gas = 500_000u64;
tx_builder.set_fee(70_000_000_000_000_000u128, &test_scenario.chain_denom, gas);
let signed_bytes = tx_builder
.get_signed_bytes()
.expect("Failed to get signed bytes");
let response = client
.broadcast_tx(signed_bytes)
.await
.expect("Failed to broadcast tx");
match response.tx_result.code {
Code::Ok => {
println!("Transaction successful: {:?}", response.hash);
let update_config_event = response
.tx_result
.events
.iter()
.find(|ev| ev.kind == "wasm-update_config")
.expect("Failed to find update config event");
assert_event_attribute(
update_config_event,
"price_expire_millis",
&price_expire_millis.to_string(),
);
assert_event_attribute(
update_config_event,
"price_threshold_ratio",
&price_threshold_ratio.to_string(),
);
}
Code::Err(code) => {
panic!(
"Transaction failed with code: {:?} response: {:?}",
code, response
);
}
}
}
}