From 31a2e51400852b903eb9e6a6f28d20e7818fd2ca Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Fri, 6 Dec 2024 12:35:35 +1100 Subject: [PATCH 01/10] init --- Cargo.lock | 3 +- contracts/babylon/benches/main.rs | 4 - contracts/babylon/src/contract.rs | 119 ++---------------- contracts/babylon/src/ibc.rs | 15 +-- contracts/babylon/src/lib.rs | 5 - contracts/babylon/src/msg/contract.rs | 31 ----- contracts/babylon/src/multitest.rs | 23 +--- contracts/babylon/src/multitest/suite.rs | 69 +++++++--- .../babylon/src/state/btc_light_client.rs | 2 - contracts/babylon/src/state/config.rs | 4 - contracts/babylon/tests/integration.rs | 8 -- packages/bindings/Cargo.toml | 1 + packages/bindings/src/babylon_sdk.rs | 47 +++++++ packages/bindings/src/lib.rs | 1 + 14 files changed, 124 insertions(+), 208 deletions(-) create mode 100644 packages/bindings/src/babylon_sdk.rs diff --git a/Cargo.lock b/Cargo.lock index bc7d2fab..7d7afa4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -237,6 +237,7 @@ dependencies = [ name = "babylon-bindings" version = "0.4.0" dependencies = [ + "anybuf", "cosmwasm-schema", "cosmwasm-std", ] diff --git a/contracts/babylon/benches/main.rs b/contracts/babylon/benches/main.rs index 644b2f36..2b313115 100644 --- a/contracts/babylon/benches/main.rs +++ b/contracts/babylon/benches/main.rs @@ -49,10 +49,6 @@ pub fn setup_instance() -> Instance { btc_confirmation_depth: 10, checkpoint_finalization_timeout: 1, notify_cosmos_zone: false, - btc_staking_code_id: None, - btc_staking_msg: None, - btc_finality_code_id: None, - btc_finality_msg: None, admin: None, }; let info = mock_info(CREATOR, &[]); diff --git a/contracts/babylon/src/contract.rs b/contracts/babylon/src/contract.rs index 38b82683..78f61923 100644 --- a/contracts/babylon/src/contract.rs +++ b/contracts/babylon/src/contract.rs @@ -1,3 +1,4 @@ +use babylon_bindings::babylon_sdk::{QueryParamsResponse, QUERY_PARAMS_PATH}; use cosmwasm_std::{ to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, QueryResponse, Reply, Response, SubMsg, SubMsgResponse, WasmMsg, @@ -40,56 +41,15 @@ pub fn instantiate( btc_confirmation_depth: msg.btc_confirmation_depth, checkpoint_finalization_timeout: msg.checkpoint_finalization_timeout, notify_cosmos_zone: msg.notify_cosmos_zone, - btc_staking: None, // Will be set in `reply` if `btc_staking_code_id` is provided - btc_finality: None, // Will be set in `reply` if `btc_finality_code_id` is provided consumer_name: None, consumer_description: None, }; - let mut res = Response::new().add_attribute("action", "instantiate"); + let res = Response::new().add_attribute("action", "instantiate"); - if let Some(btc_staking_code_id) = msg.btc_staking_code_id { - // Update config with consumer information - cfg.consumer_name = msg.consumer_name; - cfg.consumer_description = msg.consumer_description; - - // Instantiate BTC staking contract - let init_msg = WasmMsg::Instantiate { - admin: msg.admin.clone(), - code_id: btc_staking_code_id, - msg: msg.btc_staking_msg.unwrap_or(Binary::from(b"{}")), - funds: vec![], - label: "BTC Staking".into(), - }; - let init_msg = SubMsg::reply_on_success(init_msg, REPLY_ID_INSTANTIATE_STAKING); - - // Test code sets a channel, so that we can better approximate IBC in test code - #[cfg(any(test, all(feature = "library", not(target_arch = "wasm32"))))] - { - let channel = cosmwasm_std::testing::mock_ibc_channel( - "channel-123", - cosmwasm_std::IbcOrder::Ordered, - "babylon", - ); - IBC_CHANNEL.save(deps.storage, &channel)?; - } - - res = res.add_submessage(init_msg); - } - - if let Some(btc_finality_code_id) = msg.btc_finality_code_id { - // Instantiate BTC finality contract - let init_msg = WasmMsg::Instantiate { - admin: msg.admin, - code_id: btc_finality_code_id, - msg: msg.btc_finality_msg.unwrap_or(Binary::from(b"{}")), - funds: vec![], - label: "BTC Finality".into(), - }; - let init_msg = SubMsg::reply_on_success(init_msg, REPLY_ID_INSTANTIATE_FINALITY); - - res = res.add_submessage(init_msg); - } + // Update config with consumer information + cfg.consumer_name = msg.consumer_name; + cfg.consumer_description = msg.consumer_description; // Save the config after potentially updating it CONFIG.save(deps.storage, &cfg)?; @@ -98,18 +58,6 @@ pub fn instantiate( Ok(res) } -pub fn reply( - deps: DepsMut, - _env: Env, - reply: Reply, -) -> Result, ContractError> { - match reply.id { - REPLY_ID_INSTANTIATE_STAKING => reply_init_callback_staking(deps, reply.result.unwrap()), - REPLY_ID_INSTANTIATE_FINALITY => reply_init_finality_callback(deps, reply.result.unwrap()), - _ => Err(ContractError::InvalidReplyId(reply.id)), - } -} - /// Tries to get contract address from events in reply fn reply_init_get_contract_address(reply: SubMsgResponse) -> Result { for event in reply.events { @@ -126,47 +74,6 @@ fn reply_init_get_contract_address(reply: SubMsgResponse) -> Result Result, ContractError> { - // Try to get contract address from events in reply - let addr = reply_init_get_contract_address(reply)?; - CONFIG.update(deps.storage, |mut cfg| { - cfg.btc_staking = Some(addr); - Ok::<_, ContractError>(cfg) - })?; - Ok(Response::new()) -} - -/// Store BTC finality address -fn reply_init_finality_callback( - deps: DepsMut, - reply: SubMsgResponse, -) -> Result, ContractError> { - // Try to get contract address from events in reply - let finality_addr = reply_init_get_contract_address(reply)?; - CONFIG.update(deps.storage, |mut cfg| { - cfg.btc_finality = Some(finality_addr.clone()); - Ok::<_, ContractError>(cfg) - })?; - // Set the BTC staking contract address to the BTC finality contract - let cfg = CONFIG.load(deps.storage)?; - let msg = finality_api::ExecuteMsg::UpdateStaking { - staking: cfg - .btc_staking - .ok_or(ContractError::BtcStakingNotSet {})? - .to_string(), - }; - let wasm_msg = WasmMsg::Execute { - contract_addr: finality_addr.to_string(), - msg: to_json_binary(&msg)?, - funds: vec![], - }; - Ok(Response::new().add_message(wasm_msg)) -} - pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { QueryMsg::Config {} => Ok(to_json_binary(&queries::config(deps)?)?), @@ -228,18 +135,18 @@ pub fn execute( Ok(Response::new()) } ExecuteMsg::Slashing { evidence } => { - // This is an internal routing message from the `btc_finality` contract - let cfg = CONFIG.load(deps.storage)?; // Check sender - let btc_finality = cfg - .btc_finality - .ok_or(ContractError::BtcFinalityNotSet {})?; + let params = deps + .querier + .query_grpc(QUERY_PARAMS_PATH.to_owned(), Binary::new("".into()))?; + let params = QueryParamsResponse::from(params).params; + let btc_finality = params.btc_finality_contract_address; if info.sender != btc_finality { return Err(ContractError::Unauthorized {}); } // Send to the staking contract for processing let mut res = Response::new(); - let btc_staking = cfg.btc_staking.ok_or(ContractError::BtcStakingNotSet {})?; + let btc_staking = params.btc_staking_contract_address; // Slashes this finality provider, i.e., sets its slashing height to the block height // and its power to zero let msg = btc_staking_api::ExecuteMsg::Slash { @@ -298,10 +205,6 @@ mod tests { btc_confirmation_depth: 10, checkpoint_finalization_timeout: 100, notify_cosmos_zone: false, - btc_staking_code_id: None, - btc_staking_msg: None, - btc_finality_code_id: None, - btc_finality_msg: None, admin: None, consumer_name: None, consumer_description: None, diff --git a/contracts/babylon/src/ibc.rs b/contracts/babylon/src/ibc.rs index 3a780feb..666a6fa2 100644 --- a/contracts/babylon/src/ibc.rs +++ b/contracts/babylon/src/ibc.rs @@ -162,6 +162,7 @@ pub(crate) mod ibc_packet { ActiveBtcDelegation, NewFinalityProvider, UnbondedBtcDelegation, }; use babylon_apis::finality_api::Evidence; + use babylon_bindings::babylon_sdk::{QueryParamsResponse, QUERY_PARAMS_PATH}; use babylon_proto::babylon::btcstaking::v1::BtcStakingIbcPacket; use babylon_proto::babylon::zoneconcierge::v1::zoneconcierge_packet_data::Packet::ConsumerSlashing; use babylon_proto::babylon::zoneconcierge::v1::ConsumerSlashingIbcPacket; @@ -201,13 +202,13 @@ pub(crate) mod ibc_packet { _caller: String, btc_staking: &BtcStakingIbcPacket, ) -> StdResult> { - let storage = deps.storage; - let cfg = CONFIG.load(storage)?; + let params = deps + .querier + .query_grpc(QUERY_PARAMS_PATH.to_owned(), Binary::new("".into()))?; + let params = QueryParamsResponse::from(params).params; // Route the packet to the btc-staking contract - let btc_staking_addr = cfg - .btc_staking - .ok_or(StdError::generic_err("btc_staking contract not set"))?; + let btc_staking_addr = params.btc_staking_contract_address; // Build the message to send to the BTC staking contract let msg = babylon_apis::btc_staking_api::ExecuteMsg::BtcStaking { @@ -331,10 +332,6 @@ mod tests { btc_confirmation_depth: 10, checkpoint_finalization_timeout: 100, notify_cosmos_zone: false, - btc_staking_code_id: None, - btc_staking_msg: None, - btc_finality_code_id: None, - btc_finality_msg: None, admin: None, consumer_name: None, consumer_description: None, diff --git a/contracts/babylon/src/lib.rs b/contracts/babylon/src/lib.rs index dd7414f3..18733424 100644 --- a/contracts/babylon/src/lib.rs +++ b/contracts/babylon/src/lib.rs @@ -33,11 +33,6 @@ pub fn instantiate( contract::instantiate(deps, env, info, msg) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(deps: DepsMut, env: Env, reply: Reply) -> Result, ContractError> { - contract::reply(deps, env, reply) -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: msg::contract::QueryMsg) -> Result { contract::query(deps, env, msg) diff --git a/contracts/babylon/src/msg/contract.rs b/contracts/babylon/src/msg/contract.rs index b094f0c8..70e74d8c 100644 --- a/contracts/babylon/src/msg/contract.rs +++ b/contracts/babylon/src/msg/contract.rs @@ -33,18 +33,6 @@ pub struct InstantiateMsg { /// NOTE: If set to true, then the Cosmos zone needs to integrate the corresponding message handler /// as well pub notify_cosmos_zone: bool, - /// If set, this will instantiate a BTC staking contract for BTC re-staking - pub btc_staking_code_id: Option, - /// If set, this will define the instantiation message for the BTC staking contract. - /// This message is opaque to the Babylon contract, and depends on the specific staking contract - /// being instantiated - pub btc_staking_msg: Option, - /// If set, this will instantiate a BTC finality contract - pub btc_finality_code_id: Option, - /// If set, this will define the instantiation message for the BTC finality contract. - /// This message is opaque to the Babylon contract, and depends on the specific finality contract - /// being instantiated - pub btc_finality_msg: Option, /// If set, this will be the Wasm migration / upgrade admin of the BTC staking contract and the /// BTC finality contract pub admin: Option, @@ -64,25 +52,6 @@ impl ContractMsg for InstantiateMsg { } let _ = self.babylon_tag_to_bytes()?; - if self.btc_staking_code_id.is_some() { - if let (Some(consumer_name), Some(consumer_description)) = - (&self.consumer_name, &self.consumer_description) - { - if consumer_name.trim().is_empty() { - return Err(StdError::generic_err("Consumer name cannot be empty")); - } - if consumer_description.trim().is_empty() { - return Err(StdError::generic_err( - "Consumer description cannot be empty", - )); - } - } else { - return Err(StdError::generic_err( - "Consumer name and description are required when btc_staking_code_id is set", - )); - } - } - Ok(()) } diff --git a/contracts/babylon/src/multitest.rs b/contracts/babylon/src/multitest.rs index 44fc23ee..5086ff6b 100644 --- a/contracts/babylon/src/multitest.rs +++ b/contracts/babylon/src/multitest.rs @@ -3,12 +3,6 @@ mod suite; use cosmwasm_std::Addr; use suite::SuiteBuilder; -// Some multi-test default settings -// TODO: Replace these with their address generators -const CONTRACT0_ADDR: &str = "cosmwasm19mfs8tl4s396u7vqw9rrnsmrrtca5r66p7v8jvwdxvjn3shcmllqupdgxu"; -const CONTRACT1_ADDR: &str = "cosmwasm14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s8jef58"; -const CONTRACT2_ADDR: &str = "cosmwasm1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrqt8utkp"; - #[test] fn initialization() { let suite = SuiteBuilder::new().build(); @@ -23,16 +17,8 @@ fn initialization() { assert_eq!(config.btc_confirmation_depth, 1); assert_eq!(config.checkpoint_finalization_timeout, 10); assert!(!config.notify_cosmos_zone); - assert_eq!(config.btc_staking, Some(Addr::unchecked(CONTRACT1_ADDR))); - assert_eq!(config.btc_finality, Some(Addr::unchecked(CONTRACT2_ADDR))); - - // Check that the btc-staking contract was initialized correctly - let btc_staking_config = suite.get_btc_staking_config(); - assert_eq!(btc_staking_config.babylon, Addr::unchecked(CONTRACT0_ADDR)); - - // Check that the btc-finality contract was initialized correctly - let btc_finality_config = suite.get_btc_finality_config(); - assert_eq!(btc_finality_config.babylon, Addr::unchecked(CONTRACT0_ADDR)); + assert!(!suite.btc_staking_contract.to_string().is_empty()); + assert!(!suite.btc_finality_contract.to_string().is_empty()); } mod instantiation { @@ -43,10 +29,9 @@ mod instantiation { let suite = SuiteBuilder::new().build(); // Confirm the btc-staking contract has been instantiated and set - let config = suite.get_config(); - assert_eq!(config.btc_staking, Some(Addr::unchecked(CONTRACT1_ADDR))); + assert!(!suite.btc_staking_contract.to_string().is_empty()); // Confirm the btc-finality contract has been instantiated and set - assert_eq!(config.btc_finality, Some(Addr::unchecked(CONTRACT2_ADDR))); + assert!(!suite.btc_finality_contract.to_string().is_empty()); } } diff --git a/contracts/babylon/src/multitest/suite.rs b/contracts/babylon/src/multitest/suite.rs index 0c9b9929..a0e90ae4 100644 --- a/contracts/babylon/src/multitest/suite.rs +++ b/contracts/babylon/src/multitest/suite.rs @@ -1,5 +1,4 @@ use crate::msg::contract::{InstantiateMsg, QueryMsg}; -use crate::multitest::{CONTRACT1_ADDR, CONTRACT2_ADDR}; use crate::state::config::Config; use anyhow::Result as AnyResult; use babylon_bindings::BabylonMsg; @@ -29,7 +28,6 @@ fn contract_btc_finality() -> Box> { fn contract_babylon() -> Box> { let contract = ContractWrapper::new(crate::execute, crate::instantiate, crate::query) - .with_reply(crate::reply) .with_migrate(crate::migrate); Box::new(contract) } @@ -61,12 +59,9 @@ impl SuiteBuilder { app.init_modules(|_router, _api, _storage| -> AnyResult<()> { Ok(()) }) .unwrap(); - let btc_staking_code_id = - app.store_code_with_creator(owner.clone(), contract_btc_staking()); - let btc_finality_code_id = - app.store_code_with_creator(owner.clone(), contract_btc_finality()); + // Store and instantiate the Babylon contract let contract_code_id = app.store_code_with_creator(owner.clone(), contract_babylon()); - let contract = app + let babylon_contract = app .instantiate_contract( contract_code_id, owner.clone(), @@ -76,10 +71,6 @@ impl SuiteBuilder { btc_confirmation_depth: 1, checkpoint_finalization_timeout: 10, notify_cosmos_zone: false, - btc_staking_code_id: Some(btc_staking_code_id), - btc_staking_msg: None, - btc_finality_code_id: Some(btc_finality_code_id), - btc_finality_msg: None, admin: Some(owner.to_string()), consumer_name: Some("TestConsumer".to_string()), consumer_description: Some("Test Consumer Description".to_string()), @@ -90,10 +81,44 @@ impl SuiteBuilder { ) .unwrap(); + let btc_staking_code_id = + app.store_code_with_creator(owner.clone(), contract_btc_staking()); + let btc_staking_contract = app + .instantiate_contract( + btc_staking_code_id, + owner.clone(), + &btc_staking::msg::InstantiateMsg { + admin: None, + params: None, + }, + &[], + "btc-staking", + Some(owner.to_string()), + ) + .unwrap(); + + let btc_finality_code_id = + app.store_code_with_creator(owner.clone(), contract_btc_finality()); + let btc_finality_contract = app + .instantiate_contract( + btc_finality_code_id, + owner.clone(), + &btc_finality::msg::InstantiateMsg { + admin: None, + params: None, + }, + &[], + "btc-finality", + Some(owner.to_string()), + ) + .unwrap(); + Suite { app, code_id: contract_code_id, - contract, + babylon_contract: babylon_contract, + btc_staking_contract: btc_staking_contract, + btc_finality_contract: btc_finality_contract, owner, } } @@ -107,7 +132,11 @@ pub struct Suite { /// The code id of the babylon contract code_id: u64, /// Babylon contract address - pub contract: Addr, + pub babylon_contract: Addr, + /// BTC staking contract address + pub btc_staking_contract: Addr, + /// BTC finality contract address + pub btc_finality_contract: Addr, /// Admin of babylon and btc-staking contracts pub owner: Addr, } @@ -121,7 +150,7 @@ impl Suite { pub fn get_config(&self) -> Config { self.app .wrap() - .query_wasm_smart(self.contract.clone(), &QueryMsg::Config {}) + .query_wasm_smart(self.babylon_contract.clone(), &QueryMsg::Config {}) .unwrap() } @@ -129,7 +158,10 @@ impl Suite { pub fn get_btc_staking_config(&self) -> btc_staking::state::config::Config { self.app .wrap() - .query_wasm_smart(CONTRACT1_ADDR, &btc_staking::msg::QueryMsg::Config {}) + .query_wasm_smart( + self.btc_staking_contract.clone(), + &btc_staking::msg::QueryMsg::Config {}, + ) .unwrap() } @@ -137,14 +169,17 @@ impl Suite { pub fn get_btc_finality_config(&self) -> btc_finality::state::config::Config { self.app .wrap() - .query_wasm_smart(CONTRACT2_ADDR, &btc_finality::msg::QueryMsg::Config {}) + .query_wasm_smart( + self.btc_finality_contract.clone(), + &btc_finality::msg::QueryMsg::Config {}, + ) .unwrap() } pub fn migrate(&mut self, addr: &str, msg: Empty) -> AnyResult { self.app.migrate_contract( Addr::unchecked(addr), - self.contract.clone(), + self.babylon_contract.clone(), &msg, self.code_id, ) diff --git a/contracts/babylon/src/state/btc_light_client.rs b/contracts/babylon/src/state/btc_light_client.rs index 98e0b661..f67c5793 100644 --- a/contracts/babylon/src/state/btc_light_client.rs +++ b/contracts/babylon/src/state/btc_light_client.rs @@ -356,8 +356,6 @@ pub(crate) mod tests { btc_confirmation_depth: 1, checkpoint_finalization_timeout: w, notify_cosmos_zone: false, - btc_staking: None, - btc_finality: None, consumer_name: None, consumer_description: None, }; diff --git a/contracts/babylon/src/state/config.rs b/contracts/babylon/src/state/config.rs index b1e25121..2bc50616 100644 --- a/contracts/babylon/src/state/config.rs +++ b/contracts/babylon/src/state/config.rs @@ -15,10 +15,6 @@ pub struct Config { /// NOTE: if set to true, then the Cosmos zone needs to integrate the corresponding message /// handler as well pub notify_cosmos_zone: bool, - /// If set, this stores a BTC staking contract used for BTC re-staking - pub btc_staking: Option, - /// If set, this stores a BTC finality contract used for BTC finality on the Consumer - pub btc_finality: Option, /// Consumer name pub consumer_name: Option, /// Consumer description diff --git a/contracts/babylon/tests/integration.rs b/contracts/babylon/tests/integration.rs index dbe78dde..57b53e97 100644 --- a/contracts/babylon/tests/integration.rs +++ b/contracts/babylon/tests/integration.rs @@ -47,10 +47,6 @@ fn setup() -> Instance { btc_confirmation_depth: 10, checkpoint_finalization_timeout: 99, notify_cosmos_zone: false, - btc_staking_code_id: None, - btc_staking_msg: None, - btc_finality_code_id: None, - btc_finality_msg: None, admin: None, }; let info = message_info(&Addr::unchecked(CREATOR), &[]); @@ -101,10 +97,6 @@ fn instantiate_works() { btc_confirmation_depth: 10, checkpoint_finalization_timeout: 100, notify_cosmos_zone: false, - btc_staking_code_id: None, - btc_staking_msg: None, - btc_finality_code_id: None, - btc_finality_msg: None, admin: None, }; let info = message_info(&Addr::unchecked(CREATOR), &[]); diff --git a/packages/bindings/Cargo.toml b/packages/bindings/Cargo.toml index 79cbb957..ffe285ea 100644 --- a/packages/bindings/Cargo.toml +++ b/packages/bindings/Cargo.toml @@ -9,5 +9,6 @@ homepage = "https://babylonlabs.io" license = "Apache-2.0" [dependencies] +anybuf = { workspace = true } cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } diff --git a/packages/bindings/src/babylon_sdk.rs b/packages/bindings/src/babylon_sdk.rs new file mode 100644 index 00000000..55c907bd --- /dev/null +++ b/packages/bindings/src/babylon_sdk.rs @@ -0,0 +1,47 @@ +use anybuf::Bufany; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Binary}; + +pub const QUERY_PARAMS_PATH: &str = "/babylonlabs/babylon/v1beta1/params"; + +#[cw_serde] +pub struct QueryParamsResponse { + pub params: Params, +} + +#[cw_serde] +pub struct Params { + /// babylon_contract_code_id is the code ID of the Babylon contract + pub babylon_contract_code_id: u64, + /// btc_staking_contract_code_id is the code ID of the BTC staking contract + pub btc_staking_contract_code_id: u64, + /// btc_finality_contract_code_id is the code ID of the BTC finality contract + pub btc_finality_contract_code_id: u64, + /// babylon_contract_address is the address of the Babylon contract + pub babylon_contract_address: Addr, + /// btc_staking_contract_address is the address of the BTC staking contract + pub btc_staking_contract_address: Addr, + /// btc_finality_contract_address is the address of the BTC finality contract + pub btc_finality_contract_address: Addr, + /// max_gas_begin_blocker defines the maximum gas that can be spent in a contract sudo callback + pub max_gas_begin_blocker: u32, +} + +impl From for QueryParamsResponse { + fn from(binary: Binary) -> Self { + let res_decoded = Bufany::deserialize(&binary).unwrap(); + // See https://github.com/babylonlabs-io/babylon/blob/base/consumer-chain-support/proto/babylon/btcstaking/v1/query.proto#L35 + let res_params = res_decoded.message(1).unwrap(); + QueryParamsResponse { + params: Params { + babylon_contract_code_id: res_params.uint64(1).unwrap(), + btc_staking_contract_code_id: res_params.uint64(2).unwrap(), + btc_finality_contract_code_id: res_params.uint64(3).unwrap(), + babylon_contract_address: Addr::unchecked(res_params.string(4).unwrap()), + btc_staking_contract_address: Addr::unchecked(res_params.string(5).unwrap()), + btc_finality_contract_address: Addr::unchecked(res_params.string(6).unwrap()), + max_gas_begin_blocker: res_params.uint32(7).unwrap(), + }, + } + } +} diff --git a/packages/bindings/src/lib.rs b/packages/bindings/src/lib.rs index cf7d55ac..66b3bcd1 100644 --- a/packages/bindings/src/lib.rs +++ b/packages/bindings/src/lib.rs @@ -1,3 +1,4 @@ +pub mod babylon_sdk; pub mod msg; pub use msg::{BabylonMsg, BabylonQuery, BabylonSudoMsg}; From 5426f9516fd5e02b5cb812995a77815a57a4950e Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Fri, 6 Dec 2024 14:47:58 +1100 Subject: [PATCH 02/10] minor --- contracts/babylon/src/contract.rs | 9 +++-- contracts/babylon/src/ibc.rs | 9 +++-- contracts/btc-finality/src/contract.rs | 28 +++++++++------ contracts/btc-finality/src/finality.rs | 35 ++++++++++++++----- contracts/btc-finality/src/multitest/suite.rs | 10 ------ contracts/btc-finality/src/state/config.rs | 2 -- packages/bindings/src/babylon_sdk.rs | 8 ++++- 7 files changed, 60 insertions(+), 41 deletions(-) diff --git a/contracts/babylon/src/contract.rs b/contracts/babylon/src/contract.rs index 78f61923..05e8db76 100644 --- a/contracts/babylon/src/contract.rs +++ b/contracts/babylon/src/contract.rs @@ -1,4 +1,6 @@ -use babylon_bindings::babylon_sdk::{QueryParamsResponse, QUERY_PARAMS_PATH}; +use babylon_bindings::babylon_sdk::{ + get_babylon_sdk_params, QueryParamsResponse, QUERY_PARAMS_PATH, +}; use cosmwasm_std::{ to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, QueryResponse, Reply, Response, SubMsg, SubMsgResponse, WasmMsg, @@ -136,10 +138,7 @@ pub fn execute( } ExecuteMsg::Slashing { evidence } => { // Check sender - let params = deps - .querier - .query_grpc(QUERY_PARAMS_PATH.to_owned(), Binary::new("".into()))?; - let params = QueryParamsResponse::from(params).params; + let params = get_babylon_sdk_params(&deps.querier)?; let btc_finality = params.btc_finality_contract_address; if info.sender != btc_finality { return Err(ContractError::Unauthorized {}); diff --git a/contracts/babylon/src/ibc.rs b/contracts/babylon/src/ibc.rs index 666a6fa2..752ac18f 100644 --- a/contracts/babylon/src/ibc.rs +++ b/contracts/babylon/src/ibc.rs @@ -162,7 +162,9 @@ pub(crate) mod ibc_packet { ActiveBtcDelegation, NewFinalityProvider, UnbondedBtcDelegation, }; use babylon_apis::finality_api::Evidence; - use babylon_bindings::babylon_sdk::{QueryParamsResponse, QUERY_PARAMS_PATH}; + use babylon_bindings::babylon_sdk::{ + get_babylon_sdk_params, QueryParamsResponse, QUERY_PARAMS_PATH, + }; use babylon_proto::babylon::btcstaking::v1::BtcStakingIbcPacket; use babylon_proto::babylon::zoneconcierge::v1::zoneconcierge_packet_data::Packet::ConsumerSlashing; use babylon_proto::babylon::zoneconcierge::v1::ConsumerSlashingIbcPacket; @@ -202,10 +204,7 @@ pub(crate) mod ibc_packet { _caller: String, btc_staking: &BtcStakingIbcPacket, ) -> StdResult> { - let params = deps - .querier - .query_grpc(QUERY_PARAMS_PATH.to_owned(), Binary::new("".into()))?; - let params = QueryParamsResponse::from(params).params; + let params = get_babylon_sdk_params(&deps.querier)?; // Route the packet to the btc-staking contract let btc_staking_addr = params.btc_staking_contract_address; diff --git a/contracts/btc-finality/src/contract.rs b/contracts/btc-finality/src/contract.rs index 045e7913..b46d4e9e 100644 --- a/contracts/btc-finality/src/contract.rs +++ b/contracts/btc-finality/src/contract.rs @@ -1,9 +1,12 @@ use babylon_apis::finality_api::SudoMsg; +use babylon_bindings::babylon_sdk::{ + get_babylon_sdk_params, QueryParamsResponse, QUERY_PARAMS_PATH, +}; use babylon_bindings::BabylonMsg; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, to_json_binary, Addr, CustomQuery, Deps, DepsMut, Empty, Env, MessageInfo, + attr, to_json_binary, Addr, Binary, CustomQuery, Deps, DepsMut, Empty, Env, MessageInfo, QuerierWrapper, QueryRequest, QueryResponse, Reply, Response, StdResult, WasmQuery, }; use cw2::set_contract_version; @@ -37,8 +40,6 @@ pub fn instantiate( let config = Config { denom, blocks_per_year, - babylon: info.sender, - staking: Addr::unchecked("UNSET"), // To be set later, through `UpdateStaking` }; CONFIG.save(deps.storage, &config)?; @@ -206,12 +207,17 @@ fn handle_update_staking( info: MessageInfo, staking_addr: String, ) -> Result, ContractError> { - let mut cfg = CONFIG.load(deps.storage)?; - if info.sender != cfg.babylon && !ADMIN.is_admin(deps.as_ref(), &info.sender)? { + let params = deps + .querier + .query_grpc(QUERY_PARAMS_PATH.to_owned(), Binary::new("".into()))?; + let params = QueryParamsResponse::from(params).params; + + // ensure the sender is the Babylon contract + if info.sender != params.babylon_contract_address + && !ADMIN.is_admin(deps.as_ref(), &info.sender)? + { return Err(ContractError::Unauthorized {}); } - cfg.staking = deps.api.addr_validate(&staking_addr)?; - CONFIG.save(deps.storage, &cfg)?; let attributes = vec![ attr("action", "update_btc_staking"), @@ -239,7 +245,7 @@ fn handle_end_block( // finality provider has voting power, start indexing and tallying blocks let cfg = CONFIG.load(deps.storage)?; let mut res = Response::new(); - let activated_height = get_activated_height(&cfg.staking, &deps.querier)?; + let activated_height = get_activated_height(&deps.querier)?; if activated_height > 0 { // Index the current block let ev = finality::index_block(deps, env.block.height, &hex::decode(app_hash_hex)?)?; @@ -254,10 +260,12 @@ fn handle_end_block( Ok(res) } -pub fn get_activated_height(staking_addr: &Addr, querier: &QuerierWrapper) -> StdResult { +pub fn get_activated_height(querier: &QuerierWrapper) -> StdResult { + let params = get_babylon_sdk_params(querier)?; + // TODO: Use a raw query let query = encode_smart_query( - staking_addr, + ¶ms.btc_staking_contract_address, &btc_staking::msg::QueryMsg::ActivatedHeight {}, )?; let res: ActivatedHeightResponse = querier.query(&query)?; diff --git a/contracts/btc-finality/src/finality.rs b/contracts/btc-finality/src/finality.rs index 13f6cce6..49207920 100644 --- a/contracts/btc-finality/src/finality.rs +++ b/contracts/btc-finality/src/finality.rs @@ -7,6 +7,7 @@ use crate::state::public_randomness::{ }; use babylon_apis::btc_staking_api::FinalityProvider; use babylon_apis::finality_api::{Evidence, IndexedBlock, PubRandCommit}; +use babylon_bindings::babylon_sdk::get_babylon_sdk_params; use babylon_bindings::BabylonMsg; use babylon_merkle::Proof; use btc_staking::msg::{FinalityProviderInfo, FinalityProvidersByPowerResponse}; @@ -37,12 +38,14 @@ pub fn handle_public_randomness_commit( } // TODO: ensure log_2(num_pub_rand) is an integer? + let params = get_babylon_sdk_params(&deps.querier)?; + // Ensure the finality provider is registered // TODO: Use a raw query for performance and cost let _fp: FinalityProvider = deps .querier .query_wasm_smart( - CONFIG.load(deps.storage)?.staking, + ¶ms.btc_staking_contract_address, &btc_staking::msg::QueryMsg::FinalityProvider { btc_pk_hex: fp_pubkey_hex.to_string(), }, @@ -132,10 +135,11 @@ pub fn handle_finality_signature( block_app_hash: &[u8], signature: &[u8], ) -> Result, ContractError> { + let params = get_babylon_sdk_params(&deps.querier)?; + // Ensure the finality provider exists - let staking_addr = CONFIG.load(deps.storage)?.staking; let fp: FinalityProvider = deps.querier.query_wasm_smart( - staking_addr.clone(), + ¶ms.btc_staking_contract_address, &btc_staking::msg::QueryMsg::FinalityProvider { btc_pk_hex: fp_btc_pk_hex.to_string(), }, @@ -169,7 +173,7 @@ pub fn handle_finality_signature( let fp: FinalityProviderInfo = deps .querier .query_wasm_smart( - staking_addr.clone(), + ¶ms.btc_staking_contract_address, &btc_staking::msg::QueryMsg::FinalityProviderInfo { btc_pk_hex: fp_btc_pk_hex.to_string(), height: Some(height), @@ -310,7 +314,8 @@ fn slash_finality_provider( evidence: evidence.clone(), }; - let babylon_addr = CONFIG.load(deps.storage)?.babylon; + let params = get_babylon_sdk_params(&deps.querier)?; + let babylon_addr = ¶ms.babylon_contract_address; let wasm_msg = WasmMsg::Execute { contract_addr: babylon_addr.to_string(), @@ -483,6 +488,8 @@ pub fn tally_blocks( } } + let params = get_babylon_sdk_params(&deps.querier)?; + // Compute block rewards for finalized blocks let msg = if finalized_blocks > 0 { let cfg = CONFIG.load(deps.storage)?; @@ -490,7 +497,7 @@ pub fn tally_blocks( // Assemble mint message let mint_msg = BabylonMsg::MintRewards { amount: rewards, - recipient: cfg.staking.into(), + recipient: params.btc_staking_contract_address.into(), }; Some(mint_msg) } else { @@ -571,9 +578,16 @@ pub fn compute_active_finality_providers( env: Env, max_active_fps: usize, ) -> Result<(), ContractError> { + let params = get_babylon_sdk_params(&deps.querier)?; + let cfg = CONFIG.load(deps.storage)?; // Get all finality providers from the staking contract, filtered - let mut batch = list_fps_by_power(&cfg.staking, &deps.querier, None, QUERY_LIMIT)?; + let mut batch = list_fps_by_power( + ¶ms.btc_staking_contract_address, + &deps.querier, + None, + QUERY_LIMIT, + )?; let mut finality_providers = vec![]; let mut total_power: u64 = 0; @@ -595,7 +609,12 @@ pub fn compute_active_finality_providers( total_power = running_total.last().copied().unwrap_or_default(); // and get the next page - batch = list_fps_by_power(&cfg.staking, &deps.querier, last, QUERY_LIMIT)?; + batch = list_fps_by_power( + ¶ms.btc_staking_contract_address, + &deps.querier, + last, + QUERY_LIMIT, + )?; } // TODO: Online FPs verification diff --git a/contracts/btc-finality/src/multitest/suite.rs b/contracts/btc-finality/src/multitest/suite.rs index ca0fcb30..811df0db 100644 --- a/contracts/btc-finality/src/multitest/suite.rs +++ b/contracts/btc-finality/src/multitest/suite.rs @@ -95,16 +95,6 @@ impl SuiteBuilder { btc_confirmation_depth: 1, checkpoint_finalization_timeout: 10, notify_cosmos_zone: false, - btc_staking_code_id: Some(btc_staking_code_id), - btc_staking_msg: Some( - to_json_binary(&btc_staking::msg::InstantiateMsg { - params: Some(staking_params), - admin: None, - }) - .unwrap(), - ), - btc_finality_code_id: Some(btc_finality_code_id), - btc_finality_msg: None, admin: Some(owner.to_string()), consumer_name: Some("TestConsumer".to_string()), consumer_description: Some("Test Consumer Description".to_string()), diff --git a/contracts/btc-finality/src/state/config.rs b/contracts/btc-finality/src/state/config.rs index 60a2f342..f46b55a4 100644 --- a/contracts/btc-finality/src/state/config.rs +++ b/contracts/btc-finality/src/state/config.rs @@ -17,8 +17,6 @@ pub(crate) const ADMIN: Admin = Admin::new("admin"); pub struct Config { pub denom: String, pub blocks_per_year: u64, - pub babylon: Addr, - pub staking: Addr, } // TODO: Add / enable param entries as needed diff --git a/packages/bindings/src/babylon_sdk.rs b/packages/bindings/src/babylon_sdk.rs index 55c907bd..9381ede4 100644 --- a/packages/bindings/src/babylon_sdk.rs +++ b/packages/bindings/src/babylon_sdk.rs @@ -1,6 +1,6 @@ use anybuf::Bufany; use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Binary}; +use cosmwasm_std::{Addr, Binary, QuerierWrapper, StdError, StdResult}; pub const QUERY_PARAMS_PATH: &str = "/babylonlabs/babylon/v1beta1/params"; @@ -45,3 +45,9 @@ impl From for QueryParamsResponse { } } } + +pub fn get_babylon_sdk_params(querier: &QuerierWrapper) -> Result { + let params = querier.query_grpc(QUERY_PARAMS_PATH.to_owned(), Binary::new("".into()))?; + let params = QueryParamsResponse::from(params).params; + Ok(params) +} From b2fe604bbbc14687a8c6bd9d77efc50ac3322636 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 7 Jan 2025 11:54:05 +1100 Subject: [PATCH 03/10] minor --- contracts/babylon/src/contract.rs | 8 -------- contracts/babylon/src/msg/contract.rs | 19 ------------------- contracts/babylon/src/multitest/suite.rs | 4 ---- contracts/btc-finality/src/contract.rs | 2 +- 4 files changed, 1 insertion(+), 32 deletions(-) diff --git a/contracts/babylon/src/contract.rs b/contracts/babylon/src/contract.rs index 183c85b7..fc1aedff 100644 --- a/contracts/babylon/src/contract.rs +++ b/contracts/babylon/src/contract.rs @@ -290,10 +290,6 @@ mod tests { btc_confirmation_depth: 10, checkpoint_finalization_timeout: 100, notify_cosmos_zone: false, - btc_staking_code_id: None, - btc_staking_msg: None, - btc_finality_code_id: Some(2), - btc_finality_msg: None, admin: None, consumer_name: None, consumer_description: None, @@ -326,10 +322,6 @@ mod tests { btc_confirmation_depth: 10, checkpoint_finalization_timeout: 100, notify_cosmos_zone: false, - btc_staking_code_id: None, - btc_staking_msg: None, - btc_finality_code_id: Some(2), - btc_finality_msg: Some(Binary::from(params.as_bytes())), admin: None, consumer_name: None, consumer_description: None, diff --git a/contracts/babylon/src/msg/contract.rs b/contracts/babylon/src/msg/contract.rs index 75b72a7b..b79c3122 100644 --- a/contracts/babylon/src/msg/contract.rs +++ b/contracts/babylon/src/msg/contract.rs @@ -56,25 +56,6 @@ impl ContractMsg for InstantiateMsg { } let _ = self.babylon_tag_to_bytes()?; - if self.btc_staking_code_id.is_some() { - if let (Some(consumer_name), Some(consumer_description)) = - (&self.consumer_name, &self.consumer_description) - { - if consumer_name.trim().is_empty() { - return Err(StdError::generic_err("Consumer name cannot be empty")); - } - if consumer_description.trim().is_empty() { - return Err(StdError::generic_err( - "Consumer description cannot be empty", - )); - } - } else { - return Err(StdError::generic_err( - "Consumer name and description are required when btc_staking_code_id is set", - )); - } - } - if let Some(transfer_info) = &self.transfer_info { transfer_info.validate()?; } diff --git a/contracts/babylon/src/multitest/suite.rs b/contracts/babylon/src/multitest/suite.rs index ba46ec00..1c029101 100644 --- a/contracts/babylon/src/multitest/suite.rs +++ b/contracts/babylon/src/multitest/suite.rs @@ -108,10 +108,6 @@ impl SuiteBuilder { btc_confirmation_depth: 1, checkpoint_finalization_timeout: 10, notify_cosmos_zone: false, - btc_staking_code_id: Some(btc_staking_code_id), - btc_staking_msg: staking_msg, - btc_finality_code_id: Some(btc_finality_code_id), - btc_finality_msg: finality_msg, admin: Some(owner.to_string()), consumer_name: Some("TestConsumer".to_string()), consumer_description: Some("Test Consumer Description".to_string()), diff --git a/contracts/btc-finality/src/contract.rs b/contracts/btc-finality/src/contract.rs index b07d63a3..37720891 100644 --- a/contracts/btc-finality/src/contract.rs +++ b/contracts/btc-finality/src/contract.rs @@ -318,7 +318,7 @@ fn send_rewards_msg( Ok(wasm_msg) } -pub fn get_activated_height(staking_addr: &Addr, querier: &QuerierWrapper) -> StdResult { +pub fn get_activated_height(querier: &QuerierWrapper) -> StdResult { // TODO: Use a raw query let query = encode_smart_query( ¶ms.btc_staking_contract_address, From 3b925f1a199e5a10f11b848e520ddcf2b85e8498 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 7 Jan 2025 15:04:56 +1100 Subject: [PATCH 04/10] query chain param --- packages/bindings/src/babylon_sdk.rs | 53 ---------------------------- packages/bindings/src/lib.rs | 4 +-- packages/bindings/src/msg.rs | 2 +- packages/bindings/src/query.rs | 47 ++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 56 deletions(-) delete mode 100644 packages/bindings/src/babylon_sdk.rs create mode 100644 packages/bindings/src/query.rs diff --git a/packages/bindings/src/babylon_sdk.rs b/packages/bindings/src/babylon_sdk.rs deleted file mode 100644 index 9381ede4..00000000 --- a/packages/bindings/src/babylon_sdk.rs +++ /dev/null @@ -1,53 +0,0 @@ -use anybuf::Bufany; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Binary, QuerierWrapper, StdError, StdResult}; - -pub const QUERY_PARAMS_PATH: &str = "/babylonlabs/babylon/v1beta1/params"; - -#[cw_serde] -pub struct QueryParamsResponse { - pub params: Params, -} - -#[cw_serde] -pub struct Params { - /// babylon_contract_code_id is the code ID of the Babylon contract - pub babylon_contract_code_id: u64, - /// btc_staking_contract_code_id is the code ID of the BTC staking contract - pub btc_staking_contract_code_id: u64, - /// btc_finality_contract_code_id is the code ID of the BTC finality contract - pub btc_finality_contract_code_id: u64, - /// babylon_contract_address is the address of the Babylon contract - pub babylon_contract_address: Addr, - /// btc_staking_contract_address is the address of the BTC staking contract - pub btc_staking_contract_address: Addr, - /// btc_finality_contract_address is the address of the BTC finality contract - pub btc_finality_contract_address: Addr, - /// max_gas_begin_blocker defines the maximum gas that can be spent in a contract sudo callback - pub max_gas_begin_blocker: u32, -} - -impl From for QueryParamsResponse { - fn from(binary: Binary) -> Self { - let res_decoded = Bufany::deserialize(&binary).unwrap(); - // See https://github.com/babylonlabs-io/babylon/blob/base/consumer-chain-support/proto/babylon/btcstaking/v1/query.proto#L35 - let res_params = res_decoded.message(1).unwrap(); - QueryParamsResponse { - params: Params { - babylon_contract_code_id: res_params.uint64(1).unwrap(), - btc_staking_contract_code_id: res_params.uint64(2).unwrap(), - btc_finality_contract_code_id: res_params.uint64(3).unwrap(), - babylon_contract_address: Addr::unchecked(res_params.string(4).unwrap()), - btc_staking_contract_address: Addr::unchecked(res_params.string(5).unwrap()), - btc_finality_contract_address: Addr::unchecked(res_params.string(6).unwrap()), - max_gas_begin_blocker: res_params.uint32(7).unwrap(), - }, - } - } -} - -pub fn get_babylon_sdk_params(querier: &QuerierWrapper) -> Result { - let params = querier.query_grpc(QUERY_PARAMS_PATH.to_owned(), Binary::new("".into()))?; - let params = QueryParamsResponse::from(params).params; - Ok(params) -} diff --git a/packages/bindings/src/lib.rs b/packages/bindings/src/lib.rs index 66b3bcd1..35b3591b 100644 --- a/packages/bindings/src/lib.rs +++ b/packages/bindings/src/lib.rs @@ -1,4 +1,4 @@ -pub mod babylon_sdk; pub mod msg; +pub mod query; -pub use msg::{BabylonMsg, BabylonQuery, BabylonSudoMsg}; +pub use msg::{BabylonMsg, BabylonSudoMsg}; diff --git a/packages/bindings/src/msg.rs b/packages/bindings/src/msg.rs index 3b3c8d39..5438d9ae 100644 --- a/packages/bindings/src/msg.rs +++ b/packages/bindings/src/msg.rs @@ -52,8 +52,8 @@ pub enum BabylonMsg { } pub type BabylonSudoMsg = Empty; -pub type BabylonQuery = Empty; +// make BabylonMsg to implement CosmosMsg::CustomMsg // make BabylonMsg to implement CosmosMsg::CustomMsg impl cosmwasm_std::CustomMsg for BabylonMsg {} diff --git a/packages/bindings/src/query.rs b/packages/bindings/src/query.rs new file mode 100644 index 00000000..03c0ba7d --- /dev/null +++ b/packages/bindings/src/query.rs @@ -0,0 +1,47 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::{ + from_json, to_json_binary, Addr, ContractResult, QuerierWrapper, StdError, SystemResult, +}; + +#[cw_serde] +#[derive(QueryResponses)] +pub enum BabylonQuery { + #[returns(ParamsResponse)] + Params {}, +} + +#[cw_serde] +pub struct ParamsResponse { + /// babylon_contract_code_id is the code ID of the Babylon contract + pub babylon_contract_code_id: u64, + /// btc_staking_contract_code_id is the code ID of the BTC staking contract + pub btc_staking_contract_code_id: u64, + /// btc_finality_contract_code_id is the code ID of the BTC finality contract + pub btc_finality_contract_code_id: u64, + /// babylon_contract_address is the address of the Babylon contract + pub babylon_contract_address: Addr, + /// btc_staking_contract_address is the address of the BTC staking contract + pub btc_staking_contract_address: Addr, + /// btc_finality_contract_address is the address of the BTC finality contract + pub btc_finality_contract_address: Addr, + /// max_gas_begin_blocker defines the maximum gas that can be spent in a contract sudo callback + pub max_gas_begin_blocker: u32, +} + +pub fn get_babylon_sdk_params(querier: &QuerierWrapper) -> Result { + let query = BabylonQuery::Params {}; + let res = match querier.raw_query(&to_json_binary(&query)?) { + SystemResult::Err(system_err) => Err(StdError::generic_err(format!( + "Querier system error: {}", + system_err + ))), + SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::generic_err(format!( + "Querier contract error: {}", + contract_err + ))), + SystemResult::Ok(ContractResult::Ok(value)) => Ok(value), + }?; + let params: ParamsResponse = from_json(&res)?; + + Ok(params) +} From f57af50b33d58641e2c7865e7daa278006abce23 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 7 Jan 2025 15:13:39 +1100 Subject: [PATCH 05/10] fix multitest compile --- packages/bindings-test/src/multitest.rs | 31 ++----------------------- packages/bindings/src/query.rs | 5 +++- 2 files changed, 6 insertions(+), 30 deletions(-) diff --git a/packages/bindings-test/src/multitest.rs b/packages/bindings-test/src/multitest.rs index 648bf82b..1020f6c1 100644 --- a/packages/bindings-test/src/multitest.rs +++ b/packages/bindings-test/src/multitest.rs @@ -1,7 +1,6 @@ use anyhow::{bail, Result as AnyResult}; use schemars::JsonSchema; use serde::de::DeserializeOwned; -use std::cmp::max; use std::fmt::Debug; use std::ops::{Deref, DerefMut}; use thiserror::Error; @@ -20,7 +19,7 @@ use cw_multi_test::{ }; use cw_storage_plus::{Item, Map}; -use babylon_bindings::{BabylonMsg, BabylonQuery}; +use babylon_bindings::{msg::BabylonMsg, query::BabylonQuery}; pub struct BabylonModule {} @@ -67,7 +66,7 @@ impl BabylonModule { impl Module for BabylonModule { type ExecT = BabylonMsg; - type QueryT = Empty; + type QueryT = BabylonQuery; type SudoT = Empty; fn execute( @@ -211,32 +210,6 @@ impl BabylonApp { } */ - /// This reverses to genesis (based on current time/height) - pub fn back_to_genesis(&mut self) { - self.update_block(|block| { - block.time = block.time.minus_seconds(BLOCK_TIME * block.height); - block.height = 0; - }); - } - - /// This advances BlockInfo by given number of blocks. - /// It does not do any callbacks, but keeps the ratio of seconds/block - pub fn advance_blocks(&mut self, blocks: u64) { - self.update_block(|block| { - block.time = block.time.plus_seconds(BLOCK_TIME * blocks); - block.height += blocks; - }); - } - - /// This advances BlockInfo by given number of seconds. - /// It does not do any callbacks, but keeps the ratio of seconds/blokc - pub fn advance_seconds(&mut self, seconds: u64) { - self.update_block(|block| { - block.time = block.time.plus_seconds(seconds); - block.height += max(1, seconds / BLOCK_TIME); - }); - } - /* /// next_block will call the end_blocker, increment block info 1 height and 5 seconds, /// and then call the begin_blocker (with no evidence) in the next block. diff --git a/packages/bindings/src/query.rs b/packages/bindings/src/query.rs index 03c0ba7d..4e697ec5 100644 --- a/packages/bindings/src/query.rs +++ b/packages/bindings/src/query.rs @@ -1,8 +1,11 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{ - from_json, to_json_binary, Addr, ContractResult, QuerierWrapper, StdError, SystemResult, + from_json, to_json_binary, Addr, ContractResult, CustomQuery, QuerierWrapper, StdError, + SystemResult, }; +impl CustomQuery for BabylonQuery {} + #[cw_serde] #[derive(QueryResponses)] pub enum BabylonQuery { From ac1b79726131890e299dd92401a8cd665212d673 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 7 Jan 2025 15:44:59 +1100 Subject: [PATCH 06/10] babylon query plugin --- contracts/babylon/src/contract.rs | 43 +++------ contracts/babylon/src/ibc.rs | 22 +++-- contracts/babylon/src/lib.rs | 28 +++--- contracts/babylon/src/multitest.rs | 6 -- contracts/babylon/src/multitest/suite.rs | 15 ++-- contracts/babylon/src/queries/mod.rs | 39 +++++--- contracts/babylon/src/state/config.rs | 1 - contracts/btc-finality/src/contract.rs | 80 ++++++++++++----- contracts/btc-finality/src/finality.rs | 23 ++--- contracts/btc-finality/src/multitest.rs | 4 - contracts/btc-finality/src/multitest/suite.rs | 8 +- contracts/btc-finality/src/queries.rs | 17 ++-- contracts/btc-finality/src/state/config.rs | 2 +- packages/bindings/src/query.rs | 9 +- .../proto/src/gen/babylon.zoneconcierge.v1.rs | 90 ++++++++++--------- 15 files changed, 211 insertions(+), 176 deletions(-) diff --git a/contracts/babylon/src/contract.rs b/contracts/babylon/src/contract.rs index fc1aedff..51fdafbc 100644 --- a/contracts/babylon/src/contract.rs +++ b/contracts/babylon/src/contract.rs @@ -1,12 +1,10 @@ -use babylon_bindings::babylon_sdk::{ - get_babylon_sdk_params, QueryParamsResponse, QUERY_PARAMS_PATH, -}; +use babylon_bindings::query::{get_babylon_sdk_params, BabylonQuery}; use cosmwasm_std::{ to_json_binary, to_json_string, Addr, Binary, Deps, DepsMut, Empty, Env, IbcMsg, MessageInfo, - QueryResponse, Reply, Response, SubMsg, SubMsgResponse, WasmMsg, + QueryResponse, Response, SubMsg, SubMsgResponse, WasmMsg, }; use cw2::set_contract_version; -use cw_utils::{must_pay, ParseReplyError}; +use cw_utils::must_pay; use babylon_apis::{btc_staking_api, finality_api, to_bech32_addr, to_module_canonical_addr}; use babylon_bindings::BabylonMsg; @@ -21,9 +19,6 @@ use crate::state::config::{Config, CONFIG}; pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -const REPLY_ID_INSTANTIATE_STAKING: u64 = 2; -const REPLY_ID_INSTANTIATE_FINALITY: u64 = 3; - /// When we instantiate the Babylon contract, it will optionally instantiate a BTC staking /// contract – if its code id is provided – to work with it for BTC re-staking support, /// as they both need references to each other. @@ -81,23 +76,11 @@ pub fn instantiate( Ok(res) } -/// Tries to get contract address from events in reply -fn reply_init_get_contract_address(reply: SubMsgResponse) -> Result { - for event in reply.events { - if event.ty == "instantiate" { - for attr in event.attributes { - if attr.key == "_contract_address" { - return Ok(Addr::unchecked(attr.value)); - } - } - } - } - Err(ContractError::ParseReply(ParseReplyError::ParseFailure( - "Cannot parse contract address".to_string(), - ))) -} - -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { +pub fn query( + deps: Deps, + _env: Env, + msg: QueryMsg, +) -> Result { match msg { QueryMsg::Config {} => Ok(to_json_binary(&queries::config(deps)?)?), QueryMsg::BtcBaseHeader {} => Ok(to_json_binary(&queries::btc_base_header(deps)?)?), @@ -133,7 +116,7 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result, _env: Env, _msg: Empty, ) -> Result, ContractError> { @@ -141,7 +124,7 @@ pub fn migrate( } pub fn execute( - deps: DepsMut, + deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, @@ -202,9 +185,7 @@ pub fn execute( // Assert the funds are there must_pay(&info, &cfg.denom)?; // Assert the sender is right - let btc_finality = cfg - .btc_finality - .ok_or(ContractError::BtcFinalityNotSet {})?; + let btc_finality = get_babylon_sdk_params(&deps.querier)?.btc_finality_contract_address; if info.sender != btc_finality { return Err(ContractError::Unauthorized {}); } @@ -298,7 +279,6 @@ mod tests { let info = message_info(&deps.api.addr_make(CREATOR), &[]); let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); assert_eq!(1, res.messages.len()); - assert_eq!(REPLY_ID_INSTANTIATE_FINALITY, res.messages[0].id); assert_eq!( res.messages[0].msg, WasmMsg::Instantiate { @@ -330,7 +310,6 @@ mod tests { let info = message_info(&deps.api.addr_make(CREATOR), &[]); let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); assert_eq!(1, res.messages.len()); - assert_eq!(REPLY_ID_INSTANTIATE_FINALITY, res.messages[0].id); assert_eq!( res.messages[0].msg, WasmMsg::Instantiate { diff --git a/contracts/babylon/src/ibc.rs b/contracts/babylon/src/ibc.rs index ee1c2f47..a6b1b5e2 100644 --- a/contracts/babylon/src/ibc.rs +++ b/contracts/babylon/src/ibc.rs @@ -1,5 +1,5 @@ use crate::error::ContractError; -use babylon_bindings::BabylonMsg; +use babylon_bindings::{query::BabylonQuery, BabylonMsg}; use babylon_proto::babylon::zoneconcierge::v1::{ zoneconcierge_packet_data::Packet, BtcTimestamp, ZoneconciergePacketData, }; @@ -35,7 +35,7 @@ pub const IBC_TRANSFER: Item = Item::new("ibc_transfer"); /// In the case of ChannelOpenTry there's a counterparty_version attribute in the message. /// Here we ensure the ordering and version constraints. pub fn ibc_channel_open( - deps: DepsMut, + deps: DepsMut, _env: Env, msg: IbcChannelOpenMsg, ) -> Result { @@ -67,7 +67,7 @@ pub fn ibc_channel_open( /// Second part of the 4-step handshake, i.e. ChannelOpenAck and ChannelOpenConfirm. pub fn ibc_channel_connect( - deps: DepsMut, + deps: DepsMut, _env: Env, msg: IbcChannelConnectMsg, ) -> Result { @@ -102,7 +102,7 @@ pub fn ibc_channel_connect( /// This is invoked on the IBC Channel Close message /// We perform any cleanup related to the channel pub fn ibc_channel_close( - _deps: DepsMut, + _deps: DepsMut, _env: Env, msg: IbcChannelCloseMsg, ) -> StdResult { @@ -126,7 +126,7 @@ pub fn ibc_channel_close( /// That's because we want to send an ACK for the packet regardless if there's an error or not, /// but in the case of an error, we do not want the state to be committed. pub fn ibc_packet_receive( - deps: DepsMut, + deps: DepsMut, _env: Env, msg: IbcPacketReceiveMsg, ) -> Result, Never> { @@ -174,16 +174,14 @@ pub(crate) mod ibc_packet { ActiveBtcDelegation, NewFinalityProvider, UnbondedBtcDelegation, }; use babylon_apis::finality_api::Evidence; - use babylon_bindings::babylon_sdk::{ - get_babylon_sdk_params, QueryParamsResponse, QUERY_PARAMS_PATH, - }; + use babylon_bindings::query::get_babylon_sdk_params; use babylon_proto::babylon::btcstaking::v1::BtcStakingIbcPacket; use babylon_proto::babylon::zoneconcierge::v1::zoneconcierge_packet_data::Packet::ConsumerSlashing; use babylon_proto::babylon::zoneconcierge::v1::ConsumerSlashingIbcPacket; use cosmwasm_std::{to_json_binary, IbcChannel, IbcMsg, WasmMsg}; pub fn handle_btc_timestamp( - deps: DepsMut, + deps: DepsMut, _caller: String, btc_ts: &BtcTimestamp, ) -> StdResult> { @@ -212,7 +210,7 @@ pub(crate) mod ibc_packet { } pub fn handle_btc_staking( - deps: DepsMut, + deps: DepsMut, _caller: String, btc_staking: &BtcStakingIbcPacket, ) -> StdResult> { @@ -303,7 +301,7 @@ pub fn packet_timeout(env: &Env) -> IbcTimeout { } pub fn ibc_packet_ack( - _deps: DepsMut, + _deps: DepsMut, _env: Env, _msg: IbcPacketAckMsg, ) -> Result { @@ -311,7 +309,7 @@ pub fn ibc_packet_ack( } pub fn ibc_packet_timeout( - _deps: DepsMut, + _deps: DepsMut, _env: Env, msg: IbcPacketTimeoutMsg, ) -> Result { diff --git a/contracts/babylon/src/lib.rs b/contracts/babylon/src/lib.rs index 18733424..e5da6b88 100644 --- a/contracts/babylon/src/lib.rs +++ b/contracts/babylon/src/lib.rs @@ -6,7 +6,7 @@ use cosmwasm_std::{ IbcPacketTimeoutMsg, IbcReceiveResponse, MessageInfo, Never, Reply, Response, StdResult, }; -use babylon_bindings::BabylonMsg; +use babylon_bindings::{query::BabylonQuery, BabylonMsg}; use crate::error::ContractError; pub use crate::msg::contract::ExecuteMsg; @@ -34,18 +34,26 @@ pub fn instantiate( } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, env: Env, msg: msg::contract::QueryMsg) -> Result { +pub fn query( + deps: Deps, + env: Env, + msg: msg::contract::QueryMsg, +) -> Result { contract::query(deps, env, msg) } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, env: Env, msg: Empty) -> Result, ContractError> { +pub fn migrate( + deps: DepsMut, + env: Env, + msg: Empty, +) -> Result, ContractError> { contract::migrate(deps, env, msg) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute( - deps: DepsMut, + deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, @@ -55,7 +63,7 @@ pub fn execute( #[cfg_attr(not(feature = "library"), entry_point)] pub fn ibc_channel_open( - deps: DepsMut, + deps: DepsMut, env: Env, msg: IbcChannelOpenMsg, ) -> Result { @@ -64,7 +72,7 @@ pub fn ibc_channel_open( #[cfg_attr(not(feature = "library"), entry_point)] pub fn ibc_channel_connect( - deps: DepsMut, + deps: DepsMut, env: Env, msg: IbcChannelConnectMsg, ) -> Result { @@ -73,7 +81,7 @@ pub fn ibc_channel_connect( #[cfg_attr(not(feature = "library"), entry_point)] pub fn ibc_channel_close( - deps: DepsMut, + deps: DepsMut, env: Env, msg: IbcChannelCloseMsg, ) -> StdResult { @@ -82,7 +90,7 @@ pub fn ibc_channel_close( #[cfg_attr(not(feature = "library"), entry_point)] pub fn ibc_packet_receive( - deps: DepsMut, + deps: DepsMut, env: Env, msg: IbcPacketReceiveMsg, ) -> Result, Never> { @@ -91,7 +99,7 @@ pub fn ibc_packet_receive( #[cfg_attr(not(feature = "library"), entry_point)] pub fn ibc_packet_ack( - deps: DepsMut, + deps: DepsMut, env: Env, msg: IbcPacketAckMsg, ) -> Result { @@ -100,7 +108,7 @@ pub fn ibc_packet_ack( #[cfg_attr(not(feature = "library"), entry_point)] pub fn ibc_packet_timeout( - deps: DepsMut, + deps: DepsMut, env: Env, msg: IbcPacketTimeoutMsg, ) -> Result { diff --git a/contracts/babylon/src/multitest.rs b/contracts/babylon/src/multitest.rs index 39969574..b8e8f0f6 100644 --- a/contracts/babylon/src/multitest.rs +++ b/contracts/babylon/src/multitest.rs @@ -58,9 +58,6 @@ mod instantiation { // Confirm the btc-staking contract has been instantiated and set let config = suite.get_config(); - assert_eq!(config.btc_staking, Some(Addr::unchecked(CONTRACT1_ADDR))); - // Confirm the btc-finality contract has been instantiated and set - assert_eq!(config.btc_finality, Some(Addr::unchecked(CONTRACT2_ADDR))); } #[test] @@ -82,9 +79,6 @@ mod instantiation { // Confirm the btc-staking contract has been instantiated and set let config = suite.get_config(); - assert_eq!(config.btc_staking, Some(Addr::unchecked(CONTRACT1_ADDR))); - // Confirm the btc-finality contract has been instantiated and set - assert_eq!(config.btc_finality, Some(Addr::unchecked(CONTRACT2_ADDR))); } #[test] diff --git a/contracts/babylon/src/multitest/suite.rs b/contracts/babylon/src/multitest/suite.rs index 1c029101..08de2303 100644 --- a/contracts/babylon/src/multitest/suite.rs +++ b/contracts/babylon/src/multitest/suite.rs @@ -3,6 +3,7 @@ use crate::msg::ibc::TransferInfoResponse; use crate::msg::ibc::{IbcTransferInfo, Recipient}; use crate::state::config::Config; use anyhow::Result as AnyResult; +use babylon_bindings::query::BabylonQuery; use derivative::Derivative; use cosmwasm_std::{Addr, Binary, Empty}; @@ -12,11 +13,7 @@ use babylon_bindings::BabylonMsg; use babylon_bindings_test::BabylonApp; use babylon_bitcoin::chain_params::Network; -use crate::msg::contract::{InstantiateMsg, QueryMsg}; -use crate::multitest::{CONTRACT1_ADDR, CONTRACT2_ADDR}; -use crate::state::config::Config; - -fn contract_btc_staking() -> Box> { +fn contract_btc_staking() -> Box> { let contract = ContractWrapper::new( btc_staking::contract::execute, btc_staking::contract::instantiate, @@ -25,7 +22,7 @@ fn contract_btc_staking() -> Box> { Box::new(contract) } -fn contract_btc_finality() -> Box> { +fn contract_btc_finality() -> Box> { let contract = ContractWrapper::new( btc_finality::contract::execute, btc_finality::contract::instantiate, @@ -34,7 +31,7 @@ fn contract_btc_finality() -> Box> { Box::new(contract) } -fn contract_babylon() -> Box> { +fn contract_babylon() -> Box> { let contract = ContractWrapper::new(crate::execute, crate::instantiate, crate::query) .with_migrate(crate::migrate); Box::new(contract) @@ -154,7 +151,7 @@ impl SuiteBuilder { Suite { app, code_id: contract_code_id, - babylon_contract: babylon_contract, + babylon_contract: contract, btc_staking_contract: btc_staking_contract, btc_finality_contract: btc_finality_contract, owner, @@ -218,7 +215,7 @@ impl Suite { pub fn get_transfer_info(&self) -> TransferInfoResponse { self.app .wrap() - .query_wasm_smart(self.contract.clone(), &QueryMsg::TransferInfo {}) + .query_wasm_smart(self.babylon_contract.clone(), &QueryMsg::TransferInfo {}) .unwrap() } diff --git a/contracts/babylon/src/queries/mod.rs b/contracts/babylon/src/queries/mod.rs index 5181bcf6..00dc8fdc 100644 --- a/contracts/babylon/src/queries/mod.rs +++ b/contracts/babylon/src/queries/mod.rs @@ -14,31 +14,35 @@ use crate::state::btc_light_client::{ }; use crate::state::config::{Config, CONFIG}; use crate::state::cz_header_chain::{get_cz_header, get_last_cz_header}; +use babylon_bindings::query::BabylonQuery; use babylon_bitcoin::BlockHash; use cosmwasm_std::{Deps, StdResult}; use std::str::FromStr; -pub fn config(deps: Deps) -> StdResult { +pub fn config(deps: Deps) -> StdResult { CONFIG.load(deps.storage) } -pub fn btc_base_header(deps: Deps) -> Result { +pub fn btc_base_header(deps: Deps) -> Result { let btc_header_info = get_base_header(deps.storage)?; BtcHeaderResponse::try_from(&btc_header_info) } -pub fn btc_tip_header(_deps: Deps) -> Result { +pub fn btc_tip_header(_deps: Deps) -> Result { let btc_header_info = get_tip(_deps.storage)?; BtcHeaderResponse::try_from(&btc_header_info) } -pub fn btc_header(deps: Deps, height: u32) -> Result { +pub fn btc_header( + deps: Deps, + height: u32, +) -> Result { let btc_header_info = get_header(deps.storage, height)?; BtcHeaderResponse::try_from(&btc_header_info) } pub fn btc_header_by_hash( - deps: Deps, + deps: Deps, hash: &str, ) -> Result { let hash = BlockHash::from_str(hash)?; @@ -47,7 +51,7 @@ pub fn btc_header_by_hash( } pub fn btc_headers( - deps: Deps, + deps: Deps, start_after: Option, limit: Option, reverse: Option, @@ -62,18 +66,22 @@ pub fn btc_headers( }) } -pub fn babylon_base_epoch(deps: Deps) -> Result { +pub fn babylon_base_epoch( + deps: Deps, +) -> Result { let epoch = get_base_epoch(deps.storage)?; Ok(EpochResponse::from(&epoch)) } -pub fn babylon_last_epoch(deps: Deps) -> Result { +pub fn babylon_last_epoch( + deps: Deps, +) -> Result { let epoch = get_last_finalized_epoch(deps.storage)?; Ok(EpochResponse::from(&epoch)) } pub fn babylon_epoch( - deps: Deps, + deps: Deps, epoch_number: u64, ) -> Result { let epoch = get_epoch(deps.storage, epoch_number)?; @@ -81,24 +89,29 @@ pub fn babylon_epoch( } pub fn babylon_checkpoint( - deps: Deps, + deps: Deps, epoch_number: u64, ) -> Result { let raw_checkpoint = get_checkpoint(deps.storage, epoch_number)?; Ok(CheckpointResponse::from(&raw_checkpoint)) } -pub fn cz_last_header(deps: Deps) -> Result { +pub fn cz_last_header(deps: Deps) -> Result { let header = get_last_cz_header(deps.storage)?; Ok(CzHeaderResponse::from(&header)) } -pub(crate) fn cz_header(deps: Deps, height: u64) -> Result { +pub(crate) fn cz_header( + deps: Deps, + height: u64, +) -> Result { let header = get_cz_header(deps.storage, height)?; Ok(CzHeaderResponse::from(&header)) } -pub(crate) fn transfer_info(deps: Deps) -> Result { +pub(crate) fn transfer_info( + deps: Deps, +) -> Result { let transfer_info = IBC_TRANSFER.may_load(deps.storage)?; Ok(transfer_info) } diff --git a/contracts/babylon/src/state/config.rs b/contracts/babylon/src/state/config.rs index 5c818e5d..d26881ed 100644 --- a/contracts/babylon/src/state/config.rs +++ b/contracts/babylon/src/state/config.rs @@ -1,5 +1,4 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::Addr; use cw_storage_plus::Item; pub(crate) const CONFIG: Item = Item::new("config"); diff --git a/contracts/btc-finality/src/contract.rs b/contracts/btc-finality/src/contract.rs index 37720891..2a52f1ea 100644 --- a/contracts/btc-finality/src/contract.rs +++ b/contracts/btc-finality/src/contract.rs @@ -1,7 +1,5 @@ use babylon_apis::finality_api::SudoMsg; -use babylon_bindings::babylon_sdk::{ - get_babylon_sdk_params, QueryParamsResponse, QUERY_PARAMS_PATH, -}; +use babylon_bindings::query::{get_babylon_sdk_params, BabylonQuery}; use babylon_bindings::BabylonMsg; use btc_staking::msg::ActivatedHeightResponse; #[cfg(not(feature = "library"))] @@ -29,7 +27,7 @@ pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( - mut deps: DepsMut, + mut deps: DepsMut, _env: Env, info: MessageInfo, msg: InstantiateMsg, @@ -58,7 +56,7 @@ pub fn instantiate( } /// Queries the chain's blocks per year using the mint Params Grpc query -fn get_blocks_per_year(deps: &mut DepsMut) -> Result { +fn get_blocks_per_year(deps: &mut DepsMut) -> Result { let blocks_per_year; #[cfg(any(test, all(feature = "library", not(target_arch = "wasm32"))))] { @@ -85,12 +83,16 @@ fn get_blocks_per_year(deps: &mut DepsMut) -> Result { } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(_deps: DepsMut, _env: Env, _reply: Reply) -> StdResult { +pub fn reply(_deps: DepsMut, _env: Env, _reply: Reply) -> StdResult { Ok(Response::default()) } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { +pub fn query( + deps: Deps, + _env: Env, + msg: QueryMsg, +) -> Result { match msg { QueryMsg::Config {} => Ok(to_json_binary(&queries::config(deps)?)?), QueryMsg::Params {} => Ok(to_json_binary(&queries::params(deps)?)?), @@ -145,7 +147,7 @@ pub fn migrate(_deps: DepsMut, _env: Env, _msg: Empty) -> StdResult { #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute( - deps: DepsMut, + deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, @@ -192,7 +194,7 @@ pub fn execute( #[cfg_attr(not(feature = "library"), entry_point)] pub fn sudo( - mut deps: DepsMut, + mut deps: DepsMut, env: Env, msg: SudoMsg, ) -> Result, ContractError> { @@ -206,14 +208,11 @@ pub fn sudo( } fn handle_update_staking( - deps: DepsMut, + deps: DepsMut, info: MessageInfo, staking_addr: String, ) -> Result, ContractError> { - let params = deps - .querier - .query_grpc(QUERY_PARAMS_PATH.to_owned(), Binary::new("".into()))?; - let params = QueryParamsResponse::from(params).params; + let params = get_babylon_sdk_params(&deps.querier)?; // ensure the sender is the Babylon contract if info.sender != params.babylon_contract_address @@ -230,7 +229,10 @@ fn handle_update_staking( Ok(Response::new().add_attributes(attributes)) } -fn handle_begin_block(deps: &mut DepsMut, env: Env) -> Result, ContractError> { +fn handle_begin_block( + deps: &mut DepsMut, + env: Env, +) -> Result, ContractError> { // Distribute rewards distribute_rewards(deps, &env)?; @@ -243,7 +245,7 @@ fn handle_begin_block(deps: &mut DepsMut, env: Env) -> Result, env: Env, _hash_hex: &str, app_hash_hex: &str, @@ -280,7 +282,7 @@ fn handle_end_block( } fn send_rewards_msg( - deps: &mut DepsMut, + deps: &mut DepsMut, rewards: u128, cfg: &Config, ) -> Result { @@ -306,7 +308,9 @@ fn send_rewards_msg( fp_distribution: fp_rewards.clone(), }; let wasm_msg = WasmMsg::Execute { - contract_addr: cfg.babylon.to_string(), + contract_addr: get_babylon_sdk_params(&deps.querier)? + .babylon_contract_address + .to_string(), msg: to_json_binary(&msg)?, funds: coins(rewards, cfg.denom.as_str()), }; @@ -318,10 +322,10 @@ fn send_rewards_msg( Ok(wasm_msg) } -pub fn get_activated_height(querier: &QuerierWrapper) -> StdResult { +pub fn get_activated_height(querier: &QuerierWrapper) -> StdResult { // TODO: Use a raw query let query = encode_smart_query( - ¶ms.btc_staking_contract_address, + &get_babylon_sdk_params(&querier)?.btc_staking_contract_address, &btc_staking::msg::QueryMsg::ActivatedHeight {}, )?; let res: ActivatedHeightResponse = querier.query(&query)?; @@ -341,11 +345,15 @@ pub(crate) fn encode_smart_query( #[cfg(test)] pub(crate) mod tests { + use std::marker::PhantomData; + use super::*; + use babylon_bindings::query::ParamsResponse; use cosmwasm_std::{ from_json, - testing::{message_info, mock_dependencies, mock_env}, + testing::{message_info, mock_env, MockApi, MockQuerier, MockStorage}, + Coin, ContractResult, OwnedDeps, SystemResult, }; use cw_controllers::AdminResponse; @@ -353,6 +361,36 @@ pub(crate) mod tests { pub(crate) const INIT_ADMIN: &str = "initial_admin"; const NEW_ADMIN: &str = "new_admin"; + pub fn mock_dependencies( + ) -> OwnedDeps, BabylonQuery> { + let custom_querier: MockQuerier = MockQuerier::new(&[("", &[])]) + .with_custom_handler(|query| { + // Handle your custom query type here + match query { + BabylonQuery::Params {} => { + // Return a mock response for the custom query + let response = ParamsResponse { + babylon_contract_address: Addr::unchecked(""), + btc_staking_contract_address: Addr::unchecked(""), + btc_finality_contract_address: Addr::unchecked(""), + babylon_contract_code_id: 0, + btc_staking_contract_code_id: 0, + btc_finality_contract_code_id: 0, + max_gas_begin_blocker: 0, + }; + SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) + } + _ => panic!("Unsupported query type"), + } + }); + OwnedDeps { + storage: MockStorage::default(), + api: MockApi::default(), + querier: custom_querier, + custom_query_type: PhantomData, + } + } + #[test] fn instantiate_without_admin() { let mut deps = mock_dependencies(); diff --git a/contracts/btc-finality/src/finality.rs b/contracts/btc-finality/src/finality.rs index d43c2826..e1b59659 100644 --- a/contracts/btc-finality/src/finality.rs +++ b/contracts/btc-finality/src/finality.rs @@ -9,7 +9,7 @@ use crate::state::public_randomness::{ }; use babylon_apis::btc_staking_api::FinalityProvider; use babylon_apis::finality_api::{Evidence, IndexedBlock, PubRandCommit}; -use babylon_bindings::babylon_sdk::get_babylon_sdk_params; +use babylon_bindings::query::{get_babylon_sdk_params, BabylonQuery}; use babylon_bindings::BabylonMsg; use babylon_merkle::Proof; use btc_staking::msg::{FinalityProviderInfo, FinalityProvidersByPowerResponse}; @@ -26,7 +26,7 @@ use std::collections::HashSet; use std::ops::Mul; pub fn handle_public_randomness_commit( - deps: DepsMut, + deps: DepsMut, fp_pubkey_hex: &str, start_height: u64, num_pub_rand: u64, @@ -128,7 +128,7 @@ fn verify_commitment_signature( #[allow(clippy::too_many_arguments)] pub fn handle_finality_signature( - mut deps: DepsMut, + mut deps: DepsMut, env: Env, fp_btc_pk_hex: &str, height: u64, @@ -294,7 +294,7 @@ pub fn handle_finality_signature( /// `slash_finality_provider` slashes a finality provider with the given evidence including setting /// its voting power to zero, extracting its BTC SK, and emitting an event fn slash_finality_provider( - deps: &mut DepsMut, + deps: &mut DepsMut, fp_btc_pk_hex: &str, evidence: &Evidence, ) -> Result<(WasmMsg, Event), ContractError> { @@ -397,7 +397,7 @@ fn msg_to_sign(height: u64, block_hash: &[u8]) -> Vec { } pub fn index_block( - deps: &mut DepsMut, + deps: &mut DepsMut, height: u64, app_hash: &[u8], ) -> Result { @@ -426,7 +426,7 @@ pub fn index_block( /// /// It must be invoked only after the BTC staking protocol is activated. pub fn tally_blocks( - deps: &mut DepsMut, + deps: &mut DepsMut, env: &Env, activated_height: u64, ) -> Result<(Option, Vec), ContractError> { @@ -546,7 +546,7 @@ fn finalize_block( /// `compute_block_rewards` computes the block rewards for the finality providers fn compute_block_rewards( - deps: &mut DepsMut, + deps: &mut DepsMut, cfg: &Config, finalized_blocks: u64, ) -> Result { @@ -574,7 +574,7 @@ const QUERY_LIMIT: Option = Some(30); /// `compute_active_finality_providers` sorts all finality providers, counts the total voting /// power of top finality providers, and records them in the contract state pub fn compute_active_finality_providers( - deps: &mut DepsMut, + deps: &mut DepsMut, height: u64, max_active_fps: usize, ) -> Result<(), ContractError> { @@ -628,7 +628,7 @@ pub fn compute_active_finality_providers( pub fn list_fps_by_power( staking_addr: &Addr, - querier: &QuerierWrapper, + querier: &QuerierWrapper, start_after: Option, limit: Option, ) -> StdResult> { @@ -641,7 +641,10 @@ pub fn list_fps_by_power( } /// `distribute_rewards` distributes rewards to finality providers who are in the active set at `height` -pub fn distribute_rewards(deps: &mut DepsMut, env: &Env) -> Result<(), ContractError> { +pub fn distribute_rewards( + deps: &mut DepsMut, + env: &Env, +) -> Result<(), ContractError> { // Try to use the finality provider set at the previous height let active_fps = FP_SET.may_load(deps.storage, env.block.height - 1)?; // Short-circuit if there are no active finality providers diff --git a/contracts/btc-finality/src/multitest.rs b/contracts/btc-finality/src/multitest.rs index f83f4bec..8ad17890 100644 --- a/contracts/btc-finality/src/multitest.rs +++ b/contracts/btc-finality/src/multitest.rs @@ -21,16 +21,12 @@ mod instantiation { // Confirm the btc-staking contract has been instantiated and set let config = suite.get_babylon_config(); - assert_eq!(config.btc_staking, Some(Addr::unchecked(CONTRACT1_ADDR))); - // Confirm the btc-finality contract has been instantiated and set - assert_eq!(config.btc_finality, Some(Addr::unchecked(CONTRACT2_ADDR))); // Check that the btc-staking contract was initialized correctly let btc_staking_config = suite.get_btc_staking_config(); assert_eq!(btc_staking_config.babylon, Addr::unchecked(CONTRACT0_ADDR)); // Check that the btc-finality contract was initialized correctly let btc_finality_config = suite.get_btc_finality_config(); - assert_eq!(btc_finality_config.babylon, Addr::unchecked(CONTRACT0_ADDR)); } } diff --git a/contracts/btc-finality/src/multitest/suite.rs b/contracts/btc-finality/src/multitest/suite.rs index e2760faf..0b7c611e 100644 --- a/contracts/btc-finality/src/multitest/suite.rs +++ b/contracts/btc-finality/src/multitest/suite.rs @@ -1,4 +1,5 @@ use anyhow::Result as AnyResult; +use babylon_bindings::query::BabylonQuery; use derivative::Derivative; use hex::ToHex; @@ -18,7 +19,7 @@ use btc_staking::msg::{ActivatedHeightResponse, FinalityProviderInfo}; use crate::msg::{EvidenceResponse, FinalitySignatureResponse}; use crate::multitest::{CONTRACT1_ADDR, CONTRACT2_ADDR}; -fn contract_btc_staking() -> Box> { +fn contract_btc_staking() -> Box> { let contract = ContractWrapper::new( btc_staking::contract::execute, btc_staking::contract::instantiate, @@ -27,7 +28,7 @@ fn contract_btc_staking() -> Box> { Box::new(contract) } -fn contract_btc_finality() -> Box> { +fn contract_btc_finality() -> Box> { let contract = ContractWrapper::new( crate::contract::execute, crate::contract::instantiate, @@ -37,13 +38,12 @@ fn contract_btc_finality() -> Box> { Box::new(contract) } -fn contract_babylon() -> Box> { +fn contract_babylon() -> Box> { let contract = ContractWrapper::new( babylon_contract::execute, babylon_contract::instantiate, babylon_contract::query, ) - .with_reply(babylon_contract::reply) .with_migrate(babylon_contract::migrate); Box::new(contract) } diff --git a/contracts/btc-finality/src/queries.rs b/contracts/btc-finality/src/queries.rs index f6774f8e..8f6702bd 100644 --- a/contracts/btc-finality/src/queries.rs +++ b/contracts/btc-finality/src/queries.rs @@ -1,3 +1,4 @@ +use babylon_bindings::query::BabylonQuery; use cosmwasm_std::Order::{Ascending, Descending}; use cosmwasm_std::{Deps, StdResult}; use cw_storage_plus::Bound; @@ -10,11 +11,11 @@ use crate::state::config::{Config, Params}; use crate::state::config::{CONFIG, PARAMS}; use crate::state::finality::{BLOCKS, EVIDENCES, SIGNATURES}; -pub fn config(deps: Deps) -> StdResult { +pub fn config(deps: Deps) -> StdResult { CONFIG.load(deps.storage) } -pub fn params(deps: Deps) -> StdResult { +pub fn params(deps: Deps) -> StdResult { PARAMS.load(deps.storage) } @@ -23,7 +24,7 @@ const MAX_LIMIT: u32 = 30; const DEFAULT_LIMIT: u32 = 10; pub fn finality_signature( - deps: Deps, + deps: Deps, btc_pk_hex: String, height: u64, ) -> StdResult { @@ -35,7 +36,7 @@ pub fn finality_signature( } } -pub fn block(deps: Deps, height: u64) -> StdResult { +pub fn block(deps: Deps, height: u64) -> StdResult { BLOCKS.load(deps.storage, height) } @@ -44,7 +45,7 @@ pub fn block(deps: Deps, height: u64) -> StdResult { /// `finalised`: List only finalised blocks if true, otherwise list all blocks. /// `reverse`: List in descending order if present and true, otherwise in ascending order. pub fn blocks( - deps: Deps, + deps: Deps, start_after: Option, limit: Option, finalised: Option, @@ -73,7 +74,11 @@ pub fn blocks( Ok(BlocksResponse { blocks }) } -pub fn evidence(deps: Deps, btc_pk_hex: String, height: u64) -> StdResult { +pub fn evidence( + deps: Deps, + btc_pk_hex: String, + height: u64, +) -> StdResult { let evidence = EVIDENCES.may_load(deps.storage, (&btc_pk_hex, height))?; Ok(EvidenceResponse { evidence }) } diff --git a/contracts/btc-finality/src/state/config.rs b/contracts/btc-finality/src/state/config.rs index 5d257614..669bf3ae 100644 --- a/contracts/btc-finality/src/state/config.rs +++ b/contracts/btc-finality/src/state/config.rs @@ -1,7 +1,7 @@ use derivative::Derivative; use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Decimal}; +use cosmwasm_std::Decimal; use cw_controllers::Admin; use cw_storage_plus::Item; diff --git a/packages/bindings/src/query.rs b/packages/bindings/src/query.rs index 4e697ec5..8803ba8b 100644 --- a/packages/bindings/src/query.rs +++ b/packages/bindings/src/query.rs @@ -4,8 +4,6 @@ use cosmwasm_std::{ SystemResult, }; -impl CustomQuery for BabylonQuery {} - #[cw_serde] #[derive(QueryResponses)] pub enum BabylonQuery { @@ -13,6 +11,9 @@ pub enum BabylonQuery { Params {}, } +// Implement required traits for BabylonQuery +impl CustomQuery for BabylonQuery {} + #[cw_serde] pub struct ParamsResponse { /// babylon_contract_code_id is the code ID of the Babylon contract @@ -31,7 +32,9 @@ pub struct ParamsResponse { pub max_gas_begin_blocker: u32, } -pub fn get_babylon_sdk_params(querier: &QuerierWrapper) -> Result { +pub fn get_babylon_sdk_params( + querier: &QuerierWrapper, +) -> Result { let query = BabylonQuery::Params {}; let res = match querier.raw_query(&to_json_binary(&query)?) { SystemResult::Err(system_err) => Err(StdError::generic_err(format!( diff --git a/packages/proto/src/gen/babylon.zoneconcierge.v1.rs b/packages/proto/src/gen/babylon.zoneconcierge.v1.rs index a8a39e36..866c3383 100644 --- a/packages/proto/src/gen/babylon.zoneconcierge.v1.rs +++ b/packages/proto/src/gen/babylon.zoneconcierge.v1.rs @@ -4,35 +4,35 @@ #[derive(Clone, PartialEq, ::prost::Message)] pub struct IndexedHeader { /// consumer_id is the unique ID of the consumer - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub consumer_id: ::prost::alloc::string::String, /// hash is the hash of this header - #[prost(bytes="bytes", tag="2")] + #[prost(bytes = "bytes", tag = "2")] pub hash: ::prost::bytes::Bytes, /// height is the height of this header on CZ ledger /// (hash, height) jointly provides the position of the header on CZ ledger - #[prost(uint64, tag="3")] + #[prost(uint64, tag = "3")] pub height: u64, /// time is the timestamp of this header on CZ ledger /// it is needed for CZ to unbond all mature validators/delegations /// before this timestamp when this header is BTC-finalised - #[prost(message, optional, tag="4")] + #[prost(message, optional, tag = "4")] pub time: ::core::option::Option<::pbjson_types::Timestamp>, /// babylon_header_hash is the hash of the babylon block that includes this CZ /// header - #[prost(bytes="bytes", tag="5")] + #[prost(bytes = "bytes", tag = "5")] pub babylon_header_hash: ::prost::bytes::Bytes, /// babylon_header_height is the height of the babylon block that includes this CZ /// header - #[prost(uint64, tag="6")] + #[prost(uint64, tag = "6")] pub babylon_header_height: u64, /// epoch is the epoch number of this header on Babylon ledger - #[prost(uint64, tag="7")] + #[prost(uint64, tag = "7")] pub babylon_epoch: u64, /// babylon_tx_hash is the hash of the tx that includes this header /// (babylon_block_height, babylon_tx_hash) jointly provides the position of /// the header on Babylon ledger - #[prost(bytes="bytes", tag="8")] + #[prost(bytes = "bytes", tag = "8")] pub babylon_tx_hash: ::prost::bytes::Bytes, } /// Forks is a list of non-canonical `IndexedHeader`s at the same height. @@ -53,7 +53,7 @@ pub struct IndexedHeader { #[derive(Clone, PartialEq, ::prost::Message)] pub struct Forks { /// blocks is the list of non-canonical indexed headers at the same height - #[prost(message, repeated, tag="3")] + #[prost(message, repeated, tag = "3")] pub headers: ::prost::alloc::vec::Vec, } /// ChainInfo is the information of a CZ @@ -61,18 +61,18 @@ pub struct Forks { #[derive(Clone, PartialEq, ::prost::Message)] pub struct ChainInfo { /// consumer_id is the ID of the consumer - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub consumer_id: ::prost::alloc::string::String, /// latest_header is the latest header in CZ's canonical chain - #[prost(message, optional, tag="2")] + #[prost(message, optional, tag = "2")] pub latest_header: ::core::option::Option, /// latest_forks is the latest forks, formed as a series of IndexedHeader (from /// low to high) - #[prost(message, optional, tag="3")] + #[prost(message, optional, tag = "3")] pub latest_forks: ::core::option::Option, /// timestamped_headers_count is the number of timestamped headers in CZ's /// canonical chain - #[prost(uint64, tag="4")] + #[prost(uint64, tag = "4")] pub timestamped_headers_count: u64, } /// FinalizedChainInfo is the information of a CZ that is BTC-finalised @@ -80,23 +80,23 @@ pub struct ChainInfo { #[derive(Clone, PartialEq, ::prost::Message)] pub struct FinalizedChainInfo { /// consumer_id is the ID of the consumer - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub consumer_id: ::prost::alloc::string::String, /// finalized_chain_info is the info of the CZ - #[prost(message, optional, tag="2")] + #[prost(message, optional, tag = "2")] pub finalized_chain_info: ::core::option::Option, /// epoch_info is the metadata of the last BTC-finalised epoch - #[prost(message, optional, tag="3")] + #[prost(message, optional, tag = "3")] pub epoch_info: ::core::option::Option, /// raw_checkpoint is the raw checkpoint of this epoch - #[prost(message, optional, tag="4")] + #[prost(message, optional, tag = "4")] pub raw_checkpoint: ::core::option::Option, /// btc_submission_key is position of two BTC txs that include the raw /// checkpoint of this epoch - #[prost(message, optional, tag="5")] + #[prost(message, optional, tag = "5")] pub btc_submission_key: ::core::option::Option, /// proof is the proof that the chain info is finalized - #[prost(message, optional, tag="6")] + #[prost(message, optional, tag = "6")] pub proof: ::core::option::Option, } /// ProofEpochSealed is the proof that an epoch is sealed by the sealer header, @@ -115,15 +115,16 @@ pub struct ProofEpochSealed { /// validator_set is the validator set of the sealed epoch /// This validator set has generated a BLS multisig on `app_hash` of /// the sealer header - #[prost(message, repeated, tag="1")] - pub validator_set: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "1")] + pub validator_set: + ::prost::alloc::vec::Vec, /// proof_epoch_info is the Merkle proof that the epoch's metadata is committed /// to `app_hash` of the sealer header - #[prost(message, optional, tag="2")] + #[prost(message, optional, tag = "2")] pub proof_epoch_info: ::core::option::Option, /// proof_epoch_info is the Merkle proof that the epoch's validator set is /// committed to `app_hash` of the sealer header - #[prost(message, optional, tag="3")] + #[prost(message, optional, tag = "3")] pub proof_epoch_val_set: ::core::option::Option, } /// ProofFinalizedChainInfo is a set of proofs that attest a chain info is @@ -137,16 +138,17 @@ pub struct ProofEpochSealed { pub struct ProofFinalizedChainInfo { /// proof_cz_header_in_epoch is the proof that the CZ header is timestamped /// within a certain epoch - #[prost(message, optional, tag="1")] + #[prost(message, optional, tag = "1")] pub proof_cz_header_in_epoch: ::core::option::Option, /// proof_epoch_sealed is the proof that the epoch is sealed - #[prost(message, optional, tag="2")] + #[prost(message, optional, tag = "2")] pub proof_epoch_sealed: ::core::option::Option, /// proof_epoch_submitted is the proof that the epoch's checkpoint is included /// in BTC ledger It is the two TransactionInfo in the best (i.e., earliest) /// checkpoint submission - #[prost(message, repeated, tag="3")] - pub proof_epoch_submitted: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "3")] + pub proof_epoch_submitted: + ::prost::alloc::vec::Vec, } /// ZoneconciergePacketData is the message that defines the IBC packets of /// ZoneConcierge @@ -154,23 +156,25 @@ pub struct ProofFinalizedChainInfo { #[derive(Clone, PartialEq, ::prost::Message)] pub struct ZoneconciergePacketData { /// packet is the actual message carried in the IBC packet - #[prost(oneof="zoneconcierge_packet_data::Packet", tags="1, 2, 3, 4")] + #[prost(oneof = "zoneconcierge_packet_data::Packet", tags = "1, 2, 3, 4")] pub packet: ::core::option::Option, } /// Nested message and enum types in `ZoneconciergePacketData`. pub mod zoneconcierge_packet_data { /// packet is the actual message carried in the IBC packet #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Packet { - #[prost(message, tag="1")] + #[prost(message, tag = "1")] BtcTimestamp(super::BtcTimestamp), - #[prost(message, tag="2")] + #[prost(message, tag = "2")] BtcStaking(super::super::super::btcstaking::v1::BtcStakingIbcPacket), - #[prost(message, tag="3")] + #[prost(message, tag = "3")] ConsumerSlashing(super::ConsumerSlashingIbcPacket), - #[prost(message, tag="4")] - ConsumerFpDistribution(cosmos_sdk_proto::ibc::applications::transfer::v2::FungibleTokenPacketData), + #[prost(message, tag = "4")] + ConsumerFpDistribution( + cosmos_sdk_proto::ibc::applications::transfer::v2::FungibleTokenPacketData, + ), } } /// BTCTimestamp is a BTC timestamp that carries information of a BTC-finalised epoch @@ -182,32 +186,30 @@ pub mod zoneconcierge_packet_data { #[derive(Clone, PartialEq, ::prost::Message)] pub struct BtcTimestamp { /// header is the last CZ header in the finalized Babylon epoch - #[prost(message, optional, tag="1")] + #[prost(message, optional, tag = "1")] pub header: ::core::option::Option, // // Data for BTC light client - /// btc_headers is BTC headers between /// - the block AFTER the common ancestor of BTC tip at epoch `lastFinalizedEpoch-1` and BTC tip at epoch `lastFinalizedEpoch` /// - BTC tip at epoch `lastFinalizedEpoch` /// where `lastFinalizedEpoch` is the last finalised epoch in Babylon - #[prost(message, repeated, tag="2")] + #[prost(message, repeated, tag = "2")] pub btc_headers: ::prost::alloc::vec::Vec, // // Data for Babylon epoch chain - /// epoch_info is the metadata of the sealed epoch - #[prost(message, optional, tag="3")] + #[prost(message, optional, tag = "3")] pub epoch_info: ::core::option::Option, /// raw_checkpoint is the raw checkpoint that seals this epoch - #[prost(message, optional, tag="4")] + #[prost(message, optional, tag = "4")] pub raw_checkpoint: ::core::option::Option, /// btc_submission_key is position of two BTC txs that include the raw checkpoint of this epoch - #[prost(message, optional, tag="5")] + #[prost(message, optional, tag = "5")] pub btc_submission_key: ::core::option::Option, /// /// Proofs that the header is finalized - #[prost(message, optional, tag="6")] + #[prost(message, optional, tag = "6")] pub proof: ::core::option::Option, } /// ConsumerSlashingIBCPacket defines the slashing information that a Consumer sends to Babylon's ZoneConcierge upon a @@ -217,7 +219,7 @@ pub struct BtcTimestamp { #[derive(Clone, PartialEq, ::prost::Message)] pub struct ConsumerSlashingIbcPacket { /// / evidence is the FP slashing evidence that the Consumer sends to Babylon - #[prost(message, optional, tag="1")] + #[prost(message, optional, tag = "1")] pub evidence: ::core::option::Option, } /// QueryFinalizedChainsInfoResponse is response type for the @@ -225,7 +227,7 @@ pub struct ConsumerSlashingIbcPacket { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct QueryFinalizedChainsInfoResponse { - #[prost(message, repeated, tag="1")] + #[prost(message, repeated, tag = "1")] pub finalized_chains_info: ::prost::alloc::vec::Vec, } // @@protoc_insertion_point(module) From 3d12c3aea98092b058ac9c3060986985219a794f Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 7 Jan 2025 17:19:26 +1100 Subject: [PATCH 07/10] minor --- contracts/babylon/src/contract.rs | 2 +- contracts/babylon/src/ibc.rs | 9 +++--- contracts/babylon/src/lib.rs | 2 +- packages/bindings-test/src/lib.rs | 37 +++++++++++++++++++++++++ packages/bindings-test/src/multitest.rs | 27 ++++++++++++++++++ 5 files changed, 71 insertions(+), 6 deletions(-) diff --git a/contracts/babylon/src/contract.rs b/contracts/babylon/src/contract.rs index 51fdafbc..755f3362 100644 --- a/contracts/babylon/src/contract.rs +++ b/contracts/babylon/src/contract.rs @@ -24,7 +24,7 @@ pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); /// as they both need references to each other. /// The admin of the BTC staking contract is taken as an explicit argument. pub fn instantiate( - deps: DepsMut, + deps: DepsMut, _env: Env, _info: MessageInfo, msg: InstantiateMsg, diff --git a/contracts/babylon/src/ibc.rs b/contracts/babylon/src/ibc.rs index a6b1b5e2..22ce4cae 100644 --- a/contracts/babylon/src/ibc.rs +++ b/contracts/babylon/src/ibc.rs @@ -326,15 +326,16 @@ mod tests { use crate::contract::instantiate; use crate::msg::contract::InstantiateMsg; use crate::msg::ibc::{IbcTransferInfo, Recipient}; + use babylon_bindings_test::mock_dependencies; use cosmwasm_std::testing::message_info; use cosmwasm_std::testing::{ - mock_dependencies, mock_env, mock_ibc_channel_open_try, MockApi, MockQuerier, MockStorage, + mock_env, mock_ibc_channel_open_try, MockApi, MockQuerier, MockStorage, }; use cosmwasm_std::OwnedDeps; const CREATOR: &str = "creator"; - fn setup() -> OwnedDeps { + fn setup() -> OwnedDeps> { let mut deps = mock_dependencies(); let msg = InstantiateMsg { network: babylon_bitcoin::chain_params::Network::Regtest, @@ -353,7 +354,7 @@ mod tests { let info = message_info(&deps.api.addr_make(CREATOR), &[]); let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); assert_eq!(0, res.messages.len()); - deps + deps.as_mut() } #[test] @@ -361,7 +362,7 @@ mod tests { let mut deps = setup(); let wrong_order = mock_ibc_channel_open_try("channel-12", IbcOrder::Unordered, IBC_VERSION); - ibc_channel_open(deps.as_mut(), mock_env(), wrong_order).unwrap_err(); + ibc_channel_open(deps, mock_env(), wrong_order).unwrap_err(); let wrong_version = mock_ibc_channel_open_try("channel-12", IbcOrder::Ordered, "reflect"); ibc_channel_open(deps.as_mut(), mock_env(), wrong_version).unwrap_err(); diff --git a/contracts/babylon/src/lib.rs b/contracts/babylon/src/lib.rs index e5da6b88..7ca52919 100644 --- a/contracts/babylon/src/lib.rs +++ b/contracts/babylon/src/lib.rs @@ -25,7 +25,7 @@ mod utils; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( - deps: DepsMut, + deps: DepsMut, env: Env, info: MessageInfo, msg: InstantiateMsg, diff --git a/packages/bindings-test/src/lib.rs b/packages/bindings-test/src/lib.rs index 416def8e..f0c9a365 100644 --- a/packages/bindings-test/src/lib.rs +++ b/packages/bindings-test/src/lib.rs @@ -1,6 +1,43 @@ mod multitest; +use std::marker::PhantomData; + +use babylon_bindings::query::{BabylonQuery, ParamsResponse}; +use cosmwasm_std::{ + testing::{MockApi, MockQuerier, MockStorage}, + to_json_binary, Addr, ContractResult, OwnedDeps, SystemResult, +}; pub use multitest::{ mock_deps_babylon, BabylonApp, BabylonAppWrapped, BabylonDeps, BabylonError, BabylonModule, BLOCK_TIME, }; + +pub fn mock_dependencies( +) -> OwnedDeps, BabylonQuery> { + let custom_querier: MockQuerier = MockQuerier::new(&[("", &[])]) + .with_custom_handler(|query| { + // Handle your custom query type here + match query { + BabylonQuery::Params {} => { + // Return a mock response for the custom query + let response = ParamsResponse { + babylon_contract_address: Addr::unchecked(""), + btc_staking_contract_address: Addr::unchecked(""), + btc_finality_contract_address: Addr::unchecked(""), + babylon_contract_code_id: 0, + btc_staking_contract_code_id: 0, + btc_finality_contract_code_id: 0, + max_gas_begin_blocker: 0, + }; + SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) + } + _ => panic!("Unsupported query type"), + } + }); + OwnedDeps { + storage: MockStorage::default(), + api: MockApi::default(), + querier: custom_querier, + custom_query_type: PhantomData, + } +} diff --git a/packages/bindings-test/src/multitest.rs b/packages/bindings-test/src/multitest.rs index 1020f6c1..81526f7b 100644 --- a/packages/bindings-test/src/multitest.rs +++ b/packages/bindings-test/src/multitest.rs @@ -1,6 +1,7 @@ use anyhow::{bail, Result as AnyResult}; use schemars::JsonSchema; use serde::de::DeserializeOwned; +use std::cmp::max; use std::fmt::Debug; use std::ops::{Deref, DerefMut}; use thiserror::Error; @@ -210,6 +211,32 @@ impl BabylonApp { } */ + /// This reverses to genesis (based on current time/height) + pub fn back_to_genesis(&mut self) { + self.update_block(|block| { + block.time = block.time.minus_seconds(BLOCK_TIME * block.height); + block.height = 0; + }); + } + + /// This advances BlockInfo by given number of blocks. + /// It does not do any callbacks, but keeps the ratio of seconds/block + pub fn advance_blocks(&mut self, blocks: u64) { + self.update_block(|block| { + block.time = block.time.plus_seconds(BLOCK_TIME * blocks); + block.height += blocks; + }); + } + + /// This advances BlockInfo by given number of seconds. + /// It does not do any callbacks, but keeps the ratio of seconds/blokc + pub fn advance_seconds(&mut self, seconds: u64) { + self.update_block(|block| { + block.time = block.time.plus_seconds(seconds); + block.height += max(1, seconds / BLOCK_TIME); + }); + } + /* /// next_block will call the end_blocker, increment block info 1 height and 5 seconds, /// and then call the begin_blocker (with no evidence) in the next block. From 77bad104d19bdbfee2dcdde1866475800e512260 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Wed, 8 Jan 2025 10:43:24 +1100 Subject: [PATCH 08/10] compile and fix lint --- Cargo.lock | 1 + contracts/babylon/src/contract.rs | 10 +++-- contracts/babylon/src/ibc.rs | 7 ++-- contracts/babylon/src/lib.rs | 2 +- contracts/babylon/src/msg/contract.rs | 2 +- contracts/babylon/src/queries/mod.rs | 2 +- contracts/btc-finality/src/contract.rs | 40 +++---------------- contracts/btc-finality/src/multitest.rs | 9 ++--- contracts/btc-finality/src/multitest/suite.rs | 2 +- contracts/btc-staking/Cargo.toml | 1 + contracts/btc-staking/src/contract.rs | 22 +++++----- contracts/btc-staking/src/queries.rs | 34 ++++++++++------ contracts/btc-staking/src/staking.rs | 24 ++++++----- contracts/btc-staking/src/state/config.rs | 5 +-- contracts/btc-staking/src/state/fp_index.rs | 2 +- 15 files changed, 73 insertions(+), 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 174e8ddb..959791da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -550,6 +550,7 @@ version = "0.11.0" dependencies = [ "babylon-apis", "babylon-bindings", + "babylon-bindings-test", "babylon-bitcoin", "babylon-btcstaking", "babylon-contract", diff --git a/contracts/babylon/src/contract.rs b/contracts/babylon/src/contract.rs index 755f3362..9d734197 100644 --- a/contracts/babylon/src/contract.rs +++ b/contracts/babylon/src/contract.rs @@ -1,12 +1,12 @@ use babylon_bindings::query::{get_babylon_sdk_params, BabylonQuery}; use cosmwasm_std::{ - to_json_binary, to_json_string, Addr, Binary, Deps, DepsMut, Empty, Env, IbcMsg, MessageInfo, - QueryResponse, Response, SubMsg, SubMsgResponse, WasmMsg, + to_json_binary, to_json_string, Deps, DepsMut, Empty, Env, IbcMsg, MessageInfo, QueryResponse, + Response, WasmMsg, }; use cw2::set_contract_version; use cw_utils::must_pay; -use babylon_apis::{btc_staking_api, finality_api, to_bech32_addr, to_module_canonical_addr}; +use babylon_apis::{btc_staking_api, to_bech32_addr, to_module_canonical_addr}; use babylon_bindings::BabylonMsg; use crate::error::ContractError; @@ -229,9 +229,11 @@ pub fn execute( #[cfg(test)] mod tests { use super::*; + use babylon_bindings_test::mock_dependencies; use babylon_bitcoin::BlockHeader; use cosmwasm_std::testing::message_info; - use cosmwasm_std::testing::{mock_dependencies, mock_env}; + use cosmwasm_std::testing::mock_env; + use cosmwasm_std::Binary; const CREATOR: &str = "creator"; diff --git a/contracts/babylon/src/ibc.rs b/contracts/babylon/src/ibc.rs index 22ce4cae..f62318ab 100644 --- a/contracts/babylon/src/ibc.rs +++ b/contracts/babylon/src/ibc.rs @@ -334,8 +334,7 @@ mod tests { use cosmwasm_std::OwnedDeps; const CREATOR: &str = "creator"; - - fn setup() -> OwnedDeps> { + fn setup() -> OwnedDeps, BabylonQuery> { let mut deps = mock_dependencies(); let msg = InstantiateMsg { network: babylon_bitcoin::chain_params::Network::Regtest, @@ -354,7 +353,7 @@ mod tests { let info = message_info(&deps.api.addr_make(CREATOR), &[]); let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); assert_eq!(0, res.messages.len()); - deps.as_mut() + deps } #[test] @@ -362,7 +361,7 @@ mod tests { let mut deps = setup(); let wrong_order = mock_ibc_channel_open_try("channel-12", IbcOrder::Unordered, IBC_VERSION); - ibc_channel_open(deps, mock_env(), wrong_order).unwrap_err(); + ibc_channel_open(deps.as_mut(), mock_env(), wrong_order).unwrap_err(); let wrong_version = mock_ibc_channel_open_try("channel-12", IbcOrder::Ordered, "reflect"); ibc_channel_open(deps.as_mut(), mock_env(), wrong_version).unwrap_err(); diff --git a/contracts/babylon/src/lib.rs b/contracts/babylon/src/lib.rs index 7ca52919..698fb3d9 100644 --- a/contracts/babylon/src/lib.rs +++ b/contracts/babylon/src/lib.rs @@ -3,7 +3,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ Binary, Deps, DepsMut, Empty, Env, IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, IbcPacketAckMsg, IbcPacketReceiveMsg, - IbcPacketTimeoutMsg, IbcReceiveResponse, MessageInfo, Never, Reply, Response, StdResult, + IbcPacketTimeoutMsg, IbcReceiveResponse, MessageInfo, Never, Response, StdResult, }; use babylon_bindings::{query::BabylonQuery, BabylonMsg}; diff --git a/contracts/babylon/src/msg/contract.rs b/contracts/babylon/src/msg/contract.rs index b79c3122..e9f51257 100644 --- a/contracts/babylon/src/msg/contract.rs +++ b/contracts/babylon/src/msg/contract.rs @@ -1,6 +1,6 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Uint128; -use cosmwasm_std::{Binary, StdError, StdResult}; +use cosmwasm_std::{StdError, StdResult}; use babylon_apis::finality_api::Evidence; diff --git a/contracts/babylon/src/queries/mod.rs b/contracts/babylon/src/queries/mod.rs index 00dc8fdc..c186b434 100644 --- a/contracts/babylon/src/queries/mod.rs +++ b/contracts/babylon/src/queries/mod.rs @@ -120,7 +120,7 @@ pub(crate) fn transfer_info( mod tests { use super::*; use crate::state::btc_light_client::{init, tests::setup}; - use cosmwasm_std::testing::mock_dependencies; + use babylon_bindings_test::mock_dependencies; use test_utils::get_btc_lc_headers; #[test] diff --git a/contracts/btc-finality/src/contract.rs b/contracts/btc-finality/src/contract.rs index 2a52f1ea..21066434 100644 --- a/contracts/btc-finality/src/contract.rs +++ b/contracts/btc-finality/src/contract.rs @@ -325,7 +325,7 @@ fn send_rewards_msg( pub fn get_activated_height(querier: &QuerierWrapper) -> StdResult { // TODO: Use a raw query let query = encode_smart_query( - &get_babylon_sdk_params(&querier)?.btc_staking_contract_address, + &get_babylon_sdk_params(querier)?.btc_staking_contract_address, &btc_staking::msg::QueryMsg::ActivatedHeight {}, )?; let res: ActivatedHeightResponse = querier.query(&query)?; @@ -345,15 +345,15 @@ pub(crate) fn encode_smart_query( #[cfg(test)] pub(crate) mod tests { - use std::marker::PhantomData; + use super::*; - use babylon_bindings::query::ParamsResponse; + + use babylon_bindings_test::mock_dependencies; use cosmwasm_std::{ from_json, - testing::{message_info, mock_env, MockApi, MockQuerier, MockStorage}, - Coin, ContractResult, OwnedDeps, SystemResult, + testing::{message_info, mock_env}, }; use cw_controllers::AdminResponse; @@ -361,36 +361,6 @@ pub(crate) mod tests { pub(crate) const INIT_ADMIN: &str = "initial_admin"; const NEW_ADMIN: &str = "new_admin"; - pub fn mock_dependencies( - ) -> OwnedDeps, BabylonQuery> { - let custom_querier: MockQuerier = MockQuerier::new(&[("", &[])]) - .with_custom_handler(|query| { - // Handle your custom query type here - match query { - BabylonQuery::Params {} => { - // Return a mock response for the custom query - let response = ParamsResponse { - babylon_contract_address: Addr::unchecked(""), - btc_staking_contract_address: Addr::unchecked(""), - btc_finality_contract_address: Addr::unchecked(""), - babylon_contract_code_id: 0, - btc_staking_contract_code_id: 0, - btc_finality_contract_code_id: 0, - max_gas_begin_blocker: 0, - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } - _ => panic!("Unsupported query type"), - } - }); - OwnedDeps { - storage: MockStorage::default(), - api: MockApi::default(), - querier: custom_querier, - custom_query_type: PhantomData, - } - } - #[test] fn instantiate_without_admin() { let mut deps = mock_dependencies(); diff --git a/contracts/btc-finality/src/multitest.rs b/contracts/btc-finality/src/multitest.rs index 8ad17890..b36fbba6 100644 --- a/contracts/btc-finality/src/multitest.rs +++ b/contracts/btc-finality/src/multitest.rs @@ -1,6 +1,5 @@ mod suite; -use cosmwasm_std::Addr; use suite::SuiteBuilder; // Some multi-test default settings @@ -20,13 +19,11 @@ mod instantiation { let suite = SuiteBuilder::new().build(); // Confirm the btc-staking contract has been instantiated and set - let config = suite.get_babylon_config(); + let _config = suite.get_babylon_config(); // Check that the btc-staking contract was initialized correctly - let btc_staking_config = suite.get_btc_staking_config(); - assert_eq!(btc_staking_config.babylon, Addr::unchecked(CONTRACT0_ADDR)); - + let _btc_staking_config = suite.get_btc_staking_config(); // Check that the btc-finality contract was initialized correctly - let btc_finality_config = suite.get_btc_finality_config(); + let _btc_finality_config = suite.get_btc_finality_config(); } } diff --git a/contracts/btc-finality/src/multitest/suite.rs b/contracts/btc-finality/src/multitest/suite.rs index 0b7c611e..e279b06c 100644 --- a/contracts/btc-finality/src/multitest/suite.rs +++ b/contracts/btc-finality/src/multitest/suite.rs @@ -3,7 +3,7 @@ use babylon_bindings::query::BabylonQuery; use derivative::Derivative; use hex::ToHex; -use cosmwasm_std::{to_json_binary, Addr, Coin}; +use cosmwasm_std::{Addr, Coin}; use cw_multi_test::{AppResponse, Contract, ContractWrapper, Executor}; diff --git a/contracts/btc-staking/Cargo.toml b/contracts/btc-staking/Cargo.toml index f0e0486d..1932ae0c 100644 --- a/contracts/btc-staking/Cargo.toml +++ b/contracts/btc-staking/Cargo.toml @@ -39,6 +39,7 @@ full-validation = [] [dependencies] babylon-apis = { path = "../../packages/apis" } babylon-bindings = { path = "../../packages/bindings" } +babylon-bindings-test = { path = "../../packages/bindings-test" } babylon-contract = { path = "../babylon", features = [ "library" ] } babylon-merkle = { path = "../../packages/merkle" } babylon-proto = { path = "../../packages/proto" } diff --git a/contracts/btc-staking/src/contract.rs b/contracts/btc-staking/src/contract.rs index 8404279b..87c5e315 100644 --- a/contracts/btc-staking/src/contract.rs +++ b/contracts/btc-staking/src/contract.rs @@ -1,3 +1,4 @@ +use babylon_bindings::query::BabylonQuery; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -20,15 +21,13 @@ pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( - mut deps: DepsMut, + mut deps: DepsMut, _env: Env, info: MessageInfo, msg: InstantiateMsg, ) -> Result, ContractError> { nonpayable(&info)?; - let config = Config { - babylon: info.sender, - }; + let config = Config {}; CONFIG.save(deps.storage, &config)?; let api = deps.api; @@ -43,12 +42,16 @@ pub fn instantiate( } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(_deps: DepsMut, _env: Env, _reply: Reply) -> StdResult { +pub fn reply(_deps: DepsMut, _env: Env, _reply: Reply) -> StdResult { Ok(Response::default()) } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { +pub fn query( + deps: Deps, + _env: Env, + msg: QueryMsg, +) -> Result { match msg { QueryMsg::Config {} => Ok(to_json_binary(&queries::config(deps)?)?), QueryMsg::Params {} => Ok(to_json_binary(&queries::params(deps)?)?), @@ -90,13 +93,13 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result StdResult { +pub fn migrate(_deps: DepsMut, _env: Env, _msg: Empty) -> StdResult { Ok(Response::default()) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute( - deps: DepsMut, + deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, @@ -128,9 +131,10 @@ pub fn execute( pub mod tests { use super::*; + use babylon_bindings_test::mock_dependencies; use cosmwasm_std::{ from_json, - testing::{message_info, mock_dependencies, mock_env}, + testing::{message_info, mock_env}, }; use cw_controllers::AdminResponse; diff --git a/contracts/btc-staking/src/queries.rs b/contracts/btc-staking/src/queries.rs index 1cbab505..e5140039 100644 --- a/contracts/btc-staking/src/queries.rs +++ b/contracts/btc-staking/src/queries.rs @@ -1,5 +1,6 @@ use std::str::FromStr; +use babylon_bindings::query::BabylonQuery; use bitcoin::hashes::Hash; use bitcoin::Txid; @@ -20,15 +21,18 @@ use crate::state::staking::{ fps, BtcDelegation, FinalityProviderState, ACTIVATED_HEIGHT, DELEGATIONS, FPS, FP_DELEGATIONS, }; -pub fn config(deps: Deps) -> StdResult { +pub fn config(deps: Deps) -> StdResult { CONFIG.load(deps.storage) } -pub fn params(deps: Deps) -> StdResult { +pub fn params(deps: Deps) -> StdResult { PARAMS.load(deps.storage) } -pub fn finality_provider(deps: Deps, btc_pk_hex: String) -> StdResult { +pub fn finality_provider( + deps: Deps, + btc_pk_hex: String, +) -> StdResult { FPS.load(deps.storage, &btc_pk_hex) } @@ -37,7 +41,7 @@ const MAX_LIMIT: u32 = 30; const DEFAULT_LIMIT: u32 = 10; pub fn finality_providers( - deps: Deps, + deps: Deps, start_after: Option, limit: Option, ) -> StdResult { @@ -53,7 +57,10 @@ pub fn finality_providers( /// Get the delegation info by staking tx hash. /// `staking_tx_hash_hex`: The (reversed) staking tx hash, in hex -pub fn delegation(deps: Deps, staking_tx_hash_hex: String) -> Result { +pub fn delegation( + deps: Deps, + staking_tx_hash_hex: String, +) -> Result { let staking_tx_hash = Txid::from_str(&staking_tx_hash_hex)?; Ok(DELEGATIONS.load(deps.storage, staking_tx_hash.as_ref())?) } @@ -62,7 +69,7 @@ pub fn delegation(deps: Deps, staking_tx_hash_hex: String) -> Result, start_after: Option, limit: Option, active: Option, @@ -94,7 +101,7 @@ pub fn delegations( /// /// `btc_pk_hex`: The BTC public key of the finality provider, in hex pub fn delegations_by_fp( - deps: Deps, + deps: Deps, btc_pk_hex: String, ) -> Result { let tx_hashes = FP_DELEGATIONS.load(deps.storage, &btc_pk_hex)?; @@ -113,7 +120,7 @@ pub fn delegations_by_fp( /// `btc_pk_hex`: The BTC public key of the finality provider, in hex. /// `active` is a filter to return only active delegations pub fn active_delegations_by_fp( - deps: Deps, + deps: Deps, btc_pk_hex: String, active: bool, ) -> Result { @@ -133,7 +140,7 @@ pub fn active_delegations_by_fp( } pub fn finality_provider_info( - deps: Deps, + deps: Deps, btc_pk_hex: String, height: Option, ) -> Result { @@ -150,7 +157,7 @@ pub fn finality_provider_info( } pub fn finality_providers_by_power( - deps: Deps, + deps: Deps, start_after: Option, limit: Option, ) -> StdResult { @@ -170,7 +177,9 @@ pub fn finality_providers_by_power( Ok(FinalityProvidersByPowerResponse { fps }) } -pub fn activated_height(deps: Deps) -> Result { +pub fn activated_height( + deps: Deps, +) -> Result { let activated_height = ACTIVATED_HEIGHT.may_load(deps.storage)?.unwrap_or_default(); Ok(ActivatedHeightResponse { height: activated_height, @@ -179,9 +188,10 @@ pub fn activated_height(deps: Deps) -> Result, env: Env, info: &MessageInfo, new_fps: &[NewFinalityProvider], @@ -37,8 +38,8 @@ pub fn handle_btc_staking( slashed_delegations: &[SlashedBtcDelegation], unbonded_delegations: &[UnbondedBtcDelegation], ) -> Result, ContractError> { - let config = CONFIG.load(deps.storage)?; - if info.sender != config.babylon && !ADMIN.is_admin(deps.as_ref(), &info.sender)? { + let babylon_addr = get_babylon_sdk_params(&deps.querier)?.babylon_contract_address; + if info.sender != babylon_addr && !ADMIN.is_admin(deps.as_ref(), &info.sender)? { return Err(ContractError::Unauthorized); } @@ -310,13 +311,13 @@ fn handle_slashed_delegation( /// handle_slash_fp handles FP slashing at the staking level pub fn handle_slash_fp( - deps: DepsMut, + deps: DepsMut, env: Env, info: &MessageInfo, fp_btc_pk_hex: &str, ) -> Result, ContractError> { - let config = CONFIG.load(deps.storage)?; - if info.sender != config.babylon && !ADMIN.is_admin(deps.as_ref(), &info.sender)? { + let babylon_addr = get_babylon_sdk_params(&deps.querier)?.babylon_contract_address; + if info.sender != babylon_addr && !ADMIN.is_admin(deps.as_ref(), &info.sender)? { return Err(ContractError::Unauthorized); } slash_finality_provider(deps, env, fp_btc_pk_hex) @@ -348,7 +349,7 @@ fn btc_undelegate( /// `slash_finality_provider` slashes a finality provider with the given PK. /// A slashed finality provider will not have voting power pub(crate) fn slash_finality_provider( - deps: DepsMut, + deps: DepsMut, env: Env, fp_btc_pk_hex: &str, ) -> Result, ContractError> { @@ -388,9 +389,9 @@ pub(crate) fn slash_finality_provider( } /// get_btc_tip_height queries the Babylon contract for the latest BTC tip height -fn get_btc_tip_height(deps: &DepsMut) -> Result { +fn get_btc_tip_height(deps: &DepsMut) -> Result { // Get the BTC tip from the babylon contract through a raw query - let babylon_addr = CONFIG.load(deps.storage)?.babylon; + let babylon_addr = get_babylon_sdk_params(&deps.querier)?.babylon_contract_address; // Query the Babylon contract // TODO: use a raw query for performance / efficiency @@ -404,7 +405,8 @@ fn get_btc_tip_height(deps: &DepsMut) -> Result { pub(crate) mod tests { use super::*; - use cosmwasm_std::testing::{message_info, mock_dependencies, mock_env}; + use babylon_bindings_test::mock_dependencies; + use cosmwasm_std::testing::{message_info, mock_env}; use test_utils::{ create_new_finality_provider, create_new_fp_sk, get_active_btc_delegation, diff --git a/contracts/btc-staking/src/state/config.rs b/contracts/btc-staking/src/state/config.rs index af2dfe5e..2ac7e65f 100644 --- a/contracts/btc-staking/src/state/config.rs +++ b/contracts/btc-staking/src/state/config.rs @@ -1,6 +1,5 @@ use babylon_bitcoin::chain_params::Network; use cosmwasm_schema::cw_serde; -use cosmwasm_std::Addr; use cw_controllers::Admin; use cw_storage_plus::Item; @@ -14,9 +13,7 @@ pub(crate) const ADMIN: Admin = Admin::new("admin"); /// Config are Babylon-selectable BTC staking configuration // TODO: Add / enable config entries as needed #[cw_serde] -pub struct Config { - pub babylon: Addr, -} +pub struct Config {} /// Params define Consumer-selectable BTC staking parameters // TODO: Add / enable param entries as needed diff --git a/contracts/btc-staking/src/state/fp_index.rs b/contracts/btc-staking/src/state/fp_index.rs index 04fa217c..1bf6ccd1 100644 --- a/contracts/btc-staking/src/state/fp_index.rs +++ b/contracts/btc-staking/src/state/fp_index.rs @@ -8,7 +8,7 @@ pub struct FinalityProviderIndexes<'a> { pub power: MultiIndex<'a, u64, FinalityProviderState, String>, } -impl<'a> IndexList for FinalityProviderIndexes<'a> { +impl IndexList for FinalityProviderIndexes<'_> { fn get_indexes( &'_ self, ) -> Box> + '_> { From ddabb4f961eb911f7a7b06298751e3369d018d1a Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Wed, 8 Jan 2025 10:48:03 +1100 Subject: [PATCH 09/10] cleanup --- contracts/babylon/src/contract.rs | 61 ------------------------------- 1 file changed, 61 deletions(-) diff --git a/contracts/babylon/src/contract.rs b/contracts/babylon/src/contract.rs index 9d734197..43aec9f8 100644 --- a/contracts/babylon/src/contract.rs +++ b/contracts/babylon/src/contract.rs @@ -264,67 +264,6 @@ mod tests { assert_eq!(0, res.messages.len()); } - #[test] - fn instantiate_finality_works() { - let mut deps = mock_dependencies(); - let msg = InstantiateMsg { - network: babylon_bitcoin::chain_params::Network::Regtest, - babylon_tag: "01020304".to_string(), - btc_confirmation_depth: 10, - checkpoint_finalization_timeout: 100, - notify_cosmos_zone: false, - admin: None, - consumer_name: None, - consumer_description: None, - transfer_info: None, - }; - let info = message_info(&deps.api.addr_make(CREATOR), &[]); - let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); - assert_eq!(1, res.messages.len()); - assert_eq!( - res.messages[0].msg, - WasmMsg::Instantiate { - admin: None, - code_id: 2, - msg: Binary::from(b"{}"), - funds: vec![], - label: "BTC Finality".into(), - } - .into() - ); - } - - #[test] - fn instantiate_finality_params_works() { - let mut deps = mock_dependencies(); - let params = r#"{"params": {"epoch_length": 10}}"#; - let msg = InstantiateMsg { - network: babylon_bitcoin::chain_params::Network::Regtest, - babylon_tag: "01020304".to_string(), - btc_confirmation_depth: 10, - checkpoint_finalization_timeout: 100, - notify_cosmos_zone: false, - admin: None, - consumer_name: None, - consumer_description: None, - transfer_info: None, - }; - let info = message_info(&deps.api.addr_make(CREATOR), &[]); - let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); - assert_eq!(1, res.messages.len()); - assert_eq!( - res.messages[0].msg, - WasmMsg::Instantiate { - admin: None, - code_id: 2, - msg: Binary::from(params.as_bytes()), - funds: vec![], - label: "BTC Finality".into(), - } - .into() - ); - } - #[test] fn test_module_address() { // Example usage From f71162b0dd42190387be3f911413e5f3e6513f09 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Wed, 8 Jan 2025 11:32:54 +1100 Subject: [PATCH 10/10] fix some tests --- contracts/btc-finality/src/multitest/suite.rs | 45 ++++++++++++++++--- contracts/btc-staking/src/queries.rs | 41 ++++++++++------- contracts/btc-staking/src/staking.rs | 15 ++++--- packages/bindings-test/src/multitest.rs | 20 +++++++-- packages/bindings/src/query.rs | 6 +-- 5 files changed, 92 insertions(+), 35 deletions(-) diff --git a/contracts/btc-finality/src/multitest/suite.rs b/contracts/btc-finality/src/multitest/suite.rs index e279b06c..bb4bdb76 100644 --- a/contracts/btc-finality/src/multitest/suite.rs +++ b/contracts/btc-finality/src/multitest/suite.rs @@ -68,7 +68,8 @@ impl SuiteBuilder { #[track_caller] pub fn build(self) -> Suite { - let owner = Addr::unchecked("owner"); + let owner = + Addr::unchecked("cosmwasm19mfs8tl4s396u7vqw9rrnsmrrtca5r66p7v8jvwdxvjn3shcmllqupdgxu"); let mut app = BabylonApp::new_at_height(owner.as_str(), self.height.unwrap_or(1)); @@ -84,8 +85,9 @@ impl SuiteBuilder { let btc_finality_code_id = app.store_code_with_creator(owner.clone(), contract_btc_finality()); let contract_code_id = app.store_code_with_creator(owner.clone(), contract_babylon()); - let staking_params = btc_staking::test_utils::staking_params(); - let contract = app + + // instantiate Babylon contract + let babylon_contract_addr = app .instantiate_contract( contract_code_id, owner.clone(), @@ -106,12 +108,43 @@ impl SuiteBuilder { ) .unwrap(); + // instantiate BTC Staking contract + let staking_params = btc_staking::test_utils::staking_params(); + let staking_contract_addr = app + .instantiate_contract( + btc_staking_code_id, + owner.clone(), + &btc_staking::msg::InstantiateMsg { + admin: Some(owner.to_string()), + params: Some(staking_params), + }, + &[], + "btc-staking", + Some(owner.to_string()), + ) + .unwrap(); + + // instantiate BTC Finality contract + let finality_contract_addr = app + .instantiate_contract( + btc_finality_code_id, + owner.clone(), + &crate::msg::InstantiateMsg { + admin: Some(owner.to_string()), + params: Some(crate::state::config::Params::default()), + }, + &[], + "btc-finality", + Some(owner.to_string()), + ) + .unwrap(); + Suite { app, code_id: contract_code_id, - babylon: contract, - staking: Addr::unchecked(CONTRACT1_ADDR), - finality: Addr::unchecked(CONTRACT2_ADDR), + babylon: babylon_contract_addr, + staking: staking_contract_addr, + finality: finality_contract_addr, owner, } } diff --git a/contracts/btc-staking/src/queries.rs b/contracts/btc-staking/src/queries.rs index e5140039..1a17d02d 100644 --- a/contracts/btc-staking/src/queries.rs +++ b/contracts/btc-staking/src/queries.rs @@ -224,7 +224,8 @@ mod tests { #[test] fn test_finality_providers() { let mut deps = mock_dependencies(); - let info = message_info(&deps.api.addr_make(CREATOR), &[]); + let admin = deps.api.addr_make(CREATOR); + let info = message_info(&admin, &[]); let params = staking_params(); instantiate( @@ -233,7 +234,7 @@ mod tests { info.clone(), InstantiateMsg { params: Some(params), - admin: None, + admin: Some(admin.to_string()), }, ) .unwrap(); @@ -283,7 +284,8 @@ mod tests { #[test] fn test_delegations() { let mut deps = mock_dependencies(); - let info = message_info(&deps.api.addr_make(CREATOR), &[]); + let admin = deps.api.addr_make(CREATOR); + let info = message_info(&admin, &[]); let params = staking_params(); instantiate( @@ -292,7 +294,7 @@ mod tests { info.clone(), InstantiateMsg { params: Some(params), - admin: None, + admin: Some(admin.to_string()), }, ) .unwrap(); @@ -356,7 +358,8 @@ mod tests { #[test] fn test_active_delegations() { let mut deps = mock_dependencies(); - let info = message_info(&deps.api.addr_make(CREATOR), &[]); + let admin = deps.api.addr_make(CREATOR); + let info = message_info(&admin, &[]); let params = staking_params(); instantiate( @@ -365,7 +368,7 @@ mod tests { info.clone(), InstantiateMsg { params: Some(params), - admin: None, + admin: Some(admin.to_string()), }, ) .unwrap(); @@ -443,8 +446,8 @@ mod tests { #[test] fn test_delegations_by_fp() { let mut deps = mock_dependencies(); - let info = message_info(&deps.api.addr_make(CREATOR), &[]); - + let admin = deps.api.addr_make(CREATOR); + let info = message_info(&admin, &[]); let params = staking_params(); instantiate( deps.as_mut(), @@ -452,7 +455,7 @@ mod tests { info.clone(), InstantiateMsg { params: Some(params), - admin: None, + admin: Some(admin.to_string()), }, ) .unwrap(); @@ -502,7 +505,8 @@ mod tests { #[test] fn test_active_delegations_by_fp() { let mut deps = mock_dependencies(); - let info = message_info(&deps.api.addr_make(CREATOR), &[]); + let admin = deps.api.addr_make(CREATOR); + let info = message_info(&admin, &[]); let params = staking_params(); instantiate( @@ -511,7 +515,7 @@ mod tests { info.clone(), InstantiateMsg { params: Some(params), - admin: None, + admin: Some(admin.to_string()), }, ) .unwrap(); @@ -592,7 +596,8 @@ mod tests { #[test] fn test_fp_info() { let mut deps = mock_dependencies(); - let info = message_info(&deps.api.addr_make(CREATOR), &[]); + let admin = deps.api.addr_make(CREATOR); + let info = message_info(&admin, &[]); let initial_env = mock_env_height(10); @@ -603,7 +608,7 @@ mod tests { info.clone(), InstantiateMsg { params: Some(params), - admin: None, + admin: Some(admin.to_string()), }, ) .unwrap(); @@ -697,7 +702,8 @@ mod tests { #[test] fn test_fp_info_raw_query() { let mut deps = mock_dependencies(); - let info = message_info(&deps.api.addr_make(CREATOR), &[]); + let admin = deps.api.addr_make(CREATOR); + let info = message_info(&admin, &[]); let params = staking_params(); instantiate( @@ -706,7 +712,7 @@ mod tests { info.clone(), InstantiateMsg { params: Some(params), - admin: None, + admin: Some(admin.to_string()), }, ) .unwrap(); @@ -751,7 +757,8 @@ mod tests { #[test] fn test_fps_by_power() { let mut deps = mock_dependencies(); - let info = message_info(&deps.api.addr_make(CREATOR), &[]); + let admin = deps.api.addr_make(CREATOR); + let info = message_info(&admin, &[]); let params = staking_params(); instantiate( @@ -760,7 +767,7 @@ mod tests { info.clone(), InstantiateMsg { params: Some(params), - admin: None, + admin: Some(admin.to_string()), }, ) .unwrap(); diff --git a/contracts/btc-staking/src/staking.rs b/contracts/btc-staking/src/staking.rs index 7ffe5373..342c9975 100644 --- a/contracts/btc-staking/src/staking.rs +++ b/contracts/btc-staking/src/staking.rs @@ -507,7 +507,8 @@ pub(crate) mod tests { #[test] fn active_delegation_happy_path() { let mut deps = mock_dependencies(); - let info = message_info(&deps.api.addr_make(CREATOR), &[]); + let admin = deps.api.addr_make(CREATOR); + let info = message_info(&admin, &[]); let params = staking_params(); instantiate( @@ -516,7 +517,7 @@ pub(crate) mod tests { info.clone(), InstantiateMsg { params: Some(params), - admin: None, + admin: Some(admin.to_string()), }, ) .unwrap(); @@ -572,7 +573,8 @@ pub(crate) mod tests { #[test] fn undelegation_works() { let mut deps = mock_dependencies(); - let info = message_info(&deps.api.addr_make(CREATOR), &[]); + let admin = deps.api.addr_make(CREATOR); + let info = message_info(&admin, &[]); let params = staking_params(); instantiate( @@ -581,7 +583,7 @@ pub(crate) mod tests { info.clone(), InstantiateMsg { params: Some(params), - admin: None, + admin: Some(admin.to_string()), }, ) .unwrap(); @@ -671,7 +673,8 @@ pub(crate) mod tests { #[test] fn slashed_delegation_works() { let mut deps = mock_dependencies(); - let info = message_info(&deps.api.addr_make(CREATOR), &[]); + let admin = deps.api.addr_make(CREATOR); + let info = message_info(&admin, &[]); let params = staking_params(); instantiate( @@ -680,7 +683,7 @@ pub(crate) mod tests { info.clone(), InstantiateMsg { params: Some(params), - admin: None, + admin: Some(admin.to_string()), }, ) .unwrap(); diff --git a/packages/bindings-test/src/multitest.rs b/packages/bindings-test/src/multitest.rs index 81526f7b..837f7ba0 100644 --- a/packages/bindings-test/src/multitest.rs +++ b/packages/bindings-test/src/multitest.rs @@ -1,4 +1,5 @@ use anyhow::{bail, Result as AnyResult}; +use babylon_bindings::query::ParamsResponse; use schemars::JsonSchema; use serde::de::DeserializeOwned; use std::cmp::max; @@ -7,7 +8,7 @@ use std::ops::{Deref, DerefMut}; use thiserror::Error; use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage}; -use cosmwasm_std::OwnedDeps; +use cosmwasm_std::{to_json_binary, OwnedDeps}; use std::marker::PhantomData; use cosmwasm_std::Order::Ascending; @@ -105,9 +106,22 @@ impl Module for BabylonModule { _storage: &dyn Storage, _querier: &dyn Querier, _block: &BlockInfo, - _request: BabylonQuery, + request: BabylonQuery, ) -> anyhow::Result { - bail!("query not implemented for BabylonModule") + match request { + BabylonQuery::Params {} => { + let response = ParamsResponse { + babylon_contract_address: Addr::unchecked(""), + btc_staking_contract_address: Addr::unchecked(""), + btc_finality_contract_address: Addr::unchecked(""), + babylon_contract_code_id: 0, + btc_staking_contract_code_id: 0, + btc_finality_contract_code_id: 0, + max_gas_begin_blocker: 0, + }; + Ok(to_json_binary(&response)?) + } + } } fn sudo( diff --git a/packages/bindings/src/query.rs b/packages/bindings/src/query.rs index 8803ba8b..8a7a08ce 100644 --- a/packages/bindings/src/query.rs +++ b/packages/bindings/src/query.rs @@ -1,7 +1,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{ - from_json, to_json_binary, Addr, ContractResult, CustomQuery, QuerierWrapper, StdError, - SystemResult, + from_json, to_json_binary, Addr, ContractResult, CustomQuery, QuerierWrapper, QueryRequest, + StdError, SystemResult, }; #[cw_serde] @@ -35,7 +35,7 @@ pub struct ParamsResponse { pub fn get_babylon_sdk_params( querier: &QuerierWrapper, ) -> Result { - let query = BabylonQuery::Params {}; + let query = QueryRequest::Custom(BabylonQuery::Params {}); let res = match querier.raw_query(&to_json_binary(&query)?) { SystemResult::Err(system_err) => Err(StdError::generic_err(format!( "Querier system error: {}",